Update WIDL to rev 20070519.

svn path=/trunk/; revision=26843
This commit is contained in:
Eric Kohl 2007-05-19 23:02:35 +00:00
parent 5cb63e5d4a
commit 486714fd5a
26 changed files with 5185 additions and 7796 deletions

View file

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

View file

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

View file

@ -50,82 +50,51 @@ static int print_client( const char *format, ... )
int i, r;
va_start(va, format);
for (i = 0; i < indent; i++)
fprintf(client, " ");
if (format[0] != '\n')
for (i = 0; i < indent; i++)
fprintf(client, " ");
r = vfprintf(client, format, va);
va_end(va);
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)
{
var_t *var;
int pointer_type;
const var_t *var;
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
{
pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (!pointer_type)
pointer_type = RPC_FC_RP;
if (pointer_type == RPC_FC_RP)
if (is_var_ptr(var) && cant_be_null(var))
{
if (var->ptr_level >= 1)
{
print_client("if (!%s)\n", var->name);
print_client("{\n");
indent++;
print_client("RpcRaiseException(RPC_X_NULL_REF_POINTER);\n");
indent--;
print_client("}\n\n");
}
print_client("if (!%s)\n", var->name);
print_client("{\n");
indent++;
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, unsigned int *type_offset)
static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{
const func_t *func = iface->funcs;
const func_t *func;
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
var_t *var;
const var_t *var;
int method_count = 0;
while (NEXT_LINK(func)) func = NEXT_LINK(func);
while (func)
if (!implicit_handle)
print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name);
if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{
const var_t *def = func->def;
const var_t* explicit_handle_var;
unsigned int type_offset_func;
/* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func);
@ -146,9 +115,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
}
}
write_type(client, def->type, def, def->tname);
write_type(client, def->type);
fprintf(client, " ");
write_name(client, def);
write_prefix_name(client, prefix_client, def);
fprintf(client, "(\n");
indent++;
if (func->args)
@ -163,10 +132,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
indent++;
/* declare return value '_RetVal' */
if (!is_void(def->type, NULL))
if (!is_void(def->type))
{
print_client("");
write_type(client, def->type, def, def->tname);
write_type(client, def->type);
fprintf(client, " _RetVal;\n");
}
@ -204,13 +173,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(client, "\n");
}
/* 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);
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
print_client("NdrGetBuffer(\n");
indent++;
@ -223,12 +186,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
indent--;
fprintf(client, "\n");
/* make a copy so we don't increment the type offset twice */
type_offset_func = *type_offset;
/* marshal arguments */
write_remoting_arguments(client, indent, func, &type_offset_func, PASS_IN, PHASE_MARSHAL);
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_MARSHAL);
/* send/receive message */
/* print_client("NdrNsSendReceive(\n"); */
@ -258,24 +217,19 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
/* unmarshall arguments */
fprintf(client, "\n");
write_remoting_arguments(client, indent, func, type_offset, PASS_OUT, PHASE_UNMARSHAL);
write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */
if (!is_void(def->type, NULL))
if (!is_void(def->type))
print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
/* update proc_offset */
if (func->args)
{
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
*proc_offset += get_size_procformatstring_var(var);
var = PREV_LINK(var);
}
}
if (!is_void(def->type, NULL))
if (!is_void(def->type))
*proc_offset += get_size_procformatstring_var(def);
else
*proc_offset += 2; /* FC_END and FC_PAD */
@ -297,7 +251,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
/* emit return code */
if (!is_void(def->type, NULL))
if (!is_void(def->type))
{
fprintf(client, "\n");
print_client("return _RetVal;\n");
@ -308,18 +262,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(client, "\n");
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)
{
print_client("static const MIDL_STUB_DESC %s_StubDesc;\n", iface->name);
@ -374,6 +320,9 @@ static void write_clientinterfacedecl(type_t *iface)
{
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
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("{\n");
@ -385,8 +334,16 @@ static void write_clientinterfacedecl(type_t *iface)
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("0,\n");
print_client("0,\n");
print_client("0,\n");
if (endpoints)
{
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");
@ -396,43 +353,12 @@ static void write_clientinterfacedecl(type_t *iface)
print_client("RPC_IF_HANDLE %s_ClientIfHandle = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
iface->name, iface->name);
else
print_client("RPC_IF_HANDLE %s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
iface->name, LOWORD(ver), HIWORD(ver), iface->name);
print_client("RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec = (RPC_IF_HANDLE)& %s___RpcClientInterface;\n",
prefix_client, iface->name, LOWORD(ver), HIWORD(ver), iface->name);
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)
{
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
@ -451,7 +377,7 @@ static void init_client(void)
if (!(client = fopen(client_name, "w")))
error("Could not open %s for output\n", client_name);
print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name);
print_client("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
print_client("#include <string.h>\n");
print_client("#ifdef _ALPHA_\n");
print_client("#include <stdarg.h>\n");
@ -462,25 +388,24 @@ static void init_client(void)
}
void write_client(ifref_t *ifaces)
void write_client(ifref_list_t *ifaces)
{
unsigned int proc_offset = 0;
unsigned int type_offset = 2;
ifref_t *iface = ifaces;
ifref_t *iface;
if (!do_client)
return;
if (!iface)
if (do_everything && !ifaces)
return;
END_OF_LIST(iface);
init_client();
if (!client)
return;
write_formatstringsdecl(ifaces);
write_formatstringsdecl(client, indent, ifaces, 0);
for (; iface; iface = PREV_LINK(iface))
if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry )
{
if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
continue;
@ -495,12 +420,10 @@ void write_client(ifref_t *ifaces)
int expr_eval_routines;
write_implicithandledecl(iface->iface);
write_clientinterfacedecl(iface->iface);
write_stubdescdecl(iface->iface);
write_bindinghandledecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset, &type_offset);
write_function_stubs(iface->iface, &proc_offset);
print_client("#if !defined(__RPC_WIN32__)\n");
print_client("#error Invalid build platform for this stub.\n");
@ -517,8 +440,8 @@ void write_client(ifref_t *ifaces)
fprintf(client, "\n");
write_procformatstring(client, ifaces);
write_typeformatstring(client, ifaces);
write_procformatstring(client, ifaces, 0);
write_typeformatstring(client, ifaces, 0);
fclose(client);
}

View file

@ -605,13 +605,7 @@ unsigned long lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr)
while (*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];
nLoWord = 37 * nLoWord + pnLookup[*str > 0x7f && nMask ? *str + 0x80 : *str];
str++;
}
/* Constrain to a prime modulo and sizeof(WORD) */

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -20,7 +20,7 @@
%option stack
%option nounput noyy_top_state
%option 8bit never-interactive
%option 8bit never-interactive prefix="parser_"
nl \r?\n
ws [ \f\t\r]
@ -31,7 +31,8 @@ hex 0x{hexd}+
uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
%x QUOTE
%x pp_line
%x ATTR
%x PP_LINE
%{
@ -63,6 +64,7 @@ static int cbufidx;
static int cbufalloc = 0;
static int kw_token(const char *kw);
static int attr_token(const char *kw);
#define MAX_IMPORT_DEPTH 10
struct {
@ -103,55 +105,58 @@ static UUID* parse_uuid(const char*u)
**************************************************************************
*/
%%
<INITIAL>^{ws}*\#{ws}* yy_push_state(pp_line);
<pp_line>[^\n]* {
<INITIAL,ATTR>^{ws}*\#{ws}* yy_push_state(PP_LINE);
<PP_LINE>[^\n]* {
int lineno;
char *cptr, *fname;
yy_pop_state();
lineno = (int)strtol(yytext, &cptr, 10);
if(!lineno)
yyerror("Malformed '#...' line-directive; invalid linenumber");
parser_error("Malformed '#...' line-directive; invalid linenumber");
fname = strchr(cptr, '"');
if(!fname)
yyerror("Malformed '#...' line-directive; missing filename");
parser_error("Malformed '#...' line-directive; missing filename");
fname++;
cptr = strchr(fname, '"');
if(!cptr)
yyerror("Malformed '#...' line-directive; missing terminating \"");
parser_error("Malformed '#...' line-directive; missing terminating \"");
*cptr = '\0';
line_number = lineno - 1; /* We didn't read the newline */
free( input_name );
input_name = xstrdup(fname);
}
\" yy_push_state(QUOTE); cbufidx = 0;
<INITIAL,ATTR>\" yy_push_state(QUOTE); cbufidx = 0;
<QUOTE>\" {
yy_pop_state();
yylval.str = get_buffered_cstring();
parser_lval.str = get_buffered_cstring();
return aSTRING;
}
<QUOTE>\\\\ |
<QUOTE>\\\" addcchar(yytext[1]);
<QUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
<QUOTE>. addcchar(yytext[0]);
{uuid} {
yylval.uuid = parse_uuid(yytext);
<INITIAL,ATTR>\[ yy_push_state(ATTR); return '[';
<ATTR>\] yy_pop_state(); return ']';
<ATTR>{cident} return attr_token(yytext);
<ATTR>{uuid} {
parser_lval.uuid = parse_uuid(yytext);
return aUUID;
}
{hex} {
yylval.num = strtoul(yytext, NULL, 0);
<INITIAL,ATTR>{hex} {
parser_lval.num = strtoul(yytext, NULL, 0);
return aHEXNUM;
}
{int} {
yylval.num = strtoul(yytext, NULL, 0);
<INITIAL,ATTR>{int} {
parser_lval.num = strtoul(yytext, NULL, 0);
return aNUM;
}
SAFEARRAY{ws}*/\( return tSAFEARRAY;
{cident} return kw_token(yytext);
\n line_number++;
{ws}
\<\< return SHL;
\>\> return SHR;
. return yytext[0];
<INITIAL,ATTR>\n line_number++;
<INITIAL,ATTR>{ws}
<INITIAL,ATTR>\<\< return SHL;
<INITIAL,ATTR>\>\> return SHR;
<INITIAL,ATTR>. return yytext[0];
<<EOF>> {
if (import_stack_ptr) {
pop_import();
@ -161,36 +166,27 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
}
%%
#ifndef yywrap
int yywrap(void)
#ifndef parser_wrap
int parser_wrap(void)
{
return 1;
}
#endif
static struct keyword {
struct keyword {
const char *kw;
int token;
int val;
} keywords[] = {
};
static const struct keyword keywords[] = {
{"FALSE", tFALSE},
{"TRUE", tTRUE},
{"__cdecl", tCDECL},
{"__int64", tINT64},
{"__stdcall", tSTDCALL},
{"_stdcall", tSTDCALL},
{"aggregatable", tAGGREGATABLE},
{"allocate", tALLOCATE},
{"appobject", tAPPOBJECT},
{"async", tASYNC},
{"async_uuid", tASYNCUUID},
{"auto_handle", tAUTOHANDLE},
{"bindable", tBINDABLE},
{"boolean", tBOOLEAN},
{"broadcast", tBROADCAST},
{"byte", tBYTE},
{"byte_count", tBYTECOUNT},
{"call_as", tCALLAS},
{"callback", tCALLBACK},
{"case", tCASE},
{"char", tCHAR},
@ -198,121 +194,119 @@ static struct keyword {
{"code", tCODE},
{"comm_status", tCOMMSTATUS},
{"const", tCONST},
{"context_handle", tCONTEXTHANDLE},
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
{"control", tCONTROL},
{"cpp_quote", tCPPQUOTE},
/* ... */
{"default", tDEFAULT},
{"defaultcollelem", tDEFAULTCOLLELEM},
{"defaultvalue", tDEFAULTVALUE},
{"defaultvtable", tDEFAULTVTABLE},
{"dispinterface", tDISPINTERFACE},
{"displaybind", tDISPLAYBIND},
{"dllname", tDLLNAME},
{"double", tDOUBLE},
{"dual", tDUAL},
{"endpoint", tENDPOINT},
{"entry", tENTRY},
{"enum", tENUM},
{"error_status_t", tERRORSTATUST},
{"explicit_handle", tEXPLICITHANDLE},
{"extern", tEXTERN},
{"float", tFLOAT},
{"handle", tHANDLE},
{"handle_t", tHANDLET},
{"helpcontext", tHELPCONTEXT},
{"helpfile", tHELPFILE},
{"helpstring", tHELPSTRING},
{"helpstringcontext", tHELPSTRINGCONTEXT},
{"helpstringdll", tHELPSTRINGDLL},
{"hidden", tHIDDEN},
{"hyper", tHYPER},
{"id", tID},
{"idempotent", tIDEMPOTENT},
/* ... */
{"iid_is", tIIDIS},
{"immediatebind", tIMMEDIATEBIND},
{"implicit_handle", tIMPLICITHANDLE},
{"import", tIMPORT},
{"importlib", tIMPORTLIB},
{"in", tIN},
{"in_line", tINLINE},
{"input_sync", tINPUTSYNC},
{"int", tINT},
/* ... */
{"interface", tINTERFACE},
{"lcid", tLCID},
{"length_is", tLENGTHIS},
{"library", tLIBRARY},
/* ... */
{"local", tLOCAL},
{"long", tLONG},
/* ... */
{"methods", tMETHODS},
/* ... */
{"module", tMODULE},
/* ... */
{"nonbrowsable", tNONBROWSABLE},
{"noncreatable", tNONCREATABLE},
{"nonextensible", tNONEXTENSIBLE},
{"object", tOBJECT},
{"odl", tODL},
{"oleautomation", tOLEAUTOMATION},
/* ... */
{"optional", tOPTIONAL},
{"out", tOUT},
/* ... */
{"pointer_default", tPOINTERDEFAULT},
/* ... */
{"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},
{"signed", tSIGNED},
{"single", tSINGLE},
{"size_is", tSIZEIS},
{"sizeof", tSIZEOF},
{"small", tSMALL},
/* ... */
{"source", tSOURCE},
/* ... */
{"string", tSTRING},
{"struct", tSTRUCT},
{"switch", tSWITCH},
{"switch_is", tSWITCHIS},
{"switch_type", tSWITCHTYPE},
/* ... */
{"transmit_as", tTRANSMITAS},
{"typedef", tTYPEDEF},
{"union", tUNION},
/* ... */
{"unique", tUNIQUE},
{"unsigned", tUNSIGNED},
/* ... */
{"uuid", tUUID},
{"v1_enum", tV1ENUM},
/* ... */
{"vararg", tVARARG},
{"version", tVERSION},
{"void", tVOID},
{"wchar_t", tWCHAR},
{"wire_marshal", tWIREMARSHAL},
};
#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))
static int kw_cmp_func(const void *s1, const void *s2)
@ -320,31 +314,32 @@ static int kw_cmp_func(const void *s1, const void *s2)
return strcmp(KWP(s1)->kw, KWP(s2)->kw);
}
#define KW_BSEARCH
static int kw_token(const char *kw)
{
struct keyword key, *kwp;
key.kw = kw;
#ifdef KW_BSEARCH
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) {
yylval.str = (char*)kwp->kw;
parser_lval.str = xstrdup(kwp->kw);
return kwp->token;
}
yylval.str = xstrdup(kw);
parser_lval.str = xstrdup(kw);
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)
{
if(cbufidx >= cbufalloc)
@ -352,7 +347,7 @@ static void addcchar(char c)
cbufalloc += 1024;
cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
if(cbufalloc > 65536)
yywarning("Reallocating string buffer larger than 64kB");
parser_warning("Reallocating string buffer larger than 64kB");
}
cbuffer[cbufidx++] = c;
}
@ -414,7 +409,7 @@ int do_import(char *fname)
first_import = import;
if (!(path = wpp_find_include( fname, input_name )))
yyerror("Unable to open include file %s", fname);
parser_error("Unable to open include file %s", fname);
import_stack[ptr].temp_name = temp_name;
import_stack[ptr].input_name = input_name;
@ -427,7 +422,7 @@ int do_import(char *fname)
if (ret) exit(1);
if((f = fopen(temp_name, "r")) == NULL)
yyerror("Unable to open %s", temp_name);
parser_error("Unable to open %s", temp_name);
import_stack[ptr].state = YY_CURRENT_BUFFER;
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 1.875. */
/* A Bison parser, made by GNU Bison 2.1. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
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
@ -15,8 +15,8 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
@ -162,6 +162,7 @@
NEG = 388
};
#endif
/* Tokens. */
#define aIDENTIFIER 258
#define aKNOWNTYPE 259
#define aNUM 260
@ -298,27 +299,35 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 109 "parser.y"
#line 122 "tools\\widl_new\\parser.y"
typedef union YYSTYPE {
attr_t *attr;
attr_list_t *attr_list;
str_list_t *str_list;
expr_t *expr;
expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type;
typeref_t *tref;
var_t *var;
var_list_t *var_list;
pident_t *pident;
pident_list_t *pident_list;
func_t *func;
func_list_t *func_list;
ifref_t *ifref;
ifref_list_t *ifref_list;
char *str;
UUID *uuid;
unsigned int num;
} YYSTYPE;
/* Line 1248 of yacc.c. */
#line 315 "parser.tab.h"
/* Line 1447 of yacc.c. */
#line 325 "tools\\widl_new\\parser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;
extern YYSTYPE parser_lval;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -52,8 +52,9 @@ static int print_server(const char *format, ...)
int i, r;
va_start(va, format);
for (i = 0; i < indent; i++)
fprintf(server, " ");
if (format[0] != '\n')
for (i = 0; i < indent; i++)
fprintf(server, " ");
r = vfprintf(server, format, va);
va_end(va);
return r;
@ -67,136 +68,26 @@ static void write_parameters_init(const func_t *func)
if (!func->args)
return;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
{
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
if (var->type->type != RPC_FC_BIND_PRIMITIVE)
print_server("%s = 0;\n", var->name);
var = PREV_LINK(var);
}
fprintf(server, "\n");
}
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)
static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{
char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
const func_t *func = iface->funcs;
const func_t *func;
const var_t *var;
const var_t* explicit_handle_var;
while (NEXT_LINK(func)) func = NEXT_LINK(func);
while (func)
if (!iface->funcs) return;
LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{
const var_t *def = func->def;
unsigned long buffer_size = 0;
unsigned int type_offset_func;
/* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func);
@ -229,16 +120,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(server, "{\n");
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_args(func);
declare_stub_args(server, indent, func);
print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
print_server("RPC_STATUS _Status;\n");
@ -280,11 +163,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
indent -= 2;
fprintf(server, "\n");
/* make a copy so we don't increment the type offset twice */
type_offset_func = *type_offset;
/* unmarshall arguments */
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_IN, PHASE_UNMARSHAL);
write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL);
}
print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n");
@ -305,14 +185,14 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(server, "\n");
/* Assign 'out' arguments */
assign_out_args(func);
assign_stub_out_args(server, indent, func);
/* Call the real server function */
if (!is_void(def->type, NULL))
if (!is_void(def->type))
print_server("_RetVal = ");
else
print_server("");
write_name(server, def);
write_prefix_name(server, prefix_server, def);
if (func->args)
{
@ -320,17 +200,16 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(server, "(\n");
indent++;
var = func->args;
while (NEXT_LINK(var)) var = NEXT_LINK(var);
while (var)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
{
if (first_arg)
first_arg = 0;
else
fprintf(server, ",\n");
print_server("");
if (var->array)
fprintf(server, "*");
write_name(server, var);
var = PREV_LINK(var);
}
fprintf(server, ");\n");
indent--;
@ -340,37 +219,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
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))
{
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);
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE);
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
fprintf(server, "\n");
@ -384,13 +235,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(server, "\n");
}
type_offset_func = *type_offset;
/* marshall arguments */
write_remoting_arguments(server, indent, func, type_offset, PASS_OUT, PHASE_MARSHAL);
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL);
/* marshall the return value */
if (!is_void(def->type, NULL))
if (!is_void(def->type))
print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal");
indent--;
@ -399,7 +248,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
print_server("{\n");
indent++;
write_remoting_arguments(server, indent, func, &type_offset_func, PASS_OUT, PHASE_FREE);
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE);
indent--;
print_server("}\n");
@ -416,22 +265,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
fprintf(server, "\n");
/* update proc_offset */
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);
*proc_offset += get_size_procformatstring_func( func );
}
}
@ -440,13 +274,13 @@ static void write_dispatchtable(type_t *iface)
{
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
unsigned long method_count = 0;
func_t *func = iface->funcs;
const func_t *func;
print_server("static RPC_DISPATCH_FUNCTION %s_table[] =\n", iface->name);
print_server("{\n");
indent++;
while (NEXT_LINK(func)) func = NEXT_LINK(func);
while (func)
if (iface->funcs) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{
var_t *def = func->def;
@ -455,7 +289,6 @@ static void write_dispatchtable(type_t *iface)
fprintf(server, ",\n");
method_count++;
func = PREV_LINK(func);
}
print_server("0\n");
indent--;
@ -520,6 +353,9 @@ static void write_serverinterfacedecl(type_t *iface)
{
unsigned long ver = get_attrv(iface->attrs, ATTR_VERSION);
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));
fprintf(server, "\n");
@ -533,8 +369,16 @@ static void write_serverinterfacedecl(type_t *iface)
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("&%s_v%d_%d_DispatchTable,\n", iface->name, LOWORD(ver), HIWORD(ver));
print_server("0,\n");
print_server("0,\n");
if (endpoints)
{
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");
@ -544,41 +388,11 @@ static void write_serverinterfacedecl(type_t *iface)
print_server("RPC_IF_HANDLE %s_ServerIfHandle = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
iface->name, iface->name);
else
print_server("RPC_IF_HANDLE %s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
iface->name, LOWORD(ver), HIWORD(ver), iface->name);
print_server("RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec = (RPC_IF_HANDLE)& %s___RpcServerInterface;\n",
prefix_server, iface->name, LOWORD(ver), HIWORD(ver), iface->name);
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)
{
@ -587,7 +401,7 @@ static void init_server(void)
if (!(server = fopen(server_name, "w")))
error("Could not open %s for output\n", server_name);
print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", WIDL_FULLVERSION, input_name);
print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
print_server("#include <string.h>\n");
fprintf(server, "\n");
print_server("#include \"%s\"\n", header_name);
@ -595,25 +409,23 @@ static void init_server(void)
}
void write_server(ifref_t *ifaces)
void write_server(ifref_list_t *ifaces)
{
unsigned int proc_offset = 0;
unsigned int type_offset = 2;
ifref_t *iface = ifaces;
ifref_t *iface;
if (!do_server)
return;
if (!ifaces)
if (do_everything && !ifaces)
return;
END_OF_LIST(iface);
init_server();
if (!server)
return;
write_formatstringsdecl(ifaces);
write_formatstringsdecl(server, indent, ifaces, 0);
for (; iface; iface = PREV_LINK(iface))
if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry )
{
if (is_object(iface->iface->attrs) || is_local(iface->iface->attrs))
continue;
@ -630,7 +442,7 @@ void write_server(ifref_t *ifaces)
write_serverinterfacedecl(iface->iface);
write_stubdescdecl(iface->iface);
write_function_stubs(iface->iface, &proc_offset, &type_offset);
write_function_stubs(iface->iface, &proc_offset);
print_server("#if !defined(__RPC_WIN32__)\n");
print_server("#error Invalid build platform for this stub.\n");
@ -649,8 +461,8 @@ void write_server(ifref_t *ifaces)
fprintf(server, "\n");
write_procformatstring(server, ifaces);
write_typeformatstring(server, ifaces);
write_procformatstring(server, ifaces, 0);
write_typeformatstring(server, ifaces, 0);
fclose(server);
}

File diff suppressed because it is too large Load diff

View file

@ -35,15 +35,17 @@ enum remoting_phase
PHASE_FREE
};
void write_procformatstring(FILE *file, const ifref_t *ifaces);
void write_typeformatstring(FILE *file, const ifref_t *ifaces);
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 write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, int for_objects);
void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects);
void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_objects);
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, unsigned int *type_offset, enum pass pass, enum remoting_phase phase);
void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase);
size_t get_size_procformatstring_var(const var_t *var);
size_t get_size_typeformatstring_var(const var_t *var);
size_t get_size_procformatstring(const ifref_t *ifaces);
size_t get_size_typeformatstring(const ifref_t *ifaces);
size_t get_size_procformatstring_func(const func_t *func);
size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects);
size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects);
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);
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,6 +50,38 @@ int in_typelib = 0;
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.
* (most of) these seem to be intrinsic types in mktyplib. */
@ -114,6 +146,9 @@ unsigned short get_type_vt(type_t *t)
if (vt) return vt;
}
if (t->kind == TKIND_ALIAS && t->attrs)
return VT_USERDEFINED;
switch (t->type) {
case RPC_FC_BYTE:
case RPC_FC_USMALL:
@ -128,14 +163,14 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_USHORT:
return VT_UI2;
case RPC_FC_LONG:
if (t->ref && match(t->ref->name, "int")) return VT_INT;
if (match(t->name, "int")) return VT_INT;
return VT_I4;
case RPC_FC_ULONG:
if (t->ref && match(t->ref->name, "int")) return VT_UINT;
if (match(t->name, "int")) return VT_UINT;
return VT_UI4;
case RPC_FC_HYPER:
if (t->sign < 0) return VT_UI8;
if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8;
if (match(t->name, "MIDL_uhyper")) return VT_UI8;
return VT_I8;
case RPC_FC_FLOAT:
return VT_R4;
@ -146,7 +181,11 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_OP:
case RPC_FC_FP:
if(t->ref)
{
if (match(t->ref->name, "SAFEARRAY"))
return VT_SAFEARRAY;
return VT_PTR;
}
error("get_type_vt: unknown-deref-type: %d\n", t->ref->type);
break;
@ -166,29 +205,14 @@ unsigned short get_type_vt(type_t *t)
case RPC_FC_BOGUS_STRUCT:
return VT_USERDEFINED;
case 0:
if(t->attrs)
return VT_USERDEFINED;
return 0;
return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED;
default:
error("get_type_vt: unknown type: 0x%02x\n", t->type);
}
return 0;
}
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)
void start_typelib(char *name, attr_list_t *attrs)
{
in_typelib++;
if (!do_typelib) return;
@ -197,6 +221,8 @@ void start_typelib(char *name, attr_t *attrs)
typelib->name = xstrdup(name);
typelib->filename = xstrdup(typelib_name);
typelib->attrs = attrs;
list_init( &typelib->entries );
list_init( &typelib->importlibs );
}
void end_typelib(void)
@ -208,90 +234,18 @@ void end_typelib(void)
return;
}
void add_interface(type_t *iface)
void add_typelib_entry(type_t *t)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add interface: %s\n", iface->name);
chat("add kind %i: %s\n", t->kind, t->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_INTERFACE;
entry->u.interface = iface;
LINK(entry, typelib->entry);
typelib->entry = entry;
entry->type = t;
list_add_tail( &typelib->entries, &entry->entry );
}
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)
static void tlb_read(int fd, void *buf, int count)
{
if(read(fd, buf, count) < count)
error("error while reading importlib.\n");
@ -350,6 +304,7 @@ static void read_msft_importlib(importlib_t *importlib, int fd)
importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_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_read(fd, &nameintro, sizeof(nameintro));
@ -400,18 +355,16 @@ void add_importlib(const char *name)
if(!typelib) return;
for(importlib = typelib->importlibs; importlib; importlib = NEXT_LINK(importlib)) {
LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry )
if(!strcmp(name, importlib->name))
return;
}
chat("add_importlib: %s\n", name);
importlib = xmalloc(sizeof(*importlib));
memset( importlib, 0, sizeof(*importlib) );
importlib->name = xstrdup(name);
read_importlib(importlib);
LINK(importlib, typelib->importlibs);
typelib->importlibs = importlib;
list_add_head( &typelib->importlibs, &importlib->entry );
}

View file

@ -22,14 +22,9 @@
#define __WIDL_TYPELIB_H
extern int in_typelib;
extern void start_typelib(char *name, attr_t *attrs);
extern void start_typelib(char *name, attr_list_t *attrs);
extern void end_typelib(void);
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_typelib_entry(type_t *t);
extern void add_importlib(const char *name);
/* Copied from wtypes.h. Not included directly because that would create a
@ -87,7 +82,6 @@ enum VARENUM {
VT_TYPEMASK = 0xfff
};
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);
#endif

View file

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

View file

@ -34,10 +34,9 @@
#include "utils.h"
#include "parser.h"
/* #define WANT_NEAR_INDICATION */
static const int want_near_indication = 0;
#ifdef WANT_NEAR_INDICATION
void make_print(char *str)
static void make_print(char *str)
{
while(*str)
{
@ -46,13 +45,13 @@ void make_print(char *str)
str++;
}
}
#endif
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);
vfprintf(stderr, s, ap);
#ifdef WANT_NEAR_INDICATION
if (want_near_indication)
{
char *cpy;
if(n)
@ -63,26 +62,26 @@ static void generic_msg(const char *s, const char *t, const char *n, va_list ap)
free(cpy);
}
}
#endif
fprintf(stderr, "\n");
}
int yyerror(const char *s, ...)
int parser_error(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Error", yytext, ap);
generic_msg(s, "Error", parser_text, ap);
va_end(ap);
exit(1);
return 1;
}
int yywarning(const char *s, ...)
int parser_warning(const char *s, ...)
{
va_list ap;
va_start(ap, s);
generic_msg(s, "Warning", yytext, ap);
generic_msg(s, "Warning", parser_text, ap);
va_end(ap);
return 0;
}
@ -145,7 +144,7 @@ char *dup_basename(const char *name, const char *ext)
namelen = strlen(name);
/* +4 for later extension and +1 for '\0' */
base = (char *)xmalloc(namelen +4 +1);
base = xmalloc(namelen +4 +1);
strcpy(base, name);
if(!strcasecmp(name + namelen-extlen, ext))
{
@ -164,12 +163,7 @@ void *xmalloc(size_t size)
{
error("Virtual memory exhausted.\n");
}
/*
* 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);
memset(res, 0x55, size);
return res;
}
@ -192,6 +186,6 @@ char *xstrdup(const char *str)
char *s;
assert(str != NULL);
s = (char *)xmalloc(strlen(str)+1);
s = xmalloc(strlen(str)+1);
return strcpy(s, str);
}

View file

@ -33,8 +33,8 @@ char *xstrdup(const char *str);
#define __attribute__(X)
#endif
int yyerror(const char *s, ...) __attribute__((format (printf, 1, 2)));
int yywarning(const char *s, ...) __attribute__((format (printf, 1, 2)));
int parser_error(const char *s, ...) __attribute__((format (printf, 1, 2)));
int parser_warning(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 error(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));

View file

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

View file

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

View file

@ -34,6 +34,13 @@ Generate a type library.
Define the name of the type library to be generated.
The default filename is infile.tlb.
.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:
.IP "\fB-c\fR"
Generate client stub.

View file

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

View file

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