mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
Update WIDL to rev 20070519.
svn path=/trunk/; revision=26843
This commit is contained in:
parent
5cb63e5d4a
commit
486714fd5a
|
@ -1,5 +1,10 @@
|
|||
ChangeLog
|
||||
|
||||
2007-05-20 ekohl
|
||||
|
||||
- Synchronized with WINE widl 20070519.
|
||||
|
||||
|
||||
2007-05-17 ekohl
|
||||
|
||||
tools/widl/lex.yy.c
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue