Revert latest update due to unexpected bug in compiled files.

svn path=/trunk/; revision=26856
This commit is contained in:
Eric Kohl 2007-05-21 18:28:00 +00:00
parent 6891a17fe5
commit 30740cbe3d
26 changed files with 7768 additions and 5157 deletions

View file

@ -1,10 +1,5 @@
ChangeLog ChangeLog
2007-05-20 ekohl
- Synchronized with WINE widl 20070519.
2007-05-17 ekohl 2007-05-17 ekohl
tools/widl/lex.yy.c tools/widl/lex.yy.c

View file

@ -20,27 +20,34 @@ C_SRCS = \
widl.c \ widl.c \
write_msft.c write_msft.c
LEX_SRCS = parser.l EXTRA_SRCS = parser.y parser.l
BISON_SRCS = parser.y EXTRA_OBJS = parser.tab.o @LEX_OUTPUT_ROOT@.o
INSTALLDIRS = $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext)
all: $(PROGRAMS) $(MANPAGES) all: $(PROGRAMS) $(MANPAGES)
@MAKE_RULES@ @MAKE_RULES@
widl$(EXEEXT): $(OBJS) $(LIBWPP) widl$(EXEEXT): $(OBJS) $(LIBWPP)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBWPP) $(LIBPORT) $(LDFLAGS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBWPP) $(LIBPORT) $(LEXLIB) $(LDFLAGS)
install:: $(PROGRAMS) $(MANPAGES) $(INSTALLDIRS) parser.tab.c parser.tab.h: parser.y
$(BISON) -d -t $(SRCDIR)/parser.y -o parser.tab.c
# hack to allow parallel make
parser.tab.h: parser.tab.c
parser.tab.o: parser.tab.h
@LEX_OUTPUT_ROOT@.c: parser.l
$(LEX) $(SRCDIR)/parser.l
@LEX_OUTPUT_ROOT@.o: parser.tab.h
install:: $(PROGRAMS) $(MANPAGES)
$(MKINSTALLDIRS) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man$(prog_manext)
$(INSTALL_PROGRAM) widl$(EXEEXT) $(DESTDIR)$(bindir)/widl$(EXEEXT) $(INSTALL_PROGRAM) widl$(EXEEXT) $(DESTDIR)$(bindir)/widl$(EXEEXT)
$(INSTALL_DATA) widl.man $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) $(INSTALL_DATA) widl.man $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext)
uninstall:: uninstall::
$(RM) $(DESTDIR)$(bindir)/widl$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext) $(RM) $(DESTDIR)$(bindir)/widl$(EXEEXT) $(DESTDIR)$(mandir)/man$(prog_manext)/widl.$(prog_manext)
parser.tab.c: parser.tab.h # for parallel makes ### Dependencies:
@DEPENDENCIES@ # everything below this line is overwritten by make depend
parser.yy.o: parser.tab.h

View file

@ -50,51 +50,82 @@ static int print_client( const char *format, ... )
int i, r; int i, r;
va_start(va, format); va_start(va, format);
if (format[0] != '\n') for (i = 0; i < indent; i++)
for (i = 0; i < indent; i++) fprintf(client, " ");
fprintf(client, " ");
r = vfprintf(client, format, va); r = vfprintf(client, format, va);
va_end(va); va_end(va);
return r; return r;
} }
static void print_message_buffer_size(const func_t *func)
{
unsigned int total_size = 0;
if (func->args)
{
const var_t *var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
unsigned int alignment;
total_size += get_required_buffer_size(var, &alignment, PASS_IN);
total_size += alignment;
var = PREV_LINK(var);
}
}
fprintf(client, " %u", total_size);
}
static void check_pointers(const func_t *func) static void check_pointers(const func_t *func)
{ {
const var_t *var; var_t *var;
int pointer_type;
if (!func->args) if (!func->args)
return; return;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{ {
if (is_var_ptr(var) && cant_be_null(var)) pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (!pointer_type)
pointer_type = RPC_FC_RP;
if (pointer_type == RPC_FC_RP)
{ {
print_client("if (!%s)\n", var->name); if (var->ptr_level >= 1)
print_client("{\n"); {
indent++; print_client("if (!%s)\n", var->name);
print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n"); print_client("{\n");
indent--; indent++;
print_client("}\n\n"); print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
indent--;
print_client("}\n\n");
}
} }
var = PREV_LINK(var);
} }
} }
static void write_function_stubs(type_t *iface, unsigned int *proc_offset) static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset)
{ {
const func_t *func; const func_t *func = iface->funcs;
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
const var_t *var; var_t *var;
int method_count = 0; int method_count = 0;
if (!implicit_handle) while (NEXT_LINK(func)) func = NEXT_LINK(func);
print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name); while (func)
if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{ {
const var_t *def = func->def; const var_t *def = func->def;
const var_t* explicit_handle_var; const var_t* explicit_handle_var;
unsigned int type_offset_func;
/* check for a defined binding handle */ /* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func); explicit_handle_var = get_explicit_handle_var(func);
@ -115,9 +146,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
} }
} }
write_type(client, def->type); write_type(client, def->type, def, def->tname);
fprintf(client, " "); fprintf(client, " ");
write_prefix_name(client, prefix_client, def); write_name(client, def);
fprintf(client, "(\n"); fprintf(client, "(\n");
indent++; indent++;
if (func->args) if (func->args)
@ -132,10 +163,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent++; indent++;
/* declare return value '_RetVal' */ /* declare return value '_RetVal' */
if (!is_void(def->type)) if (!is_void(def->type, NULL))
{ {
print_client(""); print_client("");
write_type(client, def->type); write_type(client, def->type, def, def->tname);
fprintf(client, " _RetVal;\n"); fprintf(client, " _RetVal;\n");
} }
@ -173,7 +204,13 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(client, "\n"); fprintf(client, "\n");
} }
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); /* emit the message buffer size */
print_client("_StubMsg.BufferLength =");
print_message_buffer_size(func);
fprintf(client, ";\n");
type_offset_func = *type_offset;
write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_BUFFERSIZE);
print_client("NdrGetBuffer(\n"); print_client("NdrGetBuffer(\n");
indent++; indent++;
@ -186,8 +223,12 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent--; indent--;
fprintf(client, "\n"); fprintf(client, "\n");
/* make a copy so we don't increment the type offset twice */
type_offset_func = *type_offset;
/* marshal arguments */ /* marshal arguments */
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_MARSHAL); write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_MARSHAL);
/* send/receive message */ /* send/receive message */
/* print_client("NdrNsSendReceive(\n"); */ /* print_client("NdrNsSendReceive(\n"); */
@ -217,19 +258,24 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* unmarshall arguments */ /* unmarshall arguments */
fprintf(client, "\n"); fprintf(client, "\n");
write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL); write_remoting_arguments(client, indent, func, type_offset, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */ /* unmarshal return value */
if (!is_void(def->type)) if (!is_void(def->type, NULL))
print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal"); print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
/* update proc_offset */ /* update proc_offset */
if (func->args) if (func->args)
{ {
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
*proc_offset += get_size_procformatstring_var(var); *proc_offset += get_size_procformatstring_var(var);
var = PREV_LINK(var);
}
} }
if (!is_void(def->type)) if (!is_void(def->type, NULL))
*proc_offset += get_size_procformatstring_var(def); *proc_offset += get_size_procformatstring_var(def);
else else
*proc_offset += 2; /* FC_END and FC_PAD */ *proc_offset += 2; /* FC_END and FC_PAD */
@ -251,7 +297,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* emit return code */ /* emit return code */
if (!is_void(def->type)) if (!is_void(def->type, NULL))
{ {
fprintf(client, "\n"); fprintf(client, "\n");
print_client("return _RetVal;\n"); print_client("return _RetVal;\n");
@ -262,10 +308,18 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(client, "\n"); fprintf(client, "\n");
method_count++; method_count++;
func = PREV_LINK(func);
} }
} }
static void write_bindinghandledecl(type_t *iface)
{
print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n", iface->name);
fprintf(client, "\n");
}
static void write_stubdescdecl(type_t *iface) static void write_stubdescdecl(type_t *iface)
{ {
print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name); print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name);
@ -320,9 +374,6 @@ static void write_clientinterfacedecl(type_t *iface)
{ {
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
if (endpoints) write_endpoints( client, iface->name, endpoints );
print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name ); print_client("static const RPC_CLIENT_INTERFACE %s___RpcClientInterface =\n", iface->name );
print_client("{\n"); print_client("{\n");
@ -334,16 +385,8 @@ static void write_clientinterfacedecl(type_t *iface)
uuid->Data4[7], LOWORD(ver), HIWORD(ver)); uuid->Data4[7], LOWORD(ver), HIWORD(ver));
print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ print_client("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
print_client("0,\n"); print_client("0,\n");
if (endpoints) print_client("0,\n");
{ print_client("0,\n");
print_client("%u,\n", list_count(endpoints));
print_client("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name);
}
else
{
print_client("0,\n");
print_client("0,\n");
}
print_client("0,\n"); print_client("0,\n");
print_client("0,\n"); print_client("0,\n");
print_client("0,\n"); print_client("0,\n");
@ -353,12 +396,43 @@ static void write_clientinterfacedecl(type_t *iface)
print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
iface->name, iface->name); iface->name, iface->name);
else else
print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n", print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
prefix_client, iface->name, LOWORD(ver), HIWORD(ver), iface->name); iface->name, LOWORD(ver), HIWORD(ver), iface->name);
fprintf(client, "\n"); fprintf(client, "\n");
} }
static void write_formatdesc( const char *str )
{
print_client("typedef struct _MIDL_%s_FORMAT_STRING\n", str );
print_client("{\n");
indent++;
print_client("short Pad;\n");
print_client("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str);
indent--;
print_client("} MIDL_%s_FORMAT_STRING;\n", str);
print_client("\n");
}
static void write_formatstringsdecl(ifref_t *ifaces)
{
print_client("#define TYPE_FORMAT_STRING_SIZE %d\n",
get_size_typeformatstring(ifaces));
print_client("#define PROC_FORMAT_STRING_SIZE %d\n",
get_size_procformatstring(ifaces));
fprintf(client, "\n");
write_formatdesc("TYPE");
write_formatdesc("PROC");
fprintf(client, "\n");
print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
print_client("\n");
}
static void write_implicithandledecl(type_t *iface) static void write_implicithandledecl(type_t *iface)
{ {
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
@ -377,7 +451,7 @@ static void init_client(void)
if (!(client = fopen(client_name, "w"))) if (!(client = fopen(client_name, "w")))
error("Could not open %s for output\n", client_name); error("Could not open %s for output\n", client_name);
print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name);
print_client("#include <string.h>\n"); print_client("#include <string.h>\n");
print_client("#ifdef _ALPHA_\n"); print_client("#ifdef _ALPHA_\n");
print_client("#include <stdarg.h>\n"); print_client("#include <stdarg.h>\n");
@ -388,24 +462,25 @@ static void init_client(void)
} }
void write_client(ifref_list_t *ifaces) void write_client(ifref_t *ifaces)
{ {
unsigned int proc_offset = 0; unsigned int proc_offset = 0;
ifref_t *iface; unsigned int type_offset = 2;
ifref_t *iface = ifaces;
if (!do_client) if (!do_client)
return; return;
if (do_everything && !ifaces) if (!iface)
return; return;
END_OF_LIST(iface);
init_client(); init_client();
if (!client) if (!client)
return; return;
write_formatstringsdecl(client, indent, ifaces, 0); write_formatstringsdecl(ifaces);
if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) for (; iface; iface = PREV_LINK(iface))
{ {
if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
continue; continue;
@ -423,7 +498,9 @@ void write_client(ifref_list_t *ifaces)
write_clientinterfacedecl(iface->iface); write_clientinterfacedecl(iface->iface);
write_stubdescdecl(iface->iface); write_stubdescdecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset); write_bindinghandledecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset, &type_offset);
print_client("#if !defined(__RPC_WIN32__)\n"); print_client("#if !defined(__RPC_WIN32__)\n");
print_client("#error Invalid build platform for this stub.\n"); print_client("#error Invalid build platform for this stub.\n");
@ -440,8 +517,8 @@ void write_client(ifref_list_t *ifaces)
fprintf(client, "\n"); fprintf(client, "\n");
write_procformatstring(client, ifaces, 0); write_procformatstring(client, ifaces);
write_typeformatstring(client, ifaces, 0); write_typeformatstring(client, ifaces);
fclose(client); fclose(client);
} }

View file

@ -605,7 +605,13 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
while (*str) while (*str)
{ {
nLoWord = 37 * nLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str]; ULONG newLoWord = 0, i;
/* Cumulative prime multiplication (*37) with modulo 2^32 wrap-around */
for (i = 0; i < 37; i++)
newLoWord += nLoWord;
nLoWord = newLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str];
str++; str++;
} }
/* Constrain to a prime modulo and sizeof(WORD) */ /* Constrain to a prime modulo and sizeof(WORD) */

View file

@ -46,84 +46,59 @@ static void indent(FILE *h, int delta)
if (delta > 0) indentation += delta; if (delta > 0) indentation += delta;
} }
int is_ptrchain_attr(const var_t *var, enum attr_type t) int is_attr(const attr_t *a, enum attr_type t)
{ {
if (is_attr(var->attrs, t)) while (a) {
return 1; if (a->type == t) return 1;
else a = NEXT_LINK(a);
{ }
type_t *type = var->type; return 0;
for (;;)
{
if (is_attr(type->attrs, t))
return 1;
else if (type->kind == TKIND_ALIAS)
type = type->orig;
else if (is_ptr(type))
type = type->ref;
else return 0;
}
}
} }
int is_attr(const attr_list_t *list, enum attr_type t) void *get_attrp(const attr_t *a, enum attr_type t)
{ {
const attr_t *attr; while (a) {
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) if (a->type == t) return a->u.pval;
if (attr->type == t) return 1; a = NEXT_LINK(a);
return 0; }
return NULL;
} }
void *get_attrp(const attr_list_t *list, enum attr_type t) unsigned long get_attrv(const attr_t *a, enum attr_type t)
{ {
const attr_t *attr; while (a) {
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) if (a->type == t) return a->u.ival;
if (attr->type == t) return attr->u.pval; a = NEXT_LINK(a);
return NULL; }
return 0;
} }
unsigned long get_attrv(const attr_list_t *list, enum attr_type t) int is_void(const type_t *t, const var_t *v)
{
const attr_t *attr;
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
if (attr->type == t) return attr->u.ival;
return 0;
}
int is_void(const type_t *t)
{ {
if (v && v->ptr_level) return 0;
if (!t->type && !t->ref) return 1; if (!t->type && !t->ref) return 1;
return 0; return 0;
} }
int is_conformant_array( const array_dims_t *array ) static void write_guid(const char *guid_prefix, const char *name, const UUID *uuid)
{
expr_t *dim;
if (!array) return 0;
dim = LIST_ENTRY( list_head( array ), expr_t, entry );
return !dim->is_const;
}
int is_non_void(const expr_list_t *list)
{
const expr_t *expr;
if (list)
LIST_FOR_EACH_ENTRY( expr, list, const expr_t, entry )
if (expr->type != EXPR_VOID) return 1;
return 0;
}
void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)
{ {
if (!uuid) return; if (!uuid) return;
fprintf(f, "DEFINE_GUID(%s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," fprintf(header, "DEFINE_GUID(%s_%s, 0x%08lx, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x,"
"0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n", "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n",
guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0],
uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5],
uuid->Data4[6], uuid->Data4[7]); uuid->Data4[6], uuid->Data4[7]);
} }
static void write_pident(FILE *h, const var_t *v)
{
int c;
for (c=0; c<v->ptr_level; c++) {
fprintf(h, "*");
}
if (v->name) fprintf(h, "%s", v->name);
}
void write_name(FILE *h, const var_t *v) void write_name(FILE *h, const var_t *v)
{ {
if (is_attr( v->attrs, ATTR_PROPGET )) if (is_attr( v->attrs, ATTR_PROPGET ))
@ -135,31 +110,24 @@ void write_name(FILE *h, const var_t *v)
fprintf(h, "%s", v->name); fprintf(h, "%s", v->name);
} }
void write_prefix_name(FILE *h, const char *prefix, const var_t *v)
{
fprintf(h, "%s", prefix);
write_name(h, v);
}
const char* get_name(const var_t *v) const char* get_name(const var_t *v)
{ {
return v->name; return v->name;
} }
void write_array(FILE *h, array_dims_t *dims, int field) void write_array(FILE *h, const expr_t *v, int field)
{ {
expr_t *v; if (!v) return;
while (NEXT_LINK(v)) v = NEXT_LINK(v);
if (!dims) return;
fprintf(h, "["); fprintf(h, "[");
LIST_FOR_EACH_ENTRY( v, dims, expr_t, entry ) while (v) {
{
if (v->is_const) if (v->is_const)
fprintf(h, "%ld", v->cval); /* statically sized array */ fprintf(h, "%ld", v->cval); /* statically sized array */
else else
if (field) fprintf(h, "1"); /* dynamically sized array */ if (field) fprintf(h, "1"); /* dynamically sized array */
if (list_next( dims, &v->entry )) if (PREV_LINK(v))
fprintf(h, ", "); fprintf(h, ", ");
v = PREV_LINK(v);
} }
fprintf(h, "]"); fprintf(h, "]");
} }
@ -169,9 +137,11 @@ static void write_field(FILE *h, var_t *v)
if (!v) return; if (!v) return;
if (v->type) { if (v->type) {
indent(h, 0); indent(h, 0);
write_type(h, v->type); write_type(h, v->type, NULL, v->tname);
if (get_name(v)) if (get_name(v)) {
fprintf(h, " %s", v->name); fprintf(h, " ");
write_pident(h, v);
}
else { else {
/* not all C/C++ compilers support anonymous structs and unions */ /* not all C/C++ compilers support anonymous structs and unions */
switch (v->type->type) { switch (v->type->type) {
@ -197,19 +167,23 @@ static void write_field(FILE *h, var_t *v)
} }
} }
static void write_fields(FILE *h, var_list_t *fields) static void write_fields(FILE *h, var_t *v)
{ {
var_t *v; var_t *first = v;
if (!fields) return; if (!v) return;
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) write_field(h, v); while (NEXT_LINK(v)) v = NEXT_LINK(v);
while (v) {
write_field(h, v);
if (v == first) break;
v = PREV_LINK(v);
}
} }
static void write_enums(FILE *h, var_list_t *enums) static void write_enums(FILE *h, var_t *v)
{ {
var_t *v; if (!v) return;
if (!enums) return; while (NEXT_LINK(v)) v = NEXT_LINK(v);
LIST_FOR_EACH_ENTRY( v, enums, var_t, entry ) while (v) {
{
if (get_name(v)) { if (get_name(v)) {
indent(h, 0); indent(h, 0);
write_name(h, v); write_name(h, v);
@ -218,25 +192,60 @@ static void write_enums(FILE *h, var_list_t *enums)
write_expr(h, v->eval, 0); write_expr(h, v->eval, 0);
} }
} }
if (list_next( enums, &v->entry )) fprintf(h, ",\n"); if (PREV_LINK(v))
fprintf(h, ",\n");
v = PREV_LINK(v);
} }
fprintf(h, "\n"); fprintf(h, "\n");
} }
static int needs_space_after(type_t *t) void write_type(FILE *h, type_t *t, const var_t *v, const char *n)
{ {
return t->kind == TKIND_ALIAS || ! is_ptr(t); int c;
}
void write_type(FILE *h, type_t *t) if (n) fprintf(h, "%s", n);
{
if (t->is_const) fprintf(h, "const ");
if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name);
else { else {
if (t->sign > 0) fprintf(h, "signed "); if (t->is_const) fprintf(h, "const ");
else if (t->sign < 0) fprintf(h, "unsigned "); if (t->type) {
switch (t->type) { if (t->sign > 0) fprintf(h, "signed ");
else if (t->sign < 0) fprintf(h, "unsigned ");
switch (t->type) {
case RPC_FC_BYTE:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "byte");
break;
case RPC_FC_CHAR:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "char");
break;
case RPC_FC_WCHAR:
fprintf(h, "WCHAR");
break;
case RPC_FC_USMALL:
case RPC_FC_SMALL:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "small");
break;
case RPC_FC_USHORT:
case RPC_FC_SHORT:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "short");
break;
case RPC_FC_ULONG:
case RPC_FC_LONG:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "long");
break;
case RPC_FC_HYPER:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "hyper");
break;
case RPC_FC_FLOAT:
fprintf(h, "float");
break;
case RPC_FC_DOUBLE:
fprintf(h, "double");
break;
case RPC_FC_ENUM16: case RPC_FC_ENUM16:
case RPC_FC_ENUM32: case RPC_FC_ENUM32:
if (t->defined && !t->written && !t->ignore) { if (t->defined && !t->written && !t->ignore) {
@ -250,6 +259,14 @@ void write_type(FILE *h, type_t *t)
} }
else fprintf(h, "enum %s", t->name); else fprintf(h, "enum %s", t->name);
break; break;
case RPC_FC_ERROR_STATUS_T:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "error_status_t");
break;
case RPC_FC_BIND_PRIMITIVE:
if (t->ref) fprintf(h, t->ref->name);
else fprintf(h, "handle_t");
break;
case RPC_FC_STRUCT: case RPC_FC_STRUCT:
case RPC_FC_CVSTRUCT: case RPC_FC_CVSTRUCT:
case RPC_FC_CPSTRUCT: case RPC_FC_CPSTRUCT:
@ -280,15 +297,24 @@ void write_type(FILE *h, type_t *t)
} }
else fprintf(h, "union %s", t->name); else fprintf(h, "union %s", t->name);
break; break;
case RPC_FC_RP:
case RPC_FC_UP:
case RPC_FC_FP: case RPC_FC_FP:
case RPC_FC_OP: if (t->ref) write_type(h, t->ref, NULL, t->name);
if (t->ref) write_type(h, t->ref); fprintf(h, "*");
fprintf(h, "%s*", needs_space_after(t->ref) ? " " : "");
break; break;
default: default:
fprintf(h, "%s", t->name); fprintf(h, "(unknown-type:%d)", t->type);
}
}
else {
if (t->ref) {
write_type(h, t->ref, NULL, t->name);
}
else fprintf(h, "void");
}
}
if (v) {
for (c=0; c<v->ptr_level; c++) {
fprintf(h, "*");
} }
} }
} }
@ -311,16 +337,12 @@ static int user_type_registered(const char *name)
return 0; return 0;
} }
static void check_for_user_types(const var_list_t *list) static void check_for_user_types(const var_t *v)
{ {
const var_t *v; while (v) {
type_t *type = v->type;
if (!list) return; const char *name = v->tname;
LIST_FOR_EACH_ENTRY( v, list, const var_t, entry ) for (type = v->type; type; type = type->ref) {
{
type_t *type;
for (type = v->type; type; type = type->kind == TKIND_ALIAS ? type->orig : type->ref) {
const char *name = type->name;
if (type->user_types_registered) continue; if (type->user_types_registered) continue;
type->user_types_registered = 1; type->user_types_registered = 1;
if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
@ -335,11 +357,18 @@ static void check_for_user_types(const var_list_t *list)
* using a wire marshaled type */ * using a wire marshaled type */
break; break;
} }
else else if (type->fields)
{ {
check_for_user_types(type->fields); const var_t *fields = type->fields;
while (NEXT_LINK(fields)) fields = NEXT_LINK(fields);
check_for_user_types(fields);
} }
/* the wire_marshal attribute is always at least one reference away
* from the name of the type, so update it after the rest of the
* processing above */
if (type->name) name = type->name;
} }
v = PREV_LINK(v);
} }
} }
@ -349,18 +378,29 @@ void write_user_types(void)
for (ut = user_type_list; ut; ut = ut->next) for (ut = user_type_list; ut; ut = ut->next)
{ {
const char *name = ut->name; const char *name = ut->name;
fprintf(header, "ULONG __RPC_USER %s_UserSize (ULONG *, ULONG, %s *);\n", name, name); fprintf(header, "unsigned long __RPC_USER %s_UserSize (unsigned long *, unsigned long, %s *);\n", name, name);
fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (ULONG *, unsigned char *, %s *);\n", name, name); fprintf(header, "unsigned char * __RPC_USER %s_UserMarshal (unsigned long *, unsigned char *, %s *);\n", name, name);
fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(ULONG *, unsigned char *, %s *);\n", name, name); fprintf(header, "unsigned char * __RPC_USER %s_UserUnmarshal(unsigned long *, unsigned char *, %s *);\n", name, name);
fprintf(header, "void __RPC_USER %s_UserFree (ULONG *, %s *);\n", name, name); fprintf(header, "void __RPC_USER %s_UserFree (unsigned long *, %s *);\n", name, name);
} }
} }
void write_typedef(type_t *type) void write_typedef(type_t *type, const var_t *names)
{ {
const char *tname = names->tname;
const var_t *lname;
while (NEXT_LINK(names)) names = NEXT_LINK(names);
lname = names;
fprintf(header, "typedef "); fprintf(header, "typedef ");
write_type(header, type->orig); write_type(header, type, NULL, tname);
fprintf(header, "%s%s;\n", needs_space_after(type->orig) ? " " : "", type->name); fprintf(header, " ");
while (names) {
write_pident(header, names);
if (PREV_LINK(names))
fprintf(header, ", ");
names = PREV_LINK(names);
}
fprintf(header, ";\n");
} }
void write_expr(FILE *h, const expr_t *e, int brackets) void write_expr(FILE *h, const expr_t *e, int brackets)
@ -369,7 +409,7 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
case EXPR_VOID: case EXPR_VOID:
break; break;
case EXPR_NUM: case EXPR_NUM:
fprintf(h, "%lu", e->u.lval); fprintf(h, "%ld", e->u.lval);
break; break;
case EXPR_HEXNUM: case EXPR_HEXNUM:
fprintf(h, "0x%lx", e->u.lval); fprintf(h, "0x%lx", e->u.lval);
@ -397,13 +437,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
break; break;
case EXPR_CAST: case EXPR_CAST:
fprintf(h, "("); fprintf(h, "(");
write_type(h, e->u.tref); write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
fprintf(h, ")"); fprintf(h, ")");
write_expr(h, e->ref, 1); write_expr(h, e->ref, 1);
break; break;
case EXPR_SIZEOF: case EXPR_SIZEOF:
fprintf(h, "sizeof("); fprintf(h, "sizeof(");
write_type(h, e->u.tref); write_type(h, e->u.tref->ref, NULL, e->u.tref->name);
fprintf(h, ")"); fprintf(h, ")");
break; break;
case EXPR_SHL: case EXPR_SHL:
@ -452,17 +492,18 @@ void write_constdef(const var_t *v)
void write_externdef(const var_t *v) void write_externdef(const var_t *v)
{ {
fprintf(header, "extern const "); fprintf(header, "extern const ");
write_type(header, v->type); write_type(header, v->type, NULL, v->tname);
if (get_name(v)) if (get_name(v)) {
fprintf(header, " %s", v->name); fprintf(header, " ");
write_pident(header, v);
}
fprintf(header, ";\n\n"); fprintf(header, ";\n\n");
} }
void write_library(const char *name, const attr_list_t *attr) void write_library(const char *name, const attr_t *attr) {
{
const UUID *uuid = get_attrp(attr, ATTR_UUID); const UUID *uuid = get_attrp(attr, ATTR_UUID);
fprintf(header, "\n"); fprintf(header, "\n");
write_guid(header, "LIBID", name, uuid); write_guid("LIBID", name, uuid);
fprintf(header, "\n"); fprintf(header, "\n");
} }
@ -474,69 +515,85 @@ const var_t* get_explicit_handle_var(const func_t* func)
if (!func->args) if (!func->args)
return NULL; return NULL;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
if (var->type->type == RPC_FC_BIND_PRIMITIVE) if (var->type->type == RPC_FC_BIND_PRIMITIVE)
return var; return var;
var = PREV_LINK(var);
}
return NULL; return NULL;
} }
int has_out_arg_or_return(const func_t *func) int has_out_arg_or_return(const func_t *func)
{ {
const var_t *var; var_t *var;
if (!is_void(func->def->type)) if (!is_void(func->def->type, NULL))
return 1; return 1;
if (!func->args) if (!func->args)
return 0; return 0;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
if (is_attr(var->attrs, ATTR_OUT)) if (is_attr(var->attrs, ATTR_OUT))
return 1; return 1;
var = PREV_LINK(var);
}
return 0; return 0;
} }
/********** INTERFACES **********/ /********** INTERFACES **********/
int is_object(const attr_list_t *list) int is_object(const attr_t *a)
{ {
const attr_t *attr; while (a) {
if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) if (a->type == ATTR_OBJECT || a->type == ATTR_ODL) return 1;
if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1; a = NEXT_LINK(a);
return 0; }
return 0;
} }
int is_local(const attr_list_t *a) int is_local(const attr_t *a)
{ {
return is_attr(a, ATTR_LOCAL); return is_attr(a, ATTR_LOCAL);
} }
const var_t *is_callas(const attr_list_t *a) const var_t *is_callas(const attr_t *a)
{ {
return get_attrp(a, ATTR_CALLAS); return get_attrp(a, ATTR_CALLAS);
} }
static void write_method_macro(const type_t *iface, const char *name) static int write_method_macro(const type_t *iface, const char *name)
{ {
const func_t *cur; int idx;
func_t *cur = iface->funcs;
if (iface->ref) write_method_macro(iface->ref, name); if (iface->ref) idx = write_method_macro(iface->ref, name);
else idx = 0;
if (!iface->funcs) return; if (!cur) return idx;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
fprintf(header, "/*** %s methods ***/\n", iface->name); fprintf(header, "/*** %s methods ***/\n", iface->name);
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) while (cur) {
{
var_t *def = cur->def; var_t *def = cur->def;
if (!is_callas(def->attrs)) { if (!is_callas(def->attrs)) {
const var_t *arg; var_t *arg = cur->args;
int argc = 0; int argc = 0;
int c; int c;
while (arg) {
if (cur->args) LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry ) argc++; arg = NEXT_LINK(arg);
argc++;
}
fprintf(header, "#define %s_", name); fprintf(header, "#define %s_", name);
write_name(header,def); write_name(header,def);
@ -551,15 +608,22 @@ static void write_method_macro(const type_t *iface, const char *name)
for (c=0; c<argc; c++) for (c=0; c<argc; c++)
fprintf(header, ",%c", c+'a'); fprintf(header, ",%c", c+'a');
fprintf(header, ")\n"); fprintf(header, ")\n");
if (cur->idx == -1) cur->idx = idx;
else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
idx++;
} }
cur = PREV_LINK(cur);
} }
return idx;
} }
void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent) void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent)
{ {
const var_t *arg;
int count = 0; int count = 0;
if (arg) {
while (NEXT_LINK(arg))
arg = NEXT_LINK(arg);
}
if (do_indent) if (do_indent)
{ {
indentation++; indentation++;
@ -569,7 +633,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
fprintf(h, "%s* This", name); fprintf(h, "%s* This", name);
count++; count++;
} }
if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) { while (arg) {
if (count) { if (count) {
if (do_indent) if (do_indent)
{ {
@ -578,7 +642,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
} }
else fprintf(h, ","); else fprintf(h, ",");
} }
write_type(h, arg->type); write_type(h, arg->type, arg, arg->tname);
if (arg->args) if (arg->args)
{ {
fprintf(h, " (STDMETHODCALLTYPE *"); fprintf(h, " (STDMETHODCALLTYPE *");
@ -589,11 +653,11 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
} }
else else
{ {
if (needs_space_after(arg->type)) fprintf(h, " ");
fprintf(h, " ");
write_name(h, arg); write_name(h, arg);
} }
write_array(h, arg->array, 0); write_array(h, arg->array, 0);
arg = PREV_LINK(arg);
count++; count++;
} }
if (do_indent) indentation--; if (do_indent) indentation--;
@ -601,17 +665,16 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
static void write_cpp_method_def(const type_t *iface) static void write_cpp_method_def(const type_t *iface)
{ {
const func_t *cur; func_t *cur = iface->funcs;
if (!iface->funcs) return; if (!cur) return;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) while (cur) {
{
var_t *def = cur->def; var_t *def = cur->def;
if (!is_callas(def->attrs)) { if (!is_callas(def->attrs)) {
indent(header, 0); indent(header, 0);
fprintf(header, "virtual "); fprintf(header, "virtual ");
write_type(header, def->type); write_type(header, def->type, def, def->tname);
fprintf(header, " STDMETHODCALLTYPE "); fprintf(header, " STDMETHODCALLTYPE ");
write_name(header, def); write_name(header, def);
fprintf(header, "(\n"); fprintf(header, "(\n");
@ -619,24 +682,25 @@ static void write_cpp_method_def(const type_t *iface)
fprintf(header, ") = 0;\n"); fprintf(header, ") = 0;\n");
fprintf(header, "\n"); fprintf(header, "\n");
} }
cur = PREV_LINK(cur);
} }
} }
static void do_write_c_method_def(const type_t *iface, const char *name) static void do_write_c_method_def(const type_t *iface, const char *name)
{ {
const func_t *cur; const func_t *cur = iface->funcs;
if (iface->ref) do_write_c_method_def(iface->ref, name); if (iface->ref) do_write_c_method_def(iface->ref, name);
if (!iface->funcs) return; if (!cur) return;
while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
indent(header, 0); indent(header, 0);
fprintf(header, "/*** %s methods ***/\n", iface->name); fprintf(header, "/*** %s methods ***/\n", iface->name);
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) while (cur) {
{
const var_t *def = cur->def; const var_t *def = cur->def;
if (!is_callas(def->attrs)) { if (!is_callas(def->attrs)) {
indent(header, 0); indent(header, 0);
write_type(header, def->type); write_type(header, def->type, def, def->tname);
fprintf(header, " (STDMETHODCALLTYPE *"); fprintf(header, " (STDMETHODCALLTYPE *");
write_name(header, def); write_name(header, def);
fprintf(header, ")(\n"); fprintf(header, ")(\n");
@ -644,6 +708,7 @@ static void do_write_c_method_def(const type_t *iface, const char *name)
fprintf(header, ");\n"); fprintf(header, ");\n");
fprintf(header, "\n"); fprintf(header, "\n");
} }
cur = PREV_LINK(cur);
} }
} }
@ -659,17 +724,17 @@ static void write_c_disp_method_def(const type_t *iface)
static void write_method_proto(const type_t *iface) static void write_method_proto(const type_t *iface)
{ {
const func_t *cur; const func_t *cur = iface->funcs;
if (!iface->funcs) return; if (!cur) return;
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
{ while (cur) {
const var_t *def = cur->def; const var_t *def = cur->def;
const var_t *cas = is_callas(def->attrs); const var_t *cas = is_callas(def->attrs);
const var_t *args;
if (!is_local(def->attrs)) { if (!is_local(def->attrs)) {
/* proxy prototype */ /* proxy prototype */
write_type(header, def->type); write_type(header, def->type, def, def->tname);
fprintf(header, " CALLBACK %s_", iface->name); fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, def); write_name(header, def);
fprintf(header, "_Proxy(\n"); fprintf(header, "_Proxy(\n");
@ -683,23 +748,29 @@ static void write_method_proto(const type_t *iface)
fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
fprintf(header, " DWORD* pdwStubPhase);\n"); fprintf(header, " DWORD* pdwStubPhase);\n");
check_for_user_types(cur->args);
args = cur->args;
if (args) {
while (NEXT_LINK(args))
args = NEXT_LINK(args);
}
check_for_user_types(args);
} }
if (cas) { if (cas) {
const func_t *m; const func_t *m = iface->funcs;
LIST_FOR_EACH_ENTRY( m, iface->funcs, const func_t, entry ) while (m && strcmp(get_name(m->def), cas->name))
if (!strcmp(get_name(m->def), cas->name)) break; m = NEXT_LINK(m);
if (&m->entry != iface->funcs) { if (m) {
const var_t *mdef = m->def; const var_t *mdef = m->def;
/* proxy prototype - use local prototype */ /* proxy prototype - use local prototype */
write_type(header, mdef->type); write_type(header, mdef->type, mdef, mdef->tname);
fprintf(header, " CALLBACK %s_", iface->name); fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, mdef); write_name(header, mdef);
fprintf(header, "_Proxy(\n"); fprintf(header, "_Proxy(\n");
write_args(header, m->args, iface->name, 1, TRUE); write_args(header, m->args, iface->name, 1, TRUE);
fprintf(header, ");\n"); fprintf(header, ");\n");
/* stub prototype - use remotable prototype */ /* stub prototype - use remotable prototype */
write_type(header, def->type); write_type(header, def->type, def, def->tname);
fprintf(header, " __RPC_STUB %s_", iface->name); fprintf(header, " __RPC_STUB %s_", iface->name);
write_name(header, mdef); write_name(header, mdef);
fprintf(header, "_Stub(\n"); fprintf(header, "_Stub(\n");
@ -707,39 +778,23 @@ static void write_method_proto(const type_t *iface)
fprintf(header, ");\n"); fprintf(header, ");\n");
} }
else { else {
parser_warning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name); yywarning("invalid call_as attribute (%s -> %s)\n", get_name(def), cas->name);
} }
} }
cur = PREV_LINK(cur);
} }
} }
static void write_function_proto(const type_t *iface, const func_t *fun, const char *prefix) static void write_function_proto(const type_t *iface)
{
var_t *def = fun->def;
/* FIXME: do we need to handle call_as? */
write_type(header, def->type);
fprintf(header, " ");
write_prefix_name(header, prefix, def);
fprintf(header, "(\n");
if (fun->args)
write_args(header, fun->args, iface->name, 0, TRUE);
else
fprintf(header, " void");
fprintf(header, ");\n");
}
static void write_function_protos(const type_t *iface)
{ {
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
const var_t* explicit_handle_var; const var_t* explicit_handle_var;
const func_t *cur;
int prefixes_differ = strcmp(prefix_client, prefix_server);
if (!iface->funcs) return; func_t *cur = iface->funcs;
LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
{ while (cur) {
var_t *def = cur->def; var_t *def = cur->def;
/* check for a defined binding handle */ /* check for a defined binding handle */
@ -756,12 +811,18 @@ static void write_function_protos(const type_t *iface)
} }
} }
if (prefixes_differ) { /* FIXME: do we need to handle call_as? */
fprintf(header, "/* client prototype */\n"); write_type(header, def->type, def, def->tname);
write_function_proto(iface, cur, prefix_client); fprintf(header, " ");
fprintf(header, "/* server prototype */\n"); write_name(header, def);
} fprintf(header, "(\n");
write_function_proto(iface, cur, prefix_server); if (cur->args)
write_args(header, cur->args, iface->name, 0, TRUE);
else
fprintf(header, " void");
fprintf(header, ");\n");
cur = PREV_LINK(cur);
} }
} }
@ -785,25 +846,25 @@ void write_forward(type_t *iface)
static void write_iface_guid(const type_t *iface) static void write_iface_guid(const type_t *iface)
{ {
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
write_guid(header, "IID", iface->name, uuid); write_guid("IID", iface->name, uuid);
} }
static void write_dispiface_guid(const type_t *iface) static void write_dispiface_guid(const type_t *iface)
{ {
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
write_guid(header, "DIID", iface->name, uuid); write_guid("DIID", iface->name, uuid);
} }
static void write_coclass_guid(type_t *cocl) static void write_coclass_guid(type_t *cocl)
{ {
const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID); const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID);
write_guid(header, "CLSID", cocl->name, uuid); write_guid("CLSID", cocl->name, uuid);
} }
static void write_com_interface(type_t *iface) static void write_com_interface(type_t *iface)
{ {
if (!iface->funcs && !iface->ref) { if (!iface->funcs && !iface->ref) {
parser_warning("%s has no methods", iface->name); yywarning("%s has no methods", iface->name);
return; return;
} }
@ -848,7 +909,7 @@ static void write_com_interface(type_t *iface)
fprintf(header, " END_INTERFACE\n"); fprintf(header, " END_INTERFACE\n");
fprintf(header, "} %sVtbl;\n", iface->name); fprintf(header, "} %sVtbl;\n", iface->name);
fprintf(header, "interface %s {\n", iface->name); fprintf(header, "interface %s {\n", iface->name);
fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name);
fprintf(header, "};\n"); fprintf(header, "};\n");
fprintf(header, "\n"); fprintf(header, "\n");
fprintf(header, "#ifdef COBJMACROS\n"); fprintf(header, "#ifdef COBJMACROS\n");
@ -885,17 +946,15 @@ static void write_rpc_interface(const type_t *iface)
if (var) fprintf(header, "extern handle_t %s;\n", var); if (var) fprintf(header, "extern handle_t %s;\n", var);
if (old_names) if (old_names)
{ {
fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name); fprintf(header, "extern RPC_IF_HANDLE %s_ClientIfHandle;\n", iface->name);
fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name); fprintf(header, "extern RPC_IF_HANDLE %s_ServerIfHandle;\n", iface->name);
} }
else else
{ {
fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n", fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_c_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
prefix_client, iface->name, LOWORD(ver), HIWORD(ver)); fprintf(header, "extern RPC_IF_HANDLE %s_v%d_%d_s_ifspec;\n", iface->name, LOWORD(ver), HIWORD(ver));
fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n",
prefix_server, iface->name, LOWORD(ver), HIWORD(ver));
} }
write_function_protos(iface); write_function_proto(iface);
} }
fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name); fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
@ -935,7 +994,7 @@ void write_dispinterface(type_t *iface)
fprintf(header, " END_INTERFACE\n"); fprintf(header, " END_INTERFACE\n");
fprintf(header, "} %sVtbl;\n", iface->name); fprintf(header, "} %sVtbl;\n", iface->name);
fprintf(header, "interface %s {\n", iface->name); fprintf(header, "interface %s {\n", iface->name);
fprintf(header, " CONST_VTBL %sVtbl* lpVtbl;\n", iface->name); fprintf(header, " const %sVtbl* lpVtbl;\n", iface->name);
fprintf(header, "};\n"); fprintf(header, "};\n");
fprintf(header, "\n"); fprintf(header, "\n");
fprintf(header, "#ifdef COBJMACROS\n"); fprintf(header, "#ifdef COBJMACROS\n");

View file

@ -21,55 +21,42 @@
#ifndef __WIDL_HEADER_H #ifndef __WIDL_HEADER_H
#define __WIDL_HEADER_H #define __WIDL_HEADER_H
#include "widltypes.h" extern int is_attr(const attr_t *a, enum attr_type t);
extern void *get_attrp(const attr_t *a, enum attr_type t);
extern int is_ptrchain_attr(const var_t *var, enum attr_type t); extern unsigned long get_attrv(const attr_t *a, enum attr_type t);
extern int is_attr(const attr_list_t *list, enum attr_type t); extern int is_void(const type_t *t, const var_t *v);
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t);
extern int is_void(const type_t *t);
extern int is_conformant_array( const array_dims_t *array );
extern int is_non_void(const expr_list_t *list);
extern void write_name(FILE *h, const var_t *v); extern void write_name(FILE *h, const var_t *v);
extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v);
extern const char* get_name(const var_t *v); extern const char* get_name(const var_t *v);
extern void write_type(FILE *h, type_t *t); extern void write_type(FILE *h, type_t *t, const var_t *v, const char *n);
extern int is_object(const attr_list_t *list); extern int is_object(const attr_t *a);
extern int is_local(const attr_list_t *list); extern int is_local(const attr_t *a);
extern const var_t *is_callas(const attr_list_t *list); extern const var_t *is_callas(const attr_t *a);
extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); extern void write_args(FILE *h, var_t *arg, const char *name, int obj, int do_indent);
extern void write_array(FILE *h, array_dims_t *v, int field); extern void write_array(FILE *h, const expr_t *v, int field);
extern void write_forward(type_t *iface); extern void write_forward(type_t *iface);
extern void write_interface(type_t *iface); extern void write_interface(type_t *iface);
extern void write_dispinterface(type_t *iface); extern void write_dispinterface(type_t *iface);
extern void write_coclass(type_t *cocl); extern void write_coclass(type_t *cocl);
extern void write_coclass_forward(type_t *cocl); extern void write_coclass_forward(type_t *cocl);
extern void write_typedef(type_t *type); extern void write_typedef(type_t *type, const var_t *names);
extern void write_expr(FILE *h, const expr_t *e, int brackets); extern void write_expr(FILE *h, const expr_t *e, int brackets);
extern void write_constdef(const var_t *v); extern void write_constdef(const var_t *v);
extern void write_externdef(const var_t *v); extern void write_externdef(const var_t *v);
extern void write_library(const char *name, const attr_list_t *attr); extern void write_library(const char *name, const attr_t *attr);
extern void write_user_types(void); extern void write_user_types(void);
extern const var_t* get_explicit_handle_var(const func_t* func); extern const var_t* get_explicit_handle_var(const func_t* func);
extern int has_out_arg_or_return(const func_t *func); extern int has_out_arg_or_return(const func_t *func);
extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
const UUID *uuid);
static inline int last_ptr(const type_t *type) static inline int is_string_type(const attr_t *attrs, int ptr_level, const expr_t *array)
{
return is_ptr(type) && !is_ptr(type->ref);
}
static inline int is_string_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array)
{ {
return (is_attr(attrs, ATTR_STRING) && return (is_attr(attrs, ATTR_STRING) &&
((last_ptr(type) && !array) || (!is_ptr(type) && array))); ((ptr_level == 1 && !array) || (ptr_level == 0 && array)));
} }
static inline int is_array_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array) static inline int is_array_type(const attr_t *attrs, int ptr_level, const expr_t *array)
{ {
return ((last_ptr(type) && !array && is_attr(attrs, ATTR_SIZEIS)) || return ((ptr_level == 1 && !array && is_attr(attrs, ATTR_SIZEIS)) ||
(!is_ptr(type) && array)); (ptr_level == 0 && array));
} }
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -21,14 +21,14 @@
#ifndef __WIDL_PARSER_H #ifndef __WIDL_PARSER_H
#define __WIDL_PARSER_H #define __WIDL_PARSER_H
int parser_parse(void); int yyparse(void);
extern FILE *parser_in; extern FILE *yyin;
extern char *parser_text; extern char *yytext;
extern int parser_debug; extern int yydebug;
extern int yy_flex_debug; extern int yy_flex_debug;
int parser_lex(void); int yylex(void);
extern int import_stack_ptr; extern int import_stack_ptr;
int do_import(char *fname); int do_import(char *fname);

View file

@ -20,7 +20,7 @@
%option stack %option stack
%option nounput noyy_top_state %option nounput noyy_top_state
%option 8bit never-interactive prefix="parser_" %option 8bit never-interactive
nl \r?\n nl \r?\n
ws [ \f\t\r] ws [ \f\t\r]
@ -31,8 +31,7 @@ hex 0x{hexd}+
uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12} uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
%x QUOTE %x QUOTE
%x ATTR %x pp_line
%x PP_LINE
%{ %{
@ -64,7 +63,6 @@ static int cbufidx;
static int cbufalloc = 0; static int cbufalloc = 0;
static int kw_token(const char *kw); static int kw_token(const char *kw);
static int attr_token(const char *kw);
#define MAX_IMPORT_DEPTH 10 #define MAX_IMPORT_DEPTH 10
struct { struct {
@ -105,58 +103,55 @@ static UUID* parse_uuid(const char*u)
************************************************************************** **************************************************************************
*/ */
%% %%
<INITIAL,ATTR>^{ws}*\#{ws}* yy_push_state(PP_LINE); <INITIAL>^{ws}*\#{ws}* yy_push_state(pp_line);
<PP_LINE>[^\n]* { <pp_line>[^\n]* {
int lineno; int lineno;
char *cptr, *fname; char *cptr, *fname;
yy_pop_state(); yy_pop_state();
lineno = (int)strtol(yytext, &cptr, 10); lineno = (int)strtol(yytext, &cptr, 10);
if(!lineno) if(!lineno)
parser_error("Malformed '#...' line-directive; invalid linenumber"); yyerror("Malformed '#...' line-directive; invalid linenumber");
fname = strchr(cptr, '"'); fname = strchr(cptr, '"');
if(!fname) if(!fname)
parser_error("Malformed '#...' line-directive; missing filename"); yyerror("Malformed '#...' line-directive; missing filename");
fname++; fname++;
cptr = strchr(fname, '"'); cptr = strchr(fname, '"');
if(!cptr) if(!cptr)
parser_error("Malformed '#...' line-directive; missing terminating \""); yyerror("Malformed '#...' line-directive; missing terminating \"");
*cptr = '\0'; *cptr = '\0';
line_number = lineno - 1; /* We didn't read the newline */ line_number = lineno - 1; /* We didn't read the newline */
free( input_name ); free( input_name );
input_name = xstrdup(fname); input_name = xstrdup(fname);
} }
<INITIAL,ATTR>\" yy_push_state(QUOTE); cbufidx = 0; \" yy_push_state(QUOTE); cbufidx = 0;
<QUOTE>\" { <QUOTE>\" {
yy_pop_state(); yy_pop_state();
parser_lval.str = get_buffered_cstring(); yylval.str = get_buffered_cstring();
return aSTRING; return aSTRING;
} }
<QUOTE>\\\\ | <QUOTE>\\\\ |
<QUOTE>\\\" addcchar(yytext[1]); <QUOTE>\\\" addcchar(yytext[1]);
<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]); <QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
<QUOTE>. addcchar(yytext[0]); <QUOTE>. addcchar(yytext[0]);
<INITIAL,ATTR>\[ yy_push_state(ATTR); return '['; {uuid} {
<ATTR>\] yy_pop_state(); return ']'; yylval.uuid = parse_uuid(yytext);
<ATTR>{cident} return attr_token(yytext);
<ATTR>{uuid} {
parser_lval.uuid = parse_uuid(yytext);
return aUUID; return aUUID;
} }
<INITIAL,ATTR>{hex} { {hex} {
parser_lval.num = strtoul(yytext, NULL, 0); yylval.num = strtoul(yytext, NULL, 0);
return aHEXNUM; return aHEXNUM;
} }
<INITIAL,ATTR>{int} { {int} {
parser_lval.num = strtoul(yytext, NULL, 0); yylval.num = strtoul(yytext, NULL, 0);
return aNUM; return aNUM;
} }
SAFEARRAY{ws}*/\( return tSAFEARRAY; SAFEARRAY{ws}*/\( return tSAFEARRAY;
{cident} return kw_token(yytext); {cident} return kw_token(yytext);
<INITIAL,ATTR>\n line_number++; \n line_number++;
<INITIAL,ATTR>{ws} {ws}
<INITIAL,ATTR>\<\< return SHL; \<\< return SHL;
<INITIAL,ATTR>\>\> return SHR; \>\> return SHR;
<INITIAL,ATTR>. return yytext[0]; . return yytext[0];
<<EOF>> { <<EOF>> {
if (import_stack_ptr) { if (import_stack_ptr) {
pop_import(); pop_import();
@ -166,27 +161,36 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
} }
%% %%
#ifndef parser_wrap #ifndef yywrap
int parser_wrap(void) int yywrap(void)
{ {
return 1; return 1;
} }
#endif #endif
struct keyword { static struct keyword {
const char *kw; const char *kw;
int token; int token;
}; int val;
} keywords[] = {
static const struct keyword keywords[] = {
{"FALSE", tFALSE}, {"FALSE", tFALSE},
{"TRUE", tTRUE}, {"TRUE", tTRUE},
{"__cdecl", tCDECL}, {"__cdecl", tCDECL},
{"__int64", tINT64}, {"__int64", tINT64},
{"__stdcall", tSTDCALL}, {"__stdcall", tSTDCALL},
{"_stdcall", tSTDCALL}, {"_stdcall", tSTDCALL},
{"aggregatable", tAGGREGATABLE},
{"allocate", tALLOCATE},
{"appobject", tAPPOBJECT},
{"async", tASYNC},
{"async_uuid", tASYNCUUID},
{"auto_handle", tAUTOHANDLE},
{"bindable", tBINDABLE},
{"boolean", tBOOLEAN}, {"boolean", tBOOLEAN},
{"broadcast", tBROADCAST},
{"byte", tBYTE}, {"byte", tBYTE},
{"byte_count", tBYTECOUNT},
{"call_as", tCALLAS},
{"callback", tCALLBACK}, {"callback", tCALLBACK},
{"case", tCASE}, {"case", tCASE},
{"char", tCHAR}, {"char", tCHAR},
@ -194,119 +198,121 @@ static const struct keyword keywords[] = {
{"code", tCODE}, {"code", tCODE},
{"comm_status", tCOMMSTATUS}, {"comm_status", tCOMMSTATUS},
{"const", tCONST}, {"const", tCONST},
{"context_handle", tCONTEXTHANDLE},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
{"control", tCONTROL},
{"cpp_quote", tCPPQUOTE}, {"cpp_quote", tCPPQUOTE},
/* ... */
{"default", tDEFAULT}, {"default", tDEFAULT},
{"defaultcollelem", tDEFAULTCOLLELEM},
{"defaultvalue", tDEFAULTVALUE},
{"defaultvtable", tDEFAULTVTABLE},
{"dispinterface", tDISPINTERFACE}, {"dispinterface", tDISPINTERFACE},
{"displaybind", tDISPLAYBIND},
{"dllname", tDLLNAME},
{"double", tDOUBLE}, {"double", tDOUBLE},
{"dual", tDUAL},
{"endpoint", tENDPOINT},
{"entry", tENTRY},
{"enum", tENUM}, {"enum", tENUM},
{"error_status_t", tERRORSTATUST}, {"error_status_t", tERRORSTATUST},
{"explicit_handle", tEXPLICITHANDLE},
{"extern", tEXTERN}, {"extern", tEXTERN},
{"float", tFLOAT}, {"float", tFLOAT},
{"handle", tHANDLE},
{"handle_t", tHANDLET}, {"handle_t", tHANDLET},
{"helpcontext", tHELPCONTEXT},
{"helpfile", tHELPFILE},
{"helpstring", tHELPSTRING},
{"helpstringcontext", tHELPSTRINGCONTEXT},
{"helpstringdll", tHELPSTRINGDLL},
{"hidden", tHIDDEN},
{"hyper", tHYPER}, {"hyper", tHYPER},
{"id", tID},
{"idempotent", tIDEMPOTENT},
/* ... */
{"iid_is", tIIDIS},
{"immediatebind", tIMMEDIATEBIND},
{"implicit_handle", tIMPLICITHANDLE},
{"import", tIMPORT}, {"import", tIMPORT},
{"importlib", tIMPORTLIB}, {"importlib", tIMPORTLIB},
{"in", tIN},
{"in_line", tINLINE}, {"in_line", tINLINE},
{"input_sync", tINPUTSYNC},
{"int", tINT}, {"int", tINT},
/* ... */
{"interface", tINTERFACE}, {"interface", tINTERFACE},
{"lcid", tLCID},
{"length_is", tLENGTHIS},
{"library", tLIBRARY}, {"library", tLIBRARY},
/* ... */
{"local", tLOCAL},
{"long", tLONG}, {"long", tLONG},
/* ... */
{"methods", tMETHODS}, {"methods", tMETHODS},
/* ... */
{"module", tMODULE}, {"module", tMODULE},
/* ... */
{"nonbrowsable", tNONBROWSABLE},
{"noncreatable", tNONCREATABLE},
{"nonextensible", tNONEXTENSIBLE},
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
/* ... */
{"optional", tOPTIONAL},
{"out", tOUT},
/* ... */
{"pointer_default", tPOINTERDEFAULT},
/* ... */
{"properties", tPROPERTIES}, {"properties", tPROPERTIES},
{"propget", tPROPGET},
{"propput", tPROPPUT},
{"propputref", tPROPPUTREF},
{"ptr", tPTR},
/* ... */
{"public", tPUBLIC},
{"range", tRANGE},
/* ... */
{"readonly", tREADONLY},
{"ref", tREF},
{"requestedit", tREQUESTEDIT},
{"restricted", tRESTRICTED},
{"retval", tRETVAL},
/* ... */
{"short", tSHORT}, {"short", tSHORT},
{"signed", tSIGNED}, {"signed", tSIGNED},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"sizeof", tSIZEOF}, {"sizeof", tSIZEOF},
{"small", tSMALL}, {"small", tSMALL},
/* ... */
{"source", tSOURCE},
/* ... */
{"string", tSTRING},
{"struct", tSTRUCT}, {"struct", tSTRUCT},
{"switch", tSWITCH}, {"switch", tSWITCH},
{"switch_is", tSWITCHIS},
{"switch_type", tSWITCHTYPE},
/* ... */
{"transmit_as", tTRANSMITAS},
{"typedef", tTYPEDEF}, {"typedef", tTYPEDEF},
{"union", tUNION}, {"union", tUNION},
/* ... */
{"unique", tUNIQUE},
{"unsigned", tUNSIGNED}, {"unsigned", tUNSIGNED},
/* ... */
{"uuid", tUUID},
{"v1_enum", tV1ENUM},
/* ... */
{"vararg", tVARARG},
{"version", tVERSION},
{"void", tVOID}, {"void", tVOID},
{"wchar_t", tWCHAR}, {"wchar_t", tWCHAR},
{"wire_marshal", tWIREMARSHAL},
}; };
#define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0])) #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
/* keywords only recognized in attribute lists */
static const struct keyword attr_keywords[] =
{
{"aggregatable", tAGGREGATABLE},
{"allocate", tALLOCATE},
{"appobject", tAPPOBJECT},
{"async", tASYNC},
{"async_uuid", tASYNCUUID},
{"auto_handle", tAUTOHANDLE},
{"bindable", tBINDABLE},
{"broadcast", tBROADCAST},
{"byte_count", tBYTECOUNT},
{"call_as", tCALLAS},
{"context_handle", tCONTEXTHANDLE},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
{"control", tCONTROL},
{"defaultcollelem", tDEFAULTCOLLELEM},
{"defaultvalue", tDEFAULTVALUE},
{"defaultvtable", tDEFAULTVTABLE},
{"displaybind", tDISPLAYBIND},
{"dllname", tDLLNAME},
{"dual", tDUAL},
{"endpoint", tENDPOINT},
{"entry", tENTRY},
{"explicit_handle", tEXPLICITHANDLE},
{"handle", tHANDLE},
{"helpcontext", tHELPCONTEXT},
{"helpfile", tHELPFILE},
{"helpstring", tHELPSTRING},
{"helpstringcontext", tHELPSTRINGCONTEXT},
{"helpstringdll", tHELPSTRINGDLL},
{"hidden", tHIDDEN},
{"id", tID},
{"idempotent", tIDEMPOTENT},
{"iid_is", tIIDIS},
{"immediatebind", tIMMEDIATEBIND},
{"implicit_handle", tIMPLICITHANDLE},
{"in", tIN},
{"input_sync", tINPUTSYNC},
{"lcid", tLCID},
{"length_is", tLENGTHIS},
{"local", tLOCAL},
{"nonbrowsable", tNONBROWSABLE},
{"noncreatable", tNONCREATABLE},
{"nonextensible", tNONEXTENSIBLE},
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
{"optional", tOPTIONAL},
{"out", tOUT},
{"pointer_default", tPOINTERDEFAULT},
{"propget", tPROPGET},
{"propput", tPROPPUT},
{"propputref", tPROPPUTREF},
{"ptr", tPTR},
{"public", tPUBLIC},
{"range", tRANGE},
{"readonly", tREADONLY},
{"ref", tREF},
{"requestedit", tREQUESTEDIT},
{"restricted", tRESTRICTED},
{"retval", tRETVAL},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"source", tSOURCE},
{"string", tSTRING},
{"switch_is", tSWITCHIS},
{"switch_type", tSWITCHTYPE},
{"transmit_as", tTRANSMITAS},
{"unique", tUNIQUE},
{"uuid", tUUID},
{"v1_enum", tV1ENUM},
{"vararg", tVARARG},
{"version", tVERSION},
{"wire_marshal", tWIREMARSHAL},
};
#define KWP(p) ((const struct keyword *)(p)) #define KWP(p) ((const struct keyword *)(p))
static int kw_cmp_func(const void *s1, const void *s2) static int kw_cmp_func(const void *s1, const void *s2)
@ -314,32 +320,31 @@ static int kw_cmp_func(const void *s1, const void *s2)
return strcmp(KWP(s1)->kw, KWP(s2)->kw); return strcmp(KWP(s1)->kw, KWP(s2)->kw);
} }
#define KW_BSEARCH
static int kw_token(const char *kw) static int kw_token(const char *kw)
{ {
struct keyword key, *kwp; struct keyword key, *kwp;
key.kw = kw; key.kw = kw;
#ifdef KW_BSEARCH
kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func); kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func);
#else
{
int i;
for (kwp=NULL, i=0; i < NKEYWORDS; i++)
if (!kw_cmp_func(&key, &keywords[i])) {
kwp = &keywords[i];
break;
}
}
#endif
if (kwp) { if (kwp) {
parser_lval.str = xstrdup(kwp->kw); yylval.str = (char*)kwp->kw;
return kwp->token; return kwp->token;
} }
parser_lval.str = xstrdup(kw); yylval.str = xstrdup(kw);
return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER; return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
} }
static int attr_token(const char *kw)
{
struct keyword key, *kwp;
key.kw = kw;
kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]),
sizeof(attr_keywords[0]), kw_cmp_func);
if (kwp) {
parser_lval.str = xstrdup(kwp->kw);
return kwp->token;
}
return kw_token(kw);
}
static void addcchar(char c) static void addcchar(char c)
{ {
if(cbufidx >= cbufalloc) if(cbufidx >= cbufalloc)
@ -347,7 +352,7 @@ static void addcchar(char c)
cbufalloc += 1024; cbufalloc += 1024;
cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0])); cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
if(cbufalloc > 65536) if(cbufalloc > 65536)
parser_warning("Reallocating string buffer larger than 64kB"); yywarning("Reallocating string buffer larger than 64kB");
} }
cbuffer[cbufidx++] = c; cbuffer[cbufidx++] = c;
} }
@ -409,7 +414,7 @@ int do_import(char *fname)
first_import = import; first_import = import;
if (!(path = wpp_find_include( fname, input_name ))) if (!(path = wpp_find_include( fname, input_name )))
parser_error("Unable to open include file %s", fname); yyerror("Unable to open include file %s", fname);
import_stack[ptr].temp_name = temp_name; import_stack[ptr].temp_name = temp_name;
import_stack[ptr].input_name = input_name; import_stack[ptr].input_name = input_name;
@ -422,7 +427,7 @@ int do_import(char *fname)
if (ret) exit(1); if (ret) exit(1);
if((f = fopen(temp_name, "r")) == NULL) if((f = fopen(temp_name, "r")) == NULL)
parser_error("Unable to open %s", temp_name); yyerror("Unable to open %s", temp_name);
import_stack[ptr].state = YY_CURRENT_BUFFER; import_stack[ptr].state = YY_CURRENT_BUFFER;
yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/* A Bison parser, made by GNU Bison 2.1. */ /* A Bison parser, made by GNU Bison 1.875. */
/* Skeleton parser for Yacc-like parsing with Bison, /* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -15,8 +15,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02110-1301, USA. */ Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a /* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction. Bison output file, you may use that output file without restriction.
@ -162,7 +162,6 @@
NEG = 388 NEG = 388
}; };
#endif #endif
/* Tokens. */
#define aIDENTIFIER 258 #define aIDENTIFIER 258
#define aKNOWNTYPE 259 #define aKNOWNTYPE 259
#define aNUM 260 #define aNUM 260
@ -299,35 +298,27 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 122 "tools\\widl_new\\parser.y" #line 109 "parser.y"
typedef union YYSTYPE { typedef union YYSTYPE {
attr_t *attr; attr_t *attr;
attr_list_t *attr_list;
str_list_t *str_list;
expr_t *expr; expr_t *expr;
expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type; type_t *type;
typeref_t *tref;
var_t *var; var_t *var;
var_list_t *var_list;
pident_t *pident;
pident_list_t *pident_list;
func_t *func; func_t *func;
func_list_t *func_list;
ifref_t *ifref; ifref_t *ifref;
ifref_list_t *ifref_list;
char *str; char *str;
UUID *uuid; UUID *uuid;
unsigned int num; unsigned int num;
} YYSTYPE; } YYSTYPE;
/* Line 1447 of yacc.c. */ /* Line 1248 of yacc.c. */
#line 325 "tools\\widl_new\\parser.tab.h" #line 315 "parser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
#endif #endif
extern YYSTYPE parser_lval; extern YYSTYPE yylval;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -52,9 +52,8 @@ static int print_server(const char *format, ...)
int i, r; int i, r;
va_start(va, format); va_start(va, format);
if (format[0] != '\n') for (i = 0; i < indent; i++)
for (i = 0; i < indent; i++) fprintf(server, " ");
fprintf(server, " ");
r = vfprintf(server, format, va); r = vfprintf(server, format, va);
va_end(va); va_end(va);
return r; return r;
@ -68,26 +67,136 @@ static void write_parameters_init(const func_t *func)
if (!func->args) if (!func->args)
return; return;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
if (var->type->type != RPC_FC_BIND_PRIMITIVE) if (var->type->type != RPC_FC_BIND_PRIMITIVE)
print_server("%s = 0;\n", var->name); print_server("%s = 0;\n", var->name);
var = PREV_LINK(var);
}
fprintf(server, "\n"); fprintf(server, "\n");
} }
static void write_function_stubs(type_t *iface, unsigned int *proc_offset) static void declare_args(const func_t *func)
{
int in_attr, out_attr;
int i = 0;
var_t *var;
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
const expr_t *size_is = get_attrp(var->attrs, ATTR_SIZEIS);
int has_size = size_is && (size_is->type != EXPR_VOID);
int is_string = is_attr(var->attrs, ATTR_STRING);
in_attr = is_attr(var->attrs, ATTR_IN);
out_attr = is_attr(var->attrs, ATTR_OUT);
if (!out_attr && !in_attr)
in_attr = 1;
if (!in_attr && !has_size && !is_string)
{
int indirection;
print_server("");
write_type(server, var->type, NULL, var->tname);
for (indirection = 0; indirection < var->ptr_level - 1; indirection++)
fprintf(server, "*");
fprintf(server, " _W%u;\n", i++);
}
print_server("");
write_type(server, var->type, var, var->tname);
fprintf(server, " ");
write_name(server, var);
write_array(server, var->array, 0);
fprintf(server, ";\n");
var = PREV_LINK(var);
}
}
static void assign_out_args(const func_t *func)
{
int in_attr, out_attr;
int i = 0, sep = 0;
var_t *var;
const expr_t *size_is;
int has_size;
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
int is_string = is_attr(var->attrs, ATTR_STRING);
size_is = get_attrp(var->attrs, ATTR_SIZEIS);
has_size = size_is && (size_is->type != EXPR_VOID);
in_attr = is_attr(var->attrs, ATTR_IN);
out_attr = is_attr(var->attrs, ATTR_OUT);
if (!out_attr && !in_attr)
in_attr = 1;
if (!in_attr)
{
print_server("");
write_name(server, var);
if (has_size)
{
unsigned int size;
type_t *type = var->type;
while (type->type == 0 && type->ref)
type = type->ref;
fprintf(server, " = NdrAllocate(&_StubMsg, ");
write_expr(server, size_is, 1);
size = get_type_memsize(type);
fprintf(server, " * %u);\n", size);
}
else if (!is_string)
{
fprintf(server, " = &_W%u;\n", i);
if (var->ptr_level > 1)
print_server("_W%u = 0;\n", i);
i++;
}
sep = 1;
}
var = PREV_LINK(var);
}
if (sep)
fprintf(server, "\n");
}
static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsigned int *type_offset)
{ {
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
const func_t *func; const func_t *func = iface->funcs;
const var_t *var; const var_t *var;
const var_t* explicit_handle_var; const var_t* explicit_handle_var;
if (!iface->funcs) return; while (NEXT_LINK(func)) func = NEXT_LINK(func);
LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) while (func)
{ {
const var_t *def = func->def; const var_t *def = func->def;
unsigned long buffer_size = 0;
unsigned int type_offset_func;
/* check for a defined binding handle */ /* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func); explicit_handle_var = get_explicit_handle_var(func);
@ -120,8 +229,16 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, "{\n"); fprintf(server, "{\n");
indent++; indent++;
/* declare return value '_RetVal' */
if (!is_void(def->type, NULL))
{
print_server("");
write_type(server, def->type, def, def->tname);
fprintf(server, " _RetVal;\n");
}
/* Declare arguments */ /* Declare arguments */
declare_stub_args(server, indent, func); declare_args(func);
print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
print_server("RPC_STATUS _Status;\n"); print_server("RPC_STATUS _Status;\n");
@ -163,8 +280,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent -= 2; indent -= 2;
fprintf(server, "\n"); fprintf(server, "\n");
/* make a copy so we don't increment the type offset twice */
type_offset_func = *type_offset;
/* unmarshall arguments */ /* unmarshall arguments */
write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL); write_remoting_arguments(server, indent, func, &type_offset_func, PASS_IN, PHASE_UNMARSHAL);
} }
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
@ -185,14 +305,14 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, "\n"); fprintf(server, "\n");
/* Assign 'out' arguments */ /* Assign 'out' arguments */
assign_stub_out_args(server, indent, func); assign_out_args(func);
/* Call the real server function */ /* Call the real server function */
if (!is_void(def->type)) if (!is_void(def->type, NULL))
print_server("_RetVal = "); print_server("_RetVal = ");
else else
print_server(""); print_server("");
write_prefix_name(server, prefix_server, def); write_name(server, def);
if (func->args) if (func->args)
{ {
@ -200,16 +320,17 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, "(\n"); fprintf(server, "(\n");
indent++; indent++;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{ {
if (first_arg) if (first_arg)
first_arg = 0; first_arg = 0;
else else
fprintf(server, ",\n"); fprintf(server, ",\n");
print_server(""); print_server("");
if (var->array)
fprintf(server, "*");
write_name(server, var); write_name(server, var);
var = PREV_LINK(var);
} }
fprintf(server, ");\n"); fprintf(server, ");\n");
indent--; indent--;
@ -219,9 +340,37 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, "();\n"); fprintf(server, "();\n");
} }
if (func->args)
{
const var_t *var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
if (is_attr(var->attrs, ATTR_OUT))
{
unsigned int alignment;
buffer_size += get_required_buffer_size(var, &alignment, PASS_OUT);
buffer_size += alignment;
}
var = PREV_LINK(var);
}
}
if (!is_void(def->type, NULL))
{
unsigned int alignment;
buffer_size += get_required_buffer_size(def, &alignment, PASS_RETURN);
buffer_size += alignment;
}
if (has_out_arg_or_return(func)) if (has_out_arg_or_return(func))
{ {
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE); fprintf(server, "\n");
print_server("_StubMsg.BufferLength = %u;\n", buffer_size);
type_offset_func = *type_offset;
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_BUFFERSIZE);
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
fprintf(server, "\n"); fprintf(server, "\n");
@ -235,11 +384,13 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, "\n"); fprintf(server, "\n");
} }
type_offset_func = *type_offset;
/* marshall arguments */ /* marshall arguments */
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL); write_remoting_arguments(server, indent, func, type_offset, PASS_OUT, PHASE_MARSHAL);
/* marshall the return value */ /* marshall the return value */
if (!is_void(def->type)) if (!is_void(def->type, NULL))
print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal");
indent--; indent--;
@ -248,7 +399,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_server("{\n"); print_server("{\n");
indent++; indent++;
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE); write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_FREE);
indent--; indent--;
print_server("}\n"); print_server("}\n");
@ -265,7 +416,22 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, "\n"); fprintf(server, "\n");
/* update proc_offset */ /* update proc_offset */
*proc_offset += get_size_procformatstring_func( func ); if (func->args)
{
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
*proc_offset += get_size_procformatstring_var(var);
var = PREV_LINK(var);
}
}
if (!is_void(def->type, NULL))
*proc_offset += get_size_procformatstring_var(def);
else
*proc_offset += 2; /* FC_END and FC_PAD */
func = PREV_LINK(func);
} }
} }
@ -274,13 +440,13 @@ static void write_dispatchtable(type_t *iface)
{ {
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
unsigned long method_count = 0; unsigned long method_count = 0;
const func_t *func; func_t *func = iface->funcs;
print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name); print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name);
print_server("{\n"); print_server("{\n");
indent++; indent++;
while (NEXT_LINK(func)) func = NEXT_LINK(func);
if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) while (func)
{ {
var_t *def = func->def; var_t *def = func->def;
@ -289,6 +455,7 @@ static void write_dispatchtable(type_t *iface)
fprintf(server, ",\n"); fprintf(server, ",\n");
method_count++; method_count++;
func = PREV_LINK(func);
} }
print_server("0\n"); print_server("0\n");
indent--; indent--;
@ -353,9 +520,6 @@ static void write_serverinterfacedecl(type_t *iface)
{ {
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION); unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
UUID *uuid = get_attrp(iface->attrs, ATTR_UUID); UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
const str_list_t *endpoints = get_attrp(iface->attrs, ATTR_ENDPOINT);
if (endpoints) write_endpoints( server, iface->name, endpoints );
print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, LOWORD(ver), HIWORD(ver)); print_server("extern RPC_DISPATCH_TABLE %s_v%d_%d_DispatchTable;\n", iface->name, LOWORD(ver), HIWORD(ver));
fprintf(server, "\n"); fprintf(server, "\n");
@ -369,16 +533,8 @@ static void write_serverinterfacedecl(type_t *iface)
uuid->Data4[7], LOWORD(ver), HIWORD(ver)); uuid->Data4[7], LOWORD(ver), HIWORD(ver));
print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */ print_server("{{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}},\n"); /* FIXME */
print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver)); print_server("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver));
if (endpoints) print_server("0,\n");
{ print_server("0,\n");
print_server("%u,\n", list_count(endpoints));
print_server("(PRPC_PROTSEQ_ENDPOINT)%s__RpcProtseqEndpoint,\n", iface->name);
}
else
{
print_server("0,\n");
print_server("0,\n");
}
print_server("0,\n"); print_server("0,\n");
print_server("0,\n"); print_server("0,\n");
print_server("0,\n"); print_server("0,\n");
@ -388,11 +544,41 @@ static void write_serverinterfacedecl(type_t *iface)
print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
iface->name, iface->name); iface->name, iface->name);
else else
print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n", print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
prefix_server, iface->name, LOWORD(ver), HIWORD(ver), iface->name); iface->name, LOWORD(ver), HIWORD(ver), iface->name);
fprintf(server, "\n"); fprintf(server, "\n");
} }
static void write_formatdesc( const char *str )
{
print_server("typedef struct _MIDL_%s_FORMAT_STRING\n", str );
print_server("{\n");
indent++;
print_server("short Pad;\n");
print_server("unsigned char Format[%s_FORMAT_STRING_SIZE];\n", str);
indent--;
print_server("} MIDL_%s_FORMAT_STRING;\n", str);
print_server("\n");
}
static void write_formatstringsdecl(ifref_t *ifaces)
{
print_server("#define TYPE_FORMAT_STRING_SIZE %d\n",
get_size_typeformatstring(ifaces));
print_server("#define PROC_FORMAT_STRING_SIZE %d\n",
get_size_procformatstring(ifaces));
fprintf(server, "\n");
write_formatdesc("TYPE");
write_formatdesc("PROC");
fprintf(server, "\n");
print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString;\n");
print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString;\n");
print_server("\n");
}
static void init_server(void) static void init_server(void)
{ {
@ -401,7 +587,7 @@ static void init_server(void)
if (!(server = fopen(server_name, "w"))) if (!(server = fopen(server_name, "w")))
error("Could not open %s for output\n", server_name); error("Could not open %s for output\n", server_name);
print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name);
print_server("#include <string.h>\n"); print_server("#include <string.h>\n");
fprintf(server, "\n"); fprintf(server, "\n");
print_server("#include \"%s\"\n", header_name); print_server("#include \"%s\"\n", header_name);
@ -409,23 +595,25 @@ static void init_server(void)
} }
void write_server(ifref_list_t *ifaces) void write_server(ifref_t *ifaces)
{ {
unsigned int proc_offset = 0; unsigned int proc_offset = 0;
ifref_t *iface; unsigned int type_offset = 2;
ifref_t *iface = ifaces;
if (!do_server) if (!do_server)
return; return;
if (do_everything && !ifaces) if (!ifaces)
return; return;
END_OF_LIST(iface);
init_server(); init_server();
if (!server) if (!server)
return; return;
write_formatstringsdecl(server, indent, ifaces, 0); write_formatstringsdecl(ifaces);
if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry ) for (; iface; iface = PREV_LINK(iface))
{ {
if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs)) if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
continue; continue;
@ -442,7 +630,7 @@ void write_server(ifref_list_t *ifaces)
write_serverinterfacedecl(iface->iface); write_serverinterfacedecl(iface->iface);
write_stubdescdecl(iface->iface); write_stubdescdecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset); write_function_stubs(iface->iface, &proc_offset, &type_offset);
print_server("#if !defined(__RPC_WIN32__)\n"); print_server("#if !defined(__RPC_WIN32__)\n");
print_server("#error Invalid build platform for this stub.\n"); print_server("#error Invalid build platform for this stub.\n");
@ -461,8 +649,8 @@ void write_server(ifref_list_t *ifaces)
fprintf(server, "\n"); fprintf(server, "\n");
write_procformatstring(server, ifaces, 0); write_procformatstring(server, ifaces);
write_typeformatstring(server, ifaces, 0); write_typeformatstring(server, ifaces);
fclose(server); fclose(server);
} }

File diff suppressed because it is too large Load diff

View file

@ -35,17 +35,15 @@ enum remoting_phase
PHASE_FREE PHASE_FREE
}; };
void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, int for_objects); void write_procformatstring(FILE *file, const ifref_t *ifaces);
void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects); void write_typeformatstring(FILE *file, const ifref_t *ifaces);
void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects); size_t get_type_memsize(const type_t *type);
unsigned int get_required_buffer_size(const var_t *var, unsigned int *alignment, enum pass pass);
void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname);
void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase); void write_remoting_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass, enum remoting_phase phase);
size_t get_size_procformatstring_var(const var_t *var); size_t get_size_procformatstring_var(const var_t *var);
size_t get_size_procformatstring_func(const func_t *func); size_t get_size_typeformatstring_var(const var_t *var);
size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects); size_t get_size_procformatstring(const ifref_t *ifaces);
size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects); size_t get_size_typeformatstring(const ifref_t *ifaces);
void assign_stub_out_args( FILE *file, int indent, const func_t *func );
void declare_stub_args( FILE *file, int indent, const func_t *func );
int write_expr_eval_routines(FILE *file, const char *iface); int write_expr_eval_routines(FILE *file, const char *iface);
void write_expr_eval_routine_list(FILE *file, const char *iface); void write_expr_eval_routine_list(FILE *file, const char *iface);
void write_endpoints( FILE *f, const char *prefix, const str_list_t *list );

View file

@ -50,38 +50,6 @@ int in_typelib = 0;
static typelib_t *typelib; static typelib_t *typelib;
type_t *duptype(type_t *t, int dupname)
{
type_t *d = xmalloc(sizeof *d);
*d = *t;
if (dupname && t->name)
d->name = xstrdup(t->name);
d->orig = t;
return d;
}
type_t *alias(type_t *t, const char *name)
{
type_t *a = duptype(t, 0);
a->name = xstrdup(name);
a->kind = TKIND_ALIAS;
a->attrs = NULL;
return a;
}
int is_ptr(const type_t *t)
{
unsigned char c = t->type;
return c == RPC_FC_RP
|| c == RPC_FC_UP
|| c == RPC_FC_FP
|| c == RPC_FC_OP;
}
/* List of oleauto types that should be recognized by name. /* List of oleauto types that should be recognized by name.
* (most of) these seem to be intrinsic types in mktyplib. */ * (most of) these seem to be intrinsic types in mktyplib. */
@ -146,9 +114,6 @@ unsigned short get_type_vt(type_t *t)
if (vt) return vt; if (vt) return vt;
} }
if (t->kind == TKIND_ALIAS && t->attrs)
return VT_USERDEFINED;
switch (t->type) { switch (t->type) {
case RPC_FC_BYTE: case RPC_FC_BYTE:
case RPC_FC_USMALL: case RPC_FC_USMALL:
@ -163,14 +128,14 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_USHORT: case RPC_FC_USHORT:
return VT_UI2; return VT_UI2;
case RPC_FC_LONG: case RPC_FC_LONG:
if (match(t->name, "int")) return VT_INT; if (t->ref && match(t->ref->name, "int")) return VT_INT;
return VT_I4; return VT_I4;
case RPC_FC_ULONG: case RPC_FC_ULONG:
if (match(t->name, "int")) return VT_UINT; if (t->ref && match(t->ref->name, "int")) return VT_UINT;
return VT_UI4; return VT_UI4;
case RPC_FC_HYPER: case RPC_FC_HYPER:
if (t->sign < 0) return VT_UI8; if (t->sign < 0) return VT_UI8;
if (match(t->name, "MIDL_uhyper")) return VT_UI8; if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8;
return VT_I8; return VT_I8;
case RPC_FC_FLOAT: case RPC_FC_FLOAT:
return VT_R4; return VT_R4;
@ -181,11 +146,7 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_OP: case RPC_FC_OP:
case RPC_FC_FP: case RPC_FC_FP:
if(t->ref) if(t->ref)
{
if (match(t->ref->name, "SAFEARRAY"))
return VT_SAFEARRAY;
return VT_PTR; return VT_PTR;
}
error("get_type_vt: unknown-deref-type: %d\n", t->ref->type); error("get_type_vt: unknown-deref-type: %d\n", t->ref->type);
break; break;
@ -205,14 +166,29 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_BOGUS_STRUCT: case RPC_FC_BOGUS_STRUCT:
return VT_USERDEFINED; return VT_USERDEFINED;
case 0: case 0:
return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED; if(t->attrs)
return VT_USERDEFINED;
return 0;
default: default:
error("get_type_vt: unknown type: 0x%02x\n", t->type); error("get_type_vt: unknown type: 0x%02x\n", t->type);
} }
return 0; return 0;
} }
void start_typelib(char *name, attr_list_t *attrs) unsigned short get_var_vt(var_t *v)
{
unsigned short vt;
chat("get_var_vt: %p tname %s\n", v, v->tname);
if (v->tname) {
vt = builtin_vt(v->tname);
if (vt) return vt;
}
return get_type_vt(v->type);
}
void start_typelib(char *name, attr_t *attrs)
{ {
in_typelib++; in_typelib++;
if (!do_typelib) return; if (!do_typelib) return;
@ -221,8 +197,6 @@ void start_typelib(char *name, attr_list_t *attrs)
typelib->name = xstrdup(name); typelib->name = xstrdup(name);
typelib->filename = xstrdup(typelib_name); typelib->filename = xstrdup(typelib_name);
typelib->attrs = attrs; typelib->attrs = attrs;
list_init( &typelib->entries );
list_init( &typelib->importlibs );
} }
void end_typelib(void) void end_typelib(void)
@ -234,18 +208,90 @@ void end_typelib(void)
return; return;
} }
void add_typelib_entry(type_t *t) void add_interface(type_t *iface)
{ {
typelib_entry_t *entry; typelib_entry_t *entry;
if (!typelib) return; if (!typelib) return;
chat("add kind %i: %s\n", t->kind, t->name); chat("add interface: %s\n", iface->name);
entry = xmalloc(sizeof(*entry)); entry = xmalloc(sizeof(*entry));
entry->type = t; entry->kind = TKIND_INTERFACE;
list_add_tail( &typelib->entries, &entry->entry ); entry->u.interface = iface;
LINK(entry, typelib->entry);
typelib->entry = entry;
} }
static void tlb_read(int fd, void *buf, int count) void add_coclass(type_t *cls)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add coclass: %s\n", cls->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_COCLASS;
entry->u.class = cls;
LINK(entry, typelib->entry);
typelib->entry = entry;
}
void add_module(type_t *module)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add module: %s\n", module->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_MODULE;
entry->u.module = module;
LINK(entry, typelib->entry);
typelib->entry = entry;
}
void add_struct(type_t *structure)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add struct: %s\n", structure->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_RECORD;
entry->u.structure = structure;
LINK(entry, typelib->entry);
typelib->entry = entry;
}
void add_enum(type_t *enumeration)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add enum: %s\n", enumeration->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_ENUM;
entry->u.enumeration = enumeration;
LINK(entry, typelib->entry);
typelib->entry = entry;
}
void add_typedef(type_t *tdef, var_t *name)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add typedef: %s\n", name->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_ALIAS;
entry->u.tdef = xmalloc(sizeof(*entry->u.tdef));
memcpy(entry->u.tdef, name, sizeof(*name));
entry->u.tdef->type = tdef;
entry->u.tdef->name = xstrdup(name->name);
LINK(entry, typelib->entry);
typelib->entry = entry;
}
static void tlb_read(int fd, void *buf, size_t count)
{ {
if(read(fd, buf, count) < count) if(read(fd, buf, count) < count)
error("error while reading importlib.\n"); error("error while reading importlib.\n");
@ -304,7 +350,6 @@ static void read_msft_importlib(importlib_t *importlib, int fd)
importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID; importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID;
msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid); msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid);
} }
else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid));
tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset); tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset);
tlb_read(fd, &nameintro, sizeof(nameintro)); tlb_read(fd, &nameintro, sizeof(nameintro));
@ -355,16 +400,18 @@ void add_importlib(const char *name)
if(!typelib) return; if(!typelib) return;
LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry ) for(importlib = typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) {
if(!strcmp(name, importlib->name)) if(!strcmp(name, importlib->name))
return; return;
}
chat("add_importlib: %s\n", name); chat("add_importlib: %s\n", name);
importlib = xmalloc(sizeof(*importlib)); importlib = xmalloc(sizeof(*importlib));
memset( importlib, 0, sizeof(*importlib) );
importlib->name = xstrdup(name); importlib->name = xstrdup(name);
read_importlib(importlib); read_importlib(importlib);
list_add_head( &typelib->importlibs, &importlib->entry );
LINK(importlib, typelib->importlibs);
typelib->importlibs = importlib;
} }

View file

@ -22,9 +22,14 @@
#define __WIDL_TYPELIB_H #define __WIDL_TYPELIB_H
extern int in_typelib; extern int in_typelib;
extern void start_typelib(char *name, attr_list_t *attrs); extern void start_typelib(char *name, attr_t *attrs);
extern void end_typelib(void); extern void end_typelib(void);
extern void add_typelib_entry(type_t *t); extern void add_interface(type_t *iface);
extern void add_coclass(type_t *cls);
extern void add_module(type_t *module);
extern void add_struct(type_t *structure);
extern void add_enum(type_t *enumeration);
extern void add_typedef(type_t *tdef, var_t *name);
extern void add_importlib(const char *name); extern void add_importlib(const char *name);
/* Copied from wtypes.h. Not included directly because that would create a /* Copied from wtypes.h. Not included directly because that would create a
@ -82,6 +87,7 @@ enum VARENUM {
VT_TYPEMASK = 0xfff VT_TYPEMASK = 0xfff
}; };
extern unsigned short get_type_vt(type_t *t); extern unsigned short get_type_vt(type_t *t);
extern unsigned short get_var_vt(var_t *v);
extern int create_msft_typelib(typelib_t *typelib); extern int create_msft_typelib(typelib_t *typelib);
#endif #endif

View file

@ -148,7 +148,7 @@ typedef struct tagMSFT_TypeInfoBase {
/*050*/ INT size; /* size in bytes, at least for structures */ /*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */ /* FIXME: name of this field */
INT datatype1; /* position in type description table */ INT datatype1; /* position in type description table */
/* or in base interfaces */ /* or in base intefaces */
/* if coclass: offset in reftable */ /* if coclass: offset in reftable */
/* if interface: reference to inherited if */ /* if interface: reference to inherited if */
INT datatype2; /* for interfaces: hiword is num of inherited funcs */ INT datatype2; /* for interfaces: hiword is num of inherited funcs */
@ -286,7 +286,7 @@ typedef struct {
/* 0x3800 if name is typeinfo name */ /* 0x3800 if name is typeinfo name */
/* upper 16 bits are hash code */ /* upper 16 bits are hash code */
} MSFT_NameIntro; } MSFT_NameIntro;
/* the custom data table directory has entries like this */ /* the custom data table directory has enties like this */
typedef struct { typedef struct {
INT GuidOffset; INT GuidOffset;
INT DataOffset; INT DataOffset;

View file

@ -34,9 +34,10 @@
#include "utils.h" #include "utils.h"
#include "parser.h" #include "parser.h"
static const int want_near_indication = 0; /* #define WANT_NEAR_INDICATION */
static void make_print(char *str) #ifdef WANT_NEAR_INDICATION
void make_print(char *str)
{ {
while(*str) while(*str)
{ {
@ -45,13 +46,13 @@ static void make_print(char *str)
str++; str++;
} }
} }
#endif
static void generic_msg(const char *s, const char *t, const char *n, va_list ap) static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
{ {
fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t); fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t);
vfprintf(stderr, s, ap); vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
if (want_near_indication)
{ {
char *cpy; char *cpy;
if(n) if(n)
@ -62,26 +63,26 @@ static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
free(cpy); free(cpy);
} }
} }
#endif
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
int parser_error(const char *s, ...) int yyerror(const char *s, ...)
{ {
va_list ap; va_list ap;
va_start(ap, s); va_start(ap, s);
generic_msg(s, "Error", parser_text, ap); generic_msg(s, "Error", yytext, ap);
va_end(ap); va_end(ap);
exit(1); exit(1);
return 1; return 1;
} }
int parser_warning(const char *s, ...) int yywarning(const char *s, ...)
{ {
va_list ap; va_list ap;
va_start(ap, s); va_start(ap, s);
generic_msg(s, "Warning", parser_text, ap); generic_msg(s, "Warning", yytext, ap);
va_end(ap); va_end(ap);
return 0; return 0;
} }
@ -144,7 +145,7 @@ char *dup_basename(const char *name, const char *ext)
namelen = strlen(name); namelen = strlen(name);
/* +4 for later extension and +1 for '\0' */ /* +4 for later extension and +1 for '\0' */
base = xmalloc(namelen +4 +1); base = (char *)xmalloc(namelen +4 +1);
strcpy(base, name); strcpy(base, name);
if(!strcasecmp(name + namelen-extlen, ext)) if(!strcasecmp(name + namelen-extlen, ext))
{ {
@ -163,7 +164,12 @@ void *xmalloc(size_t size)
{ {
error("Virtual memory exhausted.\n"); error("Virtual memory exhausted.\n");
} }
memset(res, 0x55, size); /*
* We set it to 0.
* This is *paramount* because we depend on it
* just about everywhere in the rest of the code.
*/
memset(res, 0, size);
return res; return res;
} }
@ -186,6 +192,6 @@ char *xstrdup(const char *str)
char *s; char *s;
assert(str != NULL); assert(str != NULL);
s = xmalloc(strlen(str)+1); s = (char *)xmalloc(strlen(str)+1);
return strcpy(s, str); return strcpy(s, str);
} }

View file

@ -33,8 +33,8 @@ char *xstrdup(const char *str);
#define __attribute__(X) #define __attribute__(X)
#endif #endif
int parser_error(const char *s, ...) __attribute__((format (printf, 1, 2))); int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int parser_warning(const char *s, ...) __attribute__((format (printf, 1, 2))); int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4))); void internal_error(const char *file, int line, const char *s, ...) __attribute__((format (printf, 3, 4)));
void error(const char *s, ...) __attribute__((format (printf, 1, 2))); void error(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));

View file

@ -22,7 +22,6 @@
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
@ -47,6 +46,8 @@
/* A = ACF input filename */ /* A = ACF input filename */
/* J = do not search standard include path */ /* J = do not search standard include path */
/* O = generate interpreted stubs */ /* O = generate interpreted stubs */
/* u = UUID file only? */
/* U = UUID filename */
/* w = select win16/win32 output (?) */ /* w = select win16/win32 output (?) */
static char usage[] = static char usage[] =
@ -63,15 +64,10 @@ static char usage[] =
" --oldnames Use old naming conventions\n" " --oldnames Use old naming conventions\n"
" -p Generate proxy\n" " -p Generate proxy\n"
" -P file Name of proxy file (default is infile_p.c)\n" " -P file Name of proxy file (default is infile_p.c)\n"
" --prefix-all=p Prefix names of client stubs / server functions with 'p'\n"
" --prefix-client=p Prefix names of client stubs with 'p'\n"
" --prefix-server=p Prefix names of server functions with 'p'\n"
" -s Generate server stub\n" " -s Generate server stub\n"
" -S file Name of server stub file (default is infile_s.c)\n" " -S file Name of server stub file (default is infile_s.c)\n"
" -t Generate typelib\n" " -t Generate typelib\n"
" -T file Name of typelib file (default is infile.tlb)\n" " -T file Name of typelib file (default is infile.tlb)\n"
" -u Generate interface identifiers file\n"
" -U file Name of interface identifiers file (default is infile_i.c)\n"
" -V Print version and exit\n" " -V Print version and exit\n"
" -W Enable pedantic warnings\n" " -W Enable pedantic warnings\n"
"Debug level 'n' is a bitmask with following meaning:\n" "Debug level 'n' is a bitmask with following meaning:\n"
@ -88,17 +84,16 @@ static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSIO
int win32 = 1; int win32 = 1;
int debuglevel = DEBUGLEVEL_NONE; int debuglevel = DEBUGLEVEL_NONE;
int parser_debug, yy_flex_debug; int yy_flex_debug;
int pedantic = 0; int pedantic = 0;
int do_everything = 1; static int do_everything = 1;
int preprocess_only = 0; int preprocess_only = 0;
int do_header = 0; int do_header = 0;
int do_typelib = 0; int do_typelib = 0;
int do_proxies = 0; int do_proxies = 0;
int do_client = 0; int do_client = 0;
int do_server = 0; int do_server = 0;
int do_idfile = 0;
int no_preprocess = 0; int no_preprocess = 0;
int old_names = 0; int old_names = 0;
@ -112,34 +107,19 @@ char *client_name;
char *client_token; char *client_token;
char *server_name; char *server_name;
char *server_token; char *server_token;
char *idfile_name;
char *idfile_token;
char *temp_name; char *temp_name;
const char *prefix_client = "";
const char *prefix_server = "";
int line_number = 1; int line_number = 1;
FILE *header; FILE *header;
FILE *proxy; FILE *proxy;
FILE *idfile;
time_t now; time_t now;
enum {
OLDNAMES_OPTION = CHAR_MAX + 1,
PREFIX_ALL_OPTION,
PREFIX_CLIENT_OPTION,
PREFIX_SERVER_OPTION
};
static const char *short_options = static const char *short_options =
"cC:d:D:EhH:I:NpP:sS:tT:uU:VW"; "cC:d:D:EhH:I:NpP:sS:tT:VW";
static struct option long_options[] = { static struct option long_options[] = {
{ "oldnames", no_argument, 0, OLDNAMES_OPTION }, { "oldnames", 0, 0, 1 },
{ "prefix-all", required_argument, 0, PREFIX_ALL_OPTION },
{ "prefix-client", required_argument, 0, PREFIX_CLIENT_OPTION },
{ "prefix-server", required_argument, 0, PREFIX_SERVER_OPTION },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
@ -197,25 +177,15 @@ int main(int argc,char *argv[])
while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) { while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF) {
switch(optc) { switch(optc) {
case OLDNAMES_OPTION: case 1:
old_names = 1; old_names = 1;
break; break;
case PREFIX_ALL_OPTION:
prefix_client = xstrdup(optarg);
prefix_server = xstrdup(optarg);
break;
case PREFIX_CLIENT_OPTION:
prefix_client = xstrdup(optarg);
break;
case PREFIX_SERVER_OPTION:
prefix_server = xstrdup(optarg);
break;
case 'c': case 'c':
do_everything = 0; do_everything = 0;
do_client = 1; do_client = 1;
break; break;
case 'C': case 'C':
client_name = xstrdup(optarg); client_name = strdup(optarg);
break; break;
case 'd': case 'd':
debuglevel = strtol(optarg, NULL, 0); debuglevel = strtol(optarg, NULL, 0);
@ -232,7 +202,7 @@ int main(int argc,char *argv[])
do_header = 1; do_header = 1;
break; break;
case 'H': case 'H':
header_name = xstrdup(optarg); header_name = strdup(optarg);
break; break;
case 'I': case 'I':
wpp_add_include_path(optarg); wpp_add_include_path(optarg);
@ -245,28 +215,21 @@ int main(int argc,char *argv[])
do_proxies = 1; do_proxies = 1;
break; break;
case 'P': case 'P':
proxy_name = xstrdup(optarg); proxy_name = strdup(optarg);
break; break;
case 's': case 's':
do_everything = 0; do_everything = 0;
do_server = 1; do_server = 1;
break; break;
case 'S': case 'S':
server_name = xstrdup(optarg); server_name = strdup(optarg);
break; break;
case 't': case 't':
do_everything = 0; do_everything = 0;
do_typelib = 1; do_typelib = 1;
break; break;
case 'T': case 'T':
typelib_name = xstrdup(optarg); typelib_name = strdup(optarg);
break;
case 'u':
do_everything = 0;
do_idfile = 1;
break;
case 'U':
idfile_name = xstrdup(optarg);
break; break;
case 'V': case 'V':
printf(version_string); printf(version_string);
@ -281,7 +244,7 @@ int main(int argc,char *argv[])
} }
if(do_everything) { if(do_everything) {
do_header = do_typelib = do_proxies = do_client = do_server = do_idfile = 1; do_header = do_typelib = do_proxies = do_client = do_server = 1;
} }
if(optind < argc) { if(optind < argc) {
input_name = xstrdup(argv[optind]); input_name = xstrdup(argv[optind]);
@ -297,7 +260,7 @@ int main(int argc,char *argv[])
setbuf(stderr,0); setbuf(stderr,0);
} }
parser_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; yydebug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0; yy_flex_debug = debuglevel & DEBUGLEVEL_TRACE ? 1 : 0;
wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0, wpp_set_debug( (debuglevel & DEBUGLEVEL_PPLEX) != 0,
@ -329,11 +292,6 @@ int main(int argc,char *argv[])
strcat(server_name, "_s.c"); strcat(server_name, "_s.c");
} }
if (!idfile_name && do_idfile) {
idfile_name = dup_basename(input_name, ".idl");
strcat(idfile_name, "_i.c");
}
if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c"); if (do_proxies) proxy_token = dup_basename_token(proxy_name,"_p.c");
if (do_client) client_token = dup_basename_token(client_name,"_c.c"); if (do_client) client_token = dup_basename_token(client_name,"_c.c");
if (do_server) server_token = dup_basename_token(server_name,"_s.c"); if (do_server) server_token = dup_basename_token(server_name,"_s.c");
@ -356,13 +314,13 @@ int main(int argc,char *argv[])
if(ret) exit(1); if(ret) exit(1);
if(preprocess_only) exit(0); if(preprocess_only) exit(0);
if(!(parser_in = fopen(temp_name, "r"))) { if(!(yyin = fopen(temp_name, "r"))) {
fprintf(stderr, "Could not open %s for input\n", temp_name); fprintf(stderr, "Could not open %s for input\n", temp_name);
return 1; return 1;
} }
} }
else { else {
if(!(parser_in = fopen(input_name, "r"))) { if(!(yyin = fopen(input_name, "r"))) {
fprintf(stderr, "Could not open %s for input\n", input_name); fprintf(stderr, "Could not open %s for input\n", input_name);
return 1; return 1;
} }
@ -385,28 +343,7 @@ int main(int argc,char *argv[])
fprintf(header, "#endif\n"); fprintf(header, "#endif\n");
} }
if (do_idfile) { ret = yyparse();
idfile_token = make_token(idfile_name);
idfile = fopen(idfile_name, "w");
if (! idfile) {
fprintf(stderr, "Could not open %s for output\n", idfile_name);
return 1;
}
fprintf(idfile, "/*** Autogenerated by WIDL %s ", PACKAGE_VERSION);
fprintf(idfile, "from %s - Do not edit ***/\n\n", input_name);
fprintf(idfile, "#include <rpc.h>\n");
fprintf(idfile, "#include <rpcndr.h>\n\n");
fprintf(idfile, "#define INITGUID\n");
fprintf(idfile, "#include <guiddef.h>\n\n");
fprintf(idfile, "#ifdef __cplusplus\n");
fprintf(idfile, "extern \"C\" {\n");
fprintf(idfile, "#endif\n\n");
}
init_types();
ret = parser_parse();
if(do_header) { if(do_header) {
fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
@ -422,16 +359,7 @@ int main(int argc,char *argv[])
fclose(header); fclose(header);
} }
if (do_idfile) { fclose(yyin);
fprintf(idfile, "\n");
fprintf(idfile, "#ifdef __cplusplus\n");
fprintf(idfile, "}\n");
fprintf(idfile, "#endif\n");
fclose(idfile);
}
fclose(parser_in);
if(ret) { if(ret) {
exit(1); exit(1);
@ -439,7 +367,6 @@ int main(int argc,char *argv[])
header_name = NULL; header_name = NULL;
client_name = NULL; client_name = NULL;
server_name = NULL; server_name = NULL;
idfile_name = NULL;
return 0; return 0;
} }

View file

@ -25,6 +25,8 @@
#include <time.h> #include <time.h>
#define WIDL_FULLVERSION "0.1"
extern int debuglevel; extern int debuglevel;
#define DEBUGLEVEL_NONE 0x0000 #define DEBUGLEVEL_NONE 0x0000
#define DEBUGLEVEL_CHAT 0x0001 #define DEBUGLEVEL_CHAT 0x0001
@ -36,13 +38,11 @@ extern int debuglevel;
extern int win32; extern int win32;
extern int pedantic; extern int pedantic;
extern int do_everything;
extern int do_header; extern int do_header;
extern int do_typelib; extern int do_typelib;
extern int do_proxies; extern int do_proxies;
extern int do_client; extern int do_client;
extern int do_server; extern int do_server;
extern int do_idfile;
extern int old_names; extern int old_names;
extern char *input_name; extern char *input_name;
@ -54,18 +54,15 @@ extern char *client_name;
extern char *client_token; extern char *client_token;
extern char *server_name; extern char *server_name;
extern char *server_token; extern char *server_token;
extern const char *prefix_client;
extern const char *prefix_server;
extern time_t now; extern time_t now;
extern int line_number; extern int line_number;
extern int char_number; extern int char_number;
extern FILE* header; extern FILE* header;
extern FILE* idfile;
extern void write_proxies(ifref_list_t *ifaces); extern void write_proxies(ifref_t *ifaces);
extern void write_client(ifref_list_t *ifaces); extern void write_client(ifref_t *ifaces);
extern void write_server(ifref_list_t *ifaces); extern void write_server(ifref_t *ifaces);
#endif #endif

View file

@ -34,13 +34,6 @@ Generate a type library.
Define the name of the type library to be generated. Define the name of the type library to be generated.
The default filename is infile.tlb. The default filename is infile.tlb.
.PP .PP
.B UUID file options:
.IP "\fB-u\fR"
Generate a UUID file.
.IP "\fB-U \fIfile\fR"
Define the name of the UUID file to be generated.
The default filename is infile_i.c.
.PP
.B Proxy/stub generation options: .B Proxy/stub generation options:
.IP "\fB-c\fR" .IP "\fB-c\fR"
Generate client stub. Generate client stub.

View file

@ -24,7 +24,6 @@
#include <stdarg.h> #include <stdarg.h>
#include "guiddef.h" #include "guiddef.h"
#include "wine/rpcfc.h" #include "wine/rpcfc.h"
#include "wine/list.h"
#ifndef UUID_DEFINED #ifndef UUID_DEFINED
#define UUID_DEFINED #define UUID_DEFINED
@ -39,7 +38,6 @@ typedef struct _expr_t expr_t;
typedef struct _type_t type_t; typedef struct _type_t type_t;
typedef struct _typeref_t typeref_t; typedef struct _typeref_t typeref_t;
typedef struct _var_t var_t; typedef struct _var_t var_t;
typedef struct _pident_t pident_t;
typedef struct _func_t func_t; typedef struct _func_t func_t;
typedef struct _ifref_t ifref_t; typedef struct _ifref_t ifref_t;
typedef struct _typelib_entry_t typelib_entry_t; typedef struct _typelib_entry_t typelib_entry_t;
@ -47,14 +45,23 @@ typedef struct _importlib_t importlib_t;
typedef struct _importinfo_t importinfo_t; typedef struct _importinfo_t importinfo_t;
typedef struct _typelib_t typelib_t; typedef struct _typelib_t typelib_t;
typedef struct list attr_list_t; #define DECL_LINK(type) \
typedef struct list str_list_t; type *l_next; \
typedef struct list func_list_t; type *l_prev
typedef struct list expr_list_t;
typedef struct list var_list_t; #define LINK(x,y) do { x->l_next = y; if (y) y->l_prev = x; } while (0)
typedef struct list pident_list_t;
typedef struct list ifref_list_t; #define INIT_LINK(x) do { x->l_next = NULL; x->l_prev = NULL; } while (0)
typedef struct list array_dims_t; #define NEXT_LINK(x) ((x)->l_next)
#define PREV_LINK(x) ((x)->l_prev)
#define END_OF_LIST(list) \
do { \
if (list) { \
while (NEXT_LINK(list)) \
list = NEXT_LINK(list); \
} \
} while(0)
enum attr_type enum attr_type
{ {
@ -165,12 +172,6 @@ enum type_kind
TKIND_MAX TKIND_MAX
}; };
struct str_list_entry_t
{
char *str;
struct list entry;
};
struct _attr_t { struct _attr_t {
enum attr_type type; enum attr_type type;
union { union {
@ -178,7 +179,7 @@ struct _attr_t {
void *pval; void *pval;
} u; } u;
/* parser-internal */ /* parser-internal */
struct list entry; DECL_LINK(attr_t);
}; };
struct _expr_t { struct _expr_t {
@ -188,13 +189,13 @@ struct _expr_t {
long lval; long lval;
const char *sval; const char *sval;
const expr_t *ext; const expr_t *ext;
type_t *tref; const typeref_t *tref;
} u; } u;
const expr_t *ext2; const expr_t *ext2;
int is_const; int is_const;
long cval; long cval;
/* parser-internal */ /* parser-internal */
struct list entry; DECL_LINK(expr_t);
}; };
struct _type_t { struct _type_t {
@ -202,57 +203,65 @@ struct _type_t {
enum type_kind kind; enum type_kind kind;
unsigned char type; unsigned char type;
struct _type_t *ref; struct _type_t *ref;
const attr_list_t *attrs; const attr_t *attrs;
func_list_t *funcs; /* interfaces and modules */ func_t *funcs; /* interfaces and modules */
var_list_t *fields; /* interfaces, structures and enumerations */ var_t *fields; /* interfaces, structures and enumerations */
ifref_list_t *ifaces; /* coclasses */ ifref_t *ifaces; /* coclasses */
type_t *orig; /* dup'd types */
unsigned int typestring_offset;
int ignore, is_const, sign; int ignore, is_const, sign;
int defined, written, user_types_registered; int defined, written, user_types_registered;
int typelib_idx; int typelib_idx;
/* parser-internal */
DECL_LINK(type_t);
};
struct _typeref_t {
char *name;
type_t *ref;
int uniq;
}; };
struct _var_t { struct _var_t {
char *name; char *name;
array_dims_t *array; int ptr_level;
expr_t *array;
type_t *type; type_t *type;
var_list_t *args; /* for function pointers */ var_t *args; /* for function pointers */
attr_list_t *attrs; const char *tname;
attr_t *attrs;
expr_t *eval; expr_t *eval;
/* parser-internal */ /* parser-internal */
struct list entry; DECL_LINK(var_t);
};
struct _pident_t {
var_t *var;
int ptr_level;
/* parser-internal */
struct list entry;
}; };
struct _func_t { struct _func_t {
var_t *def; var_t *def;
var_list_t *args; var_t *args;
int ignore, idx; int ignore, idx;
/* parser-internal */ /* parser-internal */
struct list entry; DECL_LINK(func_t);
}; };
struct _ifref_t { struct _ifref_t {
type_t *iface; type_t *iface;
attr_list_t *attrs; attr_t *attrs;
/* parser-internal */ /* parser-internal */
struct list entry; DECL_LINK(ifref_t);
}; };
struct _typelib_entry_t { struct _typelib_entry_t {
type_t *type; enum type_kind kind;
struct list entry; union {
type_t *class;
type_t *interface;
type_t *module;
type_t *structure;
type_t *enumeration;
var_t *tdef;
} u;
DECL_LINK(typelib_entry_t);
}; };
struct _importinfo_t { struct _importinfo_t {
@ -277,24 +286,15 @@ struct _importlib_t {
int allocated; int allocated;
struct list entry; DECL_LINK(importlib_t);
}; };
struct _typelib_t { struct _typelib_t {
char *name; char *name;
char *filename; char *filename;
attr_list_t *attrs; attr_t *attrs;
struct list entries; typelib_entry_t *entry;
struct list importlibs; importlib_t *importlibs;
}; };
void init_types(void);
type_t *duptype(type_t *t, int dupname);
type_t *alias(type_t *t, const char *name);
int is_ptr(const type_t *t);
int is_var_ptr(const var_t *v);
int cant_be_null(const var_t *v);
#endif #endif

View file

@ -49,7 +49,6 @@
#include "typelib.h" #include "typelib.h"
#include "typelib_struct.h" #include "typelib_struct.h"
#include "utils.h" #include "utils.h"
#include "header.h"
#include "hash.h" #include "hash.h"
enum MSFT_segment_index { enum MSFT_segment_index {
@ -330,6 +329,7 @@ static int ctl2_encode_name(
* safe in the slightest. * safe in the slightest.
*/ */
static int ctl2_encode_string( static int ctl2_encode_string(
msft_typelib_t *typelib, /* [I] The typelib to operate against (not used?). */
const char *string, /* [I] The string to encode. */ const char *string, /* [I] The string to encode. */
char **result) /* [O] A pointer to a pointer to receive the encoded string. */ char **result) /* [O] A pointer to a pointer to receive the encoded string. */
{ {
@ -362,6 +362,7 @@ static int ctl2_encode_string(
* RETURNS * RETURNS
* *
* Success: The offset within the segment of the new data area. * Success: The offset within the segment of the new data area.
* Failure: -1 (this is invariably an out of memory condition).
* *
* BUGS * BUGS
* *
@ -388,7 +389,8 @@ static int ctl2_alloc_segment(
char *block; char *block;
block_size = typelib->typelib_segment_block_length[segment]; block_size = typelib->typelib_segment_block_length[segment];
block = xrealloc(typelib->typelib_segment_data[segment], block_size << 1); block = realloc(typelib->typelib_segment_data[segment], block_size << 1);
if (!block) return -1;
if (segment == MSFT_SEG_TYPEINFO) { if (segment == MSFT_SEG_TYPEINFO) {
/* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */ /* TypeInfos have a direct pointer to their memory space, so we have to fix them up. */
@ -428,6 +430,7 @@ static int ctl2_alloc_typeinfo(
MSFT_TypeInfoBase *typeinfo; MSFT_TypeInfoBase *typeinfo;
offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0); offset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEINFO, sizeof(MSFT_TypeInfoBase), 0);
if (offset == -1) return -1;
typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset; typelib->typelib_typeinfo_offsets[typelib->typelib_header.nrtypeinfos++] = offset;
@ -472,6 +475,7 @@ static int ctl2_alloc_typeinfo(
* RETURNS * RETURNS
* *
* Success: The offset of the new GUID. * Success: The offset of the new GUID.
* Failure: -1 (this is invariably an out of memory condition).
*/ */
static int ctl2_alloc_guid( static int ctl2_alloc_guid(
msft_typelib_t *typelib, /* [I] The type library to allocate in. */ msft_typelib_t *typelib, /* [I] The type library to allocate in. */
@ -487,6 +491,7 @@ static int ctl2_alloc_guid(
if (offset != -1) return offset; if (offset != -1) return offset;
offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0); offset = ctl2_alloc_segment(typelib, MSFT_SEG_GUID, sizeof(MSFT_GuidEntry), 0);
if (offset == -1) return -1;
guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset); guid_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_GUID] + offset);
*guid_space = *guid; *guid_space = *guid;
@ -523,6 +528,7 @@ static int ctl2_alloc_name(
if (offset != -1) return offset; if (offset != -1) return offset;
offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0); offset = ctl2_alloc_segment(typelib, MSFT_SEG_NAME, length + 8, 0);
if (offset == -1) return -1;
name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset); name_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_NAME] + offset);
name_space->hreftype = -1; name_space->hreftype = -1;
@ -559,7 +565,7 @@ static int ctl2_alloc_string(
char *string_space; char *string_space;
char *encoded_string; char *encoded_string;
length = ctl2_encode_string(string, &encoded_string); length = ctl2_encode_string(typelib, string, &encoded_string);
for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length; for (offset = 0; offset < typelib->typelib_segdir[MSFT_SEG_STRING].length;
offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff) offset += ((((typelib->typelib_segment_data[MSFT_SEG_STRING][offset + 1] << 8) & 0xff)
@ -568,6 +574,7 @@ static int ctl2_alloc_string(
} }
offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0); offset = ctl2_alloc_segment(typelib, MSFT_SEG_STRING, length, 0);
if (offset == -1) return -1;
string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset; string_space = typelib->typelib_segment_data[MSFT_SEG_STRING] + offset;
memcpy(string_space, encoded_string, length); memcpy(string_space, encoded_string, length);
@ -604,6 +611,7 @@ static int alloc_msft_importinfo(
impinfo->flags |= typelib->typelib_header.nimpinfos++; impinfo->flags |= typelib->typelib_header.nimpinfos++;
offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0); offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTINFO, sizeof(MSFT_ImpInfo), 0);
if (offset == -1) return -1;
impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset); impinfo_space = (void *)(typelib->typelib_segment_data[MSFT_SEG_IMPORTINFO] + offset);
*impinfo_space = *impinfo; *impinfo_space = *impinfo;
@ -633,7 +641,7 @@ static int alloc_importfile(
MSFT_ImpFile *importfile; MSFT_ImpFile *importfile;
char *encoded_string; char *encoded_string;
length = ctl2_encode_string(filename, &encoded_string); length = ctl2_encode_string(typelib, filename, &encoded_string);
encoded_string[0] <<= 2; encoded_string[0] <<= 2;
encoded_string[0] |= 1; encoded_string[0] |= 1;
@ -645,6 +653,7 @@ static int alloc_importfile(
} }
offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0); offset = ctl2_alloc_segment(typelib, MSFT_SEG_IMPORTFILES, length + 0xc, 0);
if (offset == -1) return -1;
importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset]; importfile = (MSFT_ImpFile *)&typelib->typelib_segment_data[MSFT_SEG_IMPORTFILES][offset];
importfile->guid = guidoffset; importfile->guid = guidoffset;
@ -716,8 +725,7 @@ static importinfo_t *find_importinfo(msft_typelib_t *typelib, const char *name)
if(!name) if(!name)
return NULL; return NULL;
LIST_FOR_EACH_ENTRY( importlib, &typelib->typelib->importlibs, importlib_t, entry ) for(importlib = typelib->typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) {
{
for(i=0; i < importlib->ntypeinfos; i++) { for(i=0; i < importlib->ntypeinfos; i++) {
if(!strcmp(name, importlib->importinfos[i].name)) { if(!strcmp(name, importlib->importinfos[i].name)) {
chat("Found %s in importlib.\n", name); chat("Found %s in importlib.\n", name);
@ -733,7 +741,6 @@ static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure);
static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface); static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface);
static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration); static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls); static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls);
static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
/**************************************************************************** /****************************************************************************
@ -829,7 +836,6 @@ static int encode_type(
break; break;
case VT_CY: case VT_CY:
case VT_DATE:
*encoded_type = default_type; *encoded_type = default_type;
*width = 8; *width = 8;
*alignment = 8; *alignment = 8;
@ -903,22 +909,14 @@ static int encode_type(
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break; break;
} }
#if 0
case VT_SAFEARRAY: case VT_SAFEARRAY:
{ /* FIXME: Make with the error checking. */
int next_vt; FIXME("SAFEARRAY vartype, may not work correctly.\n");
/* skip over SAFEARRAY type straight to element type */ ctl2_encode_typedesc(typelib, tdesc->u.lptdesc, &target_type, NULL, NULL, &child_size);
type = type->ref;
for(next_vt = 0; type->ref; type = type->ref) {
next_vt = get_type_vt(type->ref);
if (next_vt != 0)
break;
}
encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size);
for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@ -942,23 +940,19 @@ static int encode_type(
typedata[1] = target_type; typedata[1] = target_type;
} }
*encoded_type = typeoffset; *encoded_tdesc = typeoffset;
*width = 4; *width = 4;
*alignment = 4; *alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; *decoded_size = sizeof(TYPEDESC) + child_size;
break; break;
}
#endif
case VT_USERDEFINED: case VT_USERDEFINED:
{ {
int typeinfo_offset; int typeinfo_offset;
/* typedef'd types without attributes aren't included in the typelib */
while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && ! type->attrs)
type = type->orig;
chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type, chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type,
type->name, type->type, type->typelib_idx); type->name, type->type, type->typelib_idx);
@ -982,8 +976,6 @@ static int encode_type(
case 0: case 0:
if (type->kind == TKIND_COCLASS) if (type->kind == TKIND_COCLASS)
add_coclass_typeinfo(typelib, type); add_coclass_typeinfo(typelib, type);
else if (type->kind == TKIND_DISPATCH)
add_dispinterface_typeinfo(typelib, type);
else else
error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n"); error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n");
break; break;
@ -1049,8 +1041,7 @@ static void dump_type(type_t *t)
static int encode_var( static int encode_var(
msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */ msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */
type_t *type, /* [I] The type description to encode. */ var_t *var, /* [I] The type description to encode. */
var_t *var, /* [I] The var to encode. */
int *encoded_type, /* [O] The encoded type description. */ int *encoded_type, /* [O] The encoded type description. */
int *width, /* [O] The width of the type, or NULL. */ int *width, /* [O] The width of the type, or NULL. */
int *alignment, /* [O] The alignment of the type, or NULL. */ int *alignment, /* [O] The alignment of the type, or NULL. */
@ -1062,18 +1053,19 @@ static int encode_var(
int child_size; int child_size;
int vt; int vt;
int scratch; int scratch;
type_t *type;
if (!width) width = &scratch; if (!width) width = &scratch;
if (!alignment) alignment = &scratch; if (!alignment) alignment = &scratch;
if (!decoded_size) decoded_size = &scratch; if (!decoded_size) decoded_size = &scratch;
*decoded_size = 0; *decoded_size = 0;
chat("encode_var: var %p type %p type->name %s type->ref %p\n", chat("encode_var: var %p var->tname %s var->type %p var->ptr_level %d var->type->ref %p\n", var, var->tname, var->type, var->ptr_level, var->type->ref);
var, type, type->name ? type->name : "NULL", type->ref); if(var->ptr_level) {
int skip_ptr;
vt = get_type_vt(type); var->ptr_level--;
if (vt == VT_PTR) { skip_ptr = encode_var(typelib, var, &target_type, NULL, NULL, &child_size);
int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size); var->ptr_level++;
if(skip_ptr == 2) { if(skip_ptr == 2) {
chat("encode_var: skipping ptr\n"); chat("encode_var: skipping ptr\n");
@ -1115,15 +1107,19 @@ static int encode_var(
} }
if(var->array) { if(var->array) {
expr_t *dim; expr_t *dim = var->array;
array_dims_t *array_save; expr_t *array_save;
int num_dims = list_count( var->array ), elements = 1, arrayoffset; int num_dims = 1, elements = 1, arrayoffset;
int *arraydata; int *arraydata;
while(NEXT_LINK(dim)) {
dim = NEXT_LINK(dim);
num_dims++;
}
chat("array with %d dimensions\n", num_dims); chat("array with %d dimensions\n", num_dims);
array_save = var->array; array_save = var->array;
var->array = NULL; var->array = NULL;
encode_var(typelib, type, var, &target_type, width, alignment, NULL); encode_var(typelib, var, &target_type, width, alignment, NULL);
var->array = array_save; var->array = array_save;
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0); arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0);
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
@ -1133,12 +1129,12 @@ static int encode_var(
arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16);
arraydata += 2; arraydata += 2;
LIST_FOR_EACH_ENTRY( dim, var->array, expr_t, entry ) while(dim) {
{
arraydata[0] = dim->cval; arraydata[0] = dim->cval;
arraydata[1] = 0; arraydata[1] = 0;
arraydata += 2; arraydata += 2;
elements *= dim->cval; elements *= dim->cval;
dim = PREV_LINK(dim);
} }
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
@ -1152,8 +1148,18 @@ static int encode_var(
*decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
return 0; return 0;
} }
dump_type(type); dump_type(var->type);
vt = get_var_vt(var);
type = var->type;
while(!vt) {
if(type->ref == NULL) {
vt = VT_VOID;
break;
}
type = type->ref;
vt = get_type_vt(type);
}
encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size);
if(type->type == RPC_FC_IP) return 2; if(type->type == RPC_FC_IP) return 2;
return 0; return 0;
@ -1174,7 +1180,6 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value)
case VT_INT: case VT_INT:
case VT_UINT: case VT_UINT:
case VT_HRESULT: case VT_HRESULT:
case VT_PTR:
{ {
unsigned long *lv = value; unsigned long *lv = value;
if((*lv & 0x3ffffff) == *lv) { if((*lv & 0x3ffffff) == *lv) {
@ -1228,9 +1233,11 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
guidentry.next_hash = -1; guidentry.next_hash = -1;
guidoffset = ctl2_alloc_guid(typelib, &guidentry); guidoffset = ctl2_alloc_guid(typelib, &guidentry);
if (guidoffset == -1) return E_OUTOFMEMORY;
write_value(typelib, &data_out, vt, value); write_value(typelib, &data_out, vt, value);
custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0); custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0);
if (custoffset == -1) return E_OUTOFMEMORY;
custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset]; custdata = (int *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATAGUID][custoffset];
custdata[0] = guidoffset; custdata[0] = guidoffset;
@ -1241,14 +1248,14 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
return S_OK; return S_OK;
} }
static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int index) static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
{ {
int offset, name_offset; int offset, name_offset;
int *typedata, typedata_size; int *typedata, typedata_size;
int i, id, next_idx; int i, id, next_idx;
int decoded_size, extra_attr = 0; int decoded_size, extra_attr = 0;
int num_params = 0, num_defaults = 0; int num_params = 0, num_defaults = 0;
var_t *arg; var_t *arg, *last_arg = NULL;
char *namedata; char *namedata;
const attr_t *attr; const attr_t *attr;
unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */; unsigned int funcflags = 0, callconv = 4 /* CC_STDCALL */;
@ -1272,28 +1279,29 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
break; break;
} }
if (is_local( func->def->attrs )) { for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) {
chat("add_func_desc: skipping local function\n"); if(attr->type == ATTR_LOCAL) {
return S_FALSE; chat("add_func_desc: skipping local function\n");
return S_FALSE;
}
} }
if (func->args) for(arg = func->args; arg; arg = NEXT_LINK(arg)) {
LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) last_arg = arg;
{
num_params++; num_params++;
if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) {
if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) { if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING) {
num_defaults++; num_defaults++;
break; break;
} }
} }
} }
chat("add_func_desc: num of params %d\n", num_params); chat("add_func_desc: num of params %d\n", num_params);
name_offset = ctl2_alloc_name(typeinfo->typelib, func->def->name); name_offset = ctl2_alloc_name(typeinfo->typelib, func->def->name);
if (func->def->attrs) LIST_FOR_EACH_ENTRY( attr, func->def->attrs, const attr_t, entry ) { for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr)) {
expr_t *expr = attr->u.pval; expr_t *expr = attr->u.pval;
switch(attr->type) { switch(attr->type) {
case ATTR_ENTRY_ORDINAL: case ATTR_ENTRY_ORDINAL:
@ -1346,6 +1354,25 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
} }
} }
switch(invokekind) {
case 0x2: /* INVOKE_PROPERTYGET */
if((num_params != 0 && typeinfo->typekind == TKIND_DISPATCH)
|| (num_params != 1 && typeinfo->typekind == TKIND_INTERFACE)) {
error("expecting no args on a propget func\n");
return S_FALSE;
}
break;
case 0x4: /* INVOKE_PROPERTYPUT */
case 0x8: /* INVOKE_PROPERTYPUTREF */
if(num_params != 1) {
error("expecting one arg on a propput func\n");
return S_FALSE;
}
break;
default:
break;
}
/* allocate type data space for us */ /* allocate type data space for us */
typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12)); typedata_size = 0x18 + extra_attr * sizeof(int) + (num_params * (num_defaults ? 16 : 12));
@ -1387,7 +1414,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
/* fill out the basic type information */ /* fill out the basic type information */
typedata[0] = typedata_size | (index << 16); typedata[0] = typedata_size | (index << 16);
encode_var(typeinfo->typelib, func->def->type, func->def, &typedata[1], NULL, NULL, &decoded_size); encode_var(typeinfo->typelib, func->def, &typedata[1], NULL, NULL, &decoded_size);
typedata[2] = funcflags; typedata[2] = funcflags;
typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind;
@ -1413,11 +1440,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
warning("unknown number of optional attrs\n"); warning("unknown number of optional attrs\n");
} }
if (func->args) for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) {
{
i = 0;
LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry )
{
const attr_t *attr; const attr_t *attr;
int paramflags = 0; int paramflags = 0;
int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
@ -1425,8 +1448,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
if(defaultdata) *defaultdata = -1; if(defaultdata) *defaultdata = -1;
encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size); encode_var(typeinfo->typelib, arg, paramdata, NULL, NULL, &decoded_size);
if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { for(attr = arg->attrs; attr; attr = NEXT_LINK(attr)) {
switch(attr->type) { switch(attr->type) {
case ATTR_DEFAULTVALUE_EXPR: case ATTR_DEFAULTVALUE_EXPR:
{ {
@ -1435,7 +1458,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
if (arg->type->type == RPC_FC_ENUM16) if (arg->type->type == RPC_FC_ENUM16)
vt = VT_INT; vt = VT_INT;
else else
vt = get_type_vt(arg->type); vt = get_var_vt(arg);
paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
chat("default value %ld\n", expr->cval); chat("default value %ld\n", expr->cval);
write_value(typeinfo->typelib, defaultdata, vt, &expr->cval); write_value(typeinfo->typelib, defaultdata, vt, &expr->cval);
@ -1448,7 +1471,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
if (arg->type->type == RPC_FC_ENUM16) if (arg->type->type == RPC_FC_ENUM16)
vt = VT_INT; vt = VT_INT;
else else
vt = get_type_vt(arg->type); vt = get_var_vt(arg);
paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
chat("default value '%s'\n", s); chat("default value '%s'\n", s);
write_value(typeinfo->typelib, defaultdata, vt, s); write_value(typeinfo->typelib, defaultdata, vt, s);
@ -1475,8 +1498,6 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
paramdata[1] = -1; paramdata[1] = -1;
paramdata[2] = paramflags; paramdata[2] = paramflags;
typedata[3] += decoded_size << 16; typedata[3] += decoded_size << 16;
i++;
}
} }
if(typeinfo->funcs_allocated == 0) { if(typeinfo->funcs_allocated == 0) {
@ -1525,19 +1546,12 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
if(typeinfo->typekind == TKIND_MODULE) if(typeinfo->typekind == TKIND_MODULE)
namedata[9] |= 0x20; namedata[9] |= 0x20;
if (func->args) if(invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */) {
{ /* don't give the arg of a [propput*] func a name */
i = 0; for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) {
LIST_FOR_EACH_ENTRY( arg, func->args, var_t, entry ) int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
{ offset = ctl2_alloc_name(typeinfo->typelib, arg->name);
/* don't give the last arg of a [propput*] func a name */ paramdata[1] = offset;
if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
{
int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
offset = ctl2_alloc_name(typeinfo->typelib, arg->name);
paramdata[1] = offset;
}
i++;
} }
} }
return S_OK; return S_OK;
@ -1561,7 +1575,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
id = 0x40000000 + index; id = 0x40000000 + index;
if (var->attrs) LIST_FOR_EACH_ENTRY( attr, var->attrs, const attr_t, entry ) { for(attr = var->attrs; attr; attr = NEXT_LINK(attr)) {
expr_t *expr = attr->u.pval; expr_t *expr = attr->u.pval;
switch(attr->type) { switch(attr->type) {
case ATTR_HIDDEN: case ATTR_HIDDEN:
@ -1627,7 +1641,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
typeinfo->var_offsets[var_num] = offset; typeinfo->var_offsets[var_num] = offset;
/* figure out type widths and whatnot */ /* figure out type widths and whatnot */
encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth, encode_var(typeinfo->typelib, var, &typedata[1], &var_datawidth,
&var_alignment, &var_type_size); &var_alignment, &var_type_size);
/* pad out starting position to data width */ /* pad out starting position to data width */
@ -1720,9 +1734,8 @@ static HRESULT add_impl_type(msft_typeinfo_t *typeinfo, type_t *ref, importinfo_
} }
static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind, static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_kind kind,
const char *name, const attr_list_t *attrs) const char *name, const attr_t *attr, int idx)
{ {
const attr_t *attr;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
int nameoffset; int nameoffset;
int typeinfo_offset; int typeinfo_offset;
@ -1732,7 +1745,6 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_
chat("create_msft_typeinfo: name %s kind %d\n", name, kind); chat("create_msft_typeinfo: name %s kind %d\n", name, kind);
msft_typeinfo = xmalloc(sizeof(*msft_typeinfo)); msft_typeinfo = xmalloc(sizeof(*msft_typeinfo));
memset( msft_typeinfo, 0, sizeof(*msft_typeinfo) );
msft_typeinfo->typelib = typelib; msft_typeinfo->typelib = typelib;
@ -1751,7 +1763,7 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_
if(kind == TKIND_COCLASS) if(kind == TKIND_COCLASS)
typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */ typeinfo->flags |= 0x2; /* TYPEFLAG_FCANCREATE */
if (attrs) LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry ) { for( ; attr; attr = NEXT_LINK(attr)) {
switch(attr->type) { switch(attr->type) {
case ATTR_AGGREGATABLE: case ATTR_AGGREGATABLE:
if (kind == TKIND_COCLASS) if (kind == TKIND_COCLASS)
@ -1890,7 +1902,7 @@ static void add_dispatch(msft_typelib_t *typelib)
static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface)
{ {
int idx = 0; int idx = 0;
const func_t *func; func_t *func;
var_t *var; var_t *var;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
@ -1899,7 +1911,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos; dispinterface->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name, msft_typeinfo = create_msft_typeinfo(typelib, TKIND_DISPATCH, dispinterface->name,
dispinterface->attrs); dispinterface->attrs, typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->size = 4; msft_typeinfo->typeinfo->size = 4;
msft_typeinfo->typeinfo->typekind |= 0x2100; msft_typeinfo->typeinfo->typekind |= 0x2100;
@ -1908,38 +1920,50 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
add_dispatch(typelib); add_dispatch(typelib);
msft_typeinfo->typeinfo->cImplTypes = 1; msft_typeinfo->typeinfo->cImplTypes = 1;
/* count the no of funcs, as the variable indices come after the funcs */ /* count the no of funcs, as the variable indicies come after the funcs */
if (dispinterface->funcs) if((func = dispinterface->funcs)) {
LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++; idx++;
while(NEXT_LINK(func)) {
func = NEXT_LINK(func);
idx++;
}
}
if (dispinterface->fields) if((var = dispinterface->fields)) {
LIST_FOR_EACH_ENTRY( var, dispinterface->fields, var_t, entry ) while(NEXT_LINK(var)) var = NEXT_LINK(var);
add_var_desc(msft_typeinfo, idx++, var); while(var) {
add_var_desc(msft_typeinfo, idx, var);
idx++;
var = PREV_LINK(var);
}
}
if (dispinterface->funcs) idx = 0;
{ /* the func count above has already left us pointing at the first func */
idx = 0; while(func) {
LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
if(add_func_desc(msft_typeinfo, func, idx) == S_OK) idx++;
idx++; func = PREV_LINK(func);
} }
} }
static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
{ {
int idx = 0; int idx = 0;
const func_t *func; func_t *func;
type_t *ref; type_t *ref;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
importinfo_t *ref_importinfo = NULL; importinfo_t *ref_importinfo = NULL;
int num_parents = 0, num_funcs = 0; int num_parents = 0, num_funcs = 0;
const attr_t *attr;
const type_t *derived; const type_t *derived;
if (-1 < interface->typelib_idx) if (-1 < interface->typelib_idx)
return; return;
if (is_attr(interface->attrs, ATTR_DISPINTERFACE)) for(attr = interface->attrs; attr; attr = NEXT_LINK(attr))
return add_dispinterface_typeinfo(typelib, interface); if(attr->type == ATTR_DISPINTERFACE)
return add_dispinterface_typeinfo(typelib, interface);
/* midl adds the parent interface first, unless the parent itself /* midl adds the parent interface first, unless the parent itself
has no parent (i.e. it stops before IUnknown). */ has no parent (i.e. it stops before IUnknown). */
@ -1952,7 +1976,8 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
} }
interface->typelib_idx = typelib->typelib_header.nrtypeinfos; interface->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs,
typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->size = 4; msft_typeinfo->typeinfo->size = 4;
msft_typeinfo->typeinfo->typekind |= 0x2200; msft_typeinfo->typeinfo->typekind |= 0x2200;
@ -1970,64 +1995,86 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
/* count the number of inherited interfaces and non-local functions */ /* count the number of inherited interfaces and non-local functions */
for(ref = interface->ref; ref; ref = ref->ref) { for(ref = interface->ref; ref; ref = ref->ref) {
num_parents++; num_parents++;
if (ref->funcs) for(func = ref->funcs; func; func = NEXT_LINK(func)) {
LIST_FOR_EACH_ENTRY( func, ref->funcs, const func_t, entry ) const attr_t *attr;
if (!is_local(func->def->attrs)) num_funcs++; for(attr = func->def->attrs; attr; attr = NEXT_LINK(attr))
if(attr->type == ATTR_LOCAL)
break;
if(!attr)
num_funcs++;
}
} }
msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents; msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4; msft_typeinfo->typeinfo->cbSizeVft = num_funcs * 4;
if (interface->funcs) if((func = interface->funcs)) {
LIST_FOR_EACH_ENTRY( func, interface->funcs, const func_t, entry ) while(NEXT_LINK(func)) func = NEXT_LINK(func);
while(func) {
if(add_func_desc(msft_typeinfo, func, idx) == S_OK) if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
idx++; idx++;
func = PREV_LINK(func);
}
}
} }
static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure) static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure)
{ {
int idx = 0; int idx = 0;
var_t *cur; var_t *cur = structure->fields;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
if (-1 < structure->typelib_idx) if (-1 < structure->typelib_idx)
return; return;
structure->typelib_idx = typelib->typelib_header.nrtypeinfos; structure->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs,
typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->size = 0; msft_typeinfo->typeinfo->size = 0;
if (structure->fields) while(NEXT_LINK(cur)) cur = NEXT_LINK(cur);
LIST_FOR_EACH_ENTRY( cur, structure->fields, var_t, entry ) while(cur) {
add_var_desc(msft_typeinfo, idx++, cur); add_var_desc(msft_typeinfo, idx, cur);
idx++;
cur = PREV_LINK(cur);
}
} }
static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration)
{ {
int idx = 0; int idx = 0;
var_t *cur; var_t *cur = enumeration->fields;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos; enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs,
typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->size = 0; msft_typeinfo->typeinfo->size = 0;
if (enumeration->fields) while(NEXT_LINK(cur)) cur = NEXT_LINK(cur);
LIST_FOR_EACH_ENTRY( cur, enumeration->fields, var_t, entry ) while(cur) {
add_var_desc(msft_typeinfo, idx++, cur); add_var_desc(msft_typeinfo, idx, cur);
idx++;
cur = PREV_LINK(cur);
}
} }
static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) static void add_typedef_typeinfo(msft_typelib_t *typelib, var_t *tdef)
{ {
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
int alignment; int alignment;
const attr_t *attrs;
if (-1 < tdef->typelib_idx) if (-1 < tdef->type->typelib_idx)
return; return;
tdef->typelib_idx = typelib->typelib_header.nrtypeinfos; tdef->type->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->type->attrs,
encode_type(typelib, get_type_vt(tdef->orig), tdef->orig, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, typelib->typelib_header.nrtypeinfos);
attrs = tdef->type->attrs;
tdef->type->attrs = NULL;
encode_var(typelib, tdef, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size,
&alignment, &msft_typeinfo->typeinfo->datatype2); &alignment, &msft_typeinfo->typeinfo->datatype2);
tdef->type->attrs = attrs;
msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6);
} }
@ -2044,15 +2091,20 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls)
return; return;
cls->typelib_idx = typelib->typelib_header.nrtypeinfos; cls->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_COCLASS, cls->name, cls->attrs,
typelib->typelib_header.nrtypeinfos);
if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) num_ifaces++; if((iref = cls->ifaces)) {
num_ifaces++;
while(NEXT_LINK(iref)) {
iref = NEXT_LINK(iref);
num_ifaces++;
}
}
offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES, offset = msft_typeinfo->typeinfo->datatype1 = ctl2_alloc_segment(typelib, MSFT_SEG_REFERENCES,
num_ifaces * sizeof(*ref), 0); num_ifaces * sizeof(*ref), 0);
for(i = 0; i < num_ifaces; i++) {
i = 0;
if (cls->ifaces) LIST_FOR_EACH_ENTRY( iref, cls->ifaces, ifref_t, entry ) {
if(iref->iface->typelib_idx == -1) if(iref->iface->typelib_idx == -1)
add_interface_typeinfo(typelib, iref->iface); add_interface_typeinfo(typelib, iref->iface);
ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref)); ref = (MSFT_RefRecord*) (typelib->typelib_segment_data[MSFT_SEG_REFERENCES] + offset + i * sizeof(*ref));
@ -2063,7 +2115,7 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls)
if(i < num_ifaces - 1) if(i < num_ifaces - 1)
ref->onext = offset + (i + 1) * sizeof(*ref); ref->onext = offset + (i + 1) * sizeof(*ref);
if (iref->attrs) LIST_FOR_EACH_ENTRY( attr, iref->attrs, const attr_t, entry ) { for(attr = iref->attrs; attr; attr = NEXT_LINK(attr)) {
switch(attr->type) { switch(attr->type) {
case ATTR_DEFAULT: case ATTR_DEFAULT:
ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */ ref->flags |= 0x1; /* IMPLTYPEFLAG_FDEFAULT */
@ -2095,7 +2147,7 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls)
else if(!first) else if(!first)
first = ref; first = ref;
} }
i++; iref = PREV_LINK(iref);
} }
/* If we haven't had a default interface, then set the default flags on the /* If we haven't had a default interface, then set the default flags on the
@ -2113,54 +2165,57 @@ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls)
static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module) static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
{ {
int idx = 0; int idx = 0;
const func_t *func; func_t *func;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
if (-1 < module->typelib_idx) if (-1 < module->typelib_idx)
return; return;
module->typelib_idx = typelib->typelib_header.nrtypeinfos; module->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_MODULE, module->name, module->attrs,
typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->typekind |= 0x0a00; msft_typeinfo->typeinfo->typekind |= 0x0a00;
if (module->funcs) if((func = module->funcs)) {
LIST_FOR_EACH_ENTRY( func, module->funcs, const func_t, entry ) while(NEXT_LINK(func)) func = NEXT_LINK(func);
while(func) {
if(add_func_desc(msft_typeinfo, func, idx) == S_OK) if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
idx++; idx++;
func = PREV_LINK(func);
}
}
msft_typeinfo->typeinfo->size = idx; msft_typeinfo->typeinfo->size = idx;
} }
static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry)
{ {
switch(entry->type->kind) { switch(entry->kind) {
case TKIND_INTERFACE: case TKIND_INTERFACE:
case TKIND_DISPATCH: add_interface_typeinfo(typelib, entry->u.interface);
add_interface_typeinfo(typelib, entry->type);
break; break;
case TKIND_RECORD: case TKIND_RECORD:
add_structure_typeinfo(typelib, entry->type); add_structure_typeinfo(typelib, entry->u.structure);
break; break;
case TKIND_ENUM: case TKIND_ENUM:
add_enum_typeinfo(typelib, entry->type); add_enum_typeinfo(typelib, entry->u.enumeration);
break; break;
case TKIND_ALIAS: case TKIND_ALIAS:
add_typedef_typeinfo(typelib, entry->type); add_typedef_typeinfo(typelib, entry->u.tdef);
break; break;
case TKIND_COCLASS: case TKIND_COCLASS:
add_coclass_typeinfo(typelib, entry->type); add_coclass_typeinfo(typelib, entry->u.class);
break; break;
case TKIND_MODULE: case TKIND_MODULE:
add_module_typeinfo(typelib, entry->type); add_module_typeinfo(typelib, entry->u.module);
break; break;
default: default:
error("add_entry: unhandled type %d\n", entry->type->kind); error("add_entry: unhandled type %d\n", entry->kind);
break; break;
} }
} }
@ -2177,24 +2232,39 @@ static void set_name(msft_typelib_t *typelib)
static void set_version(msft_typelib_t *typelib) static void set_version(msft_typelib_t *typelib)
{ {
typelib->typelib_header.version = get_attrv( typelib->typelib->attrs, ATTR_VERSION ); long version = MAKELONG(0,0);
const attr_t *attr;
for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
if(attr->type == ATTR_VERSION) {
version = attr->u.ival;
}
}
typelib->typelib_header.version = version;
return;
} }
static void set_guid(msft_typelib_t *typelib) static void set_guid(msft_typelib_t *typelib)
{ {
MSFT_GuidEntry guidentry; MSFT_GuidEntry guidentry;
int offset; int offset;
void *ptr; const attr_t *attr;
GUID guid = {0,0,0,{0,0,0,0,0,0}}; GUID guid = {0,0,0,{0,0,0,0,0,0}};
guidentry.guid = guid; guidentry.guid = guid;
guidentry.hreftype = -2; guidentry.hreftype = -2;
guidentry.next_hash = -1; guidentry.next_hash = -1;
ptr = get_attrp( typelib->typelib->attrs, ATTR_UUID ); for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
if (ptr) guidentry.guid = *(GUID *)ptr; if(attr->type == ATTR_UUID) {
guidentry.guid = *(GUID*)(attr->u.pval);
}
}
offset = ctl2_alloc_guid(typelib, &guidentry); offset = ctl2_alloc_guid(typelib, &guidentry);
if (offset == -1) return;
typelib->typelib_header.posguid = offset; typelib->typelib_header.posguid = offset;
return; return;
@ -2202,55 +2272,71 @@ static void set_guid(msft_typelib_t *typelib)
static void set_doc_string(msft_typelib_t *typelib) static void set_doc_string(msft_typelib_t *typelib)
{ {
char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRING ); const attr_t *attr;
int offset;
if (str) for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
{ if(attr->type == ATTR_HELPSTRING) {
int offset = ctl2_alloc_string(typelib, str); offset = ctl2_alloc_string(typelib, attr->u.pval);
if (offset != -1) typelib->typelib_header.helpstring = offset; if (offset == -1) return;
typelib->typelib_header.helpstring = offset;
}
} }
return;
} }
static void set_help_file_name(msft_typelib_t *typelib) static void set_help_file_name(msft_typelib_t *typelib)
{ {
char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPFILE ); int offset;
const attr_t *attr;
if (str) for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
{ if(attr->type == ATTR_HELPFILE) {
int offset = ctl2_alloc_string(typelib, str); offset = ctl2_alloc_string(typelib, attr->u.pval);
if (offset != -1) if (offset == -1) return;
{
typelib->typelib_header.helpfile = offset; typelib->typelib_header.helpfile = offset;
typelib->typelib_header.varflags |= 0x10; typelib->typelib_header.varflags |= 0x10;
} }
} }
return;
} }
static void set_help_context(msft_typelib_t *typelib) static void set_help_context(msft_typelib_t *typelib)
{ {
const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPCONTEXT ); const attr_t *attr;
if (expr) typelib->typelib_header.helpcontext = expr->cval; for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
if(attr->type == ATTR_HELPCONTEXT) {
const expr_t *expr = (expr_t *)attr->u.pval;
typelib->typelib_header.helpcontext = expr->cval;
}
}
return;
} }
static void set_help_string_dll(msft_typelib_t *typelib) static void set_help_string_dll(msft_typelib_t *typelib)
{ {
char *str = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGDLL ); int offset;
const attr_t *attr;
if (str) for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
{ if(attr->type == ATTR_HELPSTRINGDLL) {
int offset = ctl2_alloc_string(typelib, str); offset = ctl2_alloc_string(typelib, attr->u.pval);
if (offset != -1) if (offset == -1) return;
{
typelib->help_string_dll_offset = offset; typelib->help_string_dll_offset = offset;
typelib->typelib_header.varflags |= 0x100; typelib->typelib_header.varflags |= 0x100;
} }
} }
return;
} }
static void set_help_string_context(msft_typelib_t *typelib) static void set_help_string_context(msft_typelib_t *typelib)
{ {
const expr_t *expr = get_attrp( typelib->typelib->attrs, ATTR_HELPSTRINGCONTEXT ); const attr_t *attr;
if (expr) typelib->typelib_header.helpstringcontext = expr->cval; for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
if(attr->type == ATTR_HELPSTRINGCONTEXT) {
const expr_t *expr = (expr_t *)attr->u.pval;
typelib->typelib_header.helpstringcontext = expr->cval;
}
}
return;
} }
static void set_lcid(msft_typelib_t *typelib) static void set_lcid(msft_typelib_t *typelib)
@ -2264,9 +2350,7 @@ static void set_lib_flags(msft_typelib_t *typelib)
const attr_t *attr; const attr_t *attr;
typelib->typelib_header.flags = 0; typelib->typelib_header.flags = 0;
if (!typelib->typelib->attrs) return; for(attr = typelib->typelib->attrs; attr; attr = NEXT_LINK(attr)) {
LIST_FOR_EACH_ENTRY( attr, typelib->typelib->attrs, const attr_t, entry )
{
switch(attr->type) { switch(attr->type) {
case ATTR_CONTROL: case ATTR_CONTROL:
typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */ typelib->typelib_header.flags |= 0x02; /* LIBFLAG_FCONTROL */
@ -2443,7 +2527,8 @@ int create_msft_typelib(typelib_t *typelib)
GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; GUID midl_time_guid = {0xde77ba63,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; GUID midl_version_guid = {0xde77ba64,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
msft = xmalloc(sizeof(*msft)); msft = malloc(sizeof(*msft));
if (!msft) return 0;
memset(msft, 0, sizeof(*msft)); memset(msft, 0, sizeof(*msft));
msft->typelib = typelib; msft->typelib = typelib;
@ -2459,11 +2544,7 @@ int create_msft_typelib(typelib_t *typelib)
if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; } if (ctl2_alloc_segment(msft, MSFT_SEG_GUIDHASH, 0x80, 0x80)) { failed = 1; }
if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; } if (ctl2_alloc_segment(msft, MSFT_SEG_NAMEHASH, 0x200, 0x200)) { failed = 1; }
if(failed) if(failed) return 0;
{
free(msft);
return 0;
}
msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH]; msft->typelib_guidhash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_GUIDHASH];
msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH]; msft->typelib_namehash_segment = (int *)msft->typelib_segment_data[MSFT_SEG_NAMEHASH];
@ -2488,10 +2569,12 @@ int create_msft_typelib(typelib_t *typelib)
set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset); set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset);
set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset); set_custdata(msft, &midl_version_guid, VT_UI4, &version, &msft->typelib_header.CustomDataOffset);
LIST_FOR_EACH_ENTRY( entry, &typelib->entries, typelib_entry_t, entry ) for(entry = typelib->entry; entry && NEXT_LINK(entry); entry = NEXT_LINK(entry))
;
for( ; entry; entry = PREV_LINK(entry))
add_entry(msft, entry); add_entry(msft, entry);
save_all_changes(msft); save_all_changes(msft);
free(msft);
return 1; return 1;
} }