Module: wine Branch: master Commit: 59556de0c1b7acb5f62a695b7256debb54c5de8c URL: http://source.winehq.org/git/wine.git/?a=commit;h=59556de0c1b7acb5f62a695b72...
Author: Rob Shearman rob@codeweavers.com Date: Thu Mar 27 14:03:17 2008 +0000
widl: Add support for generic binding handles.
---
tools/widl/client.c | 32 +++++++++++++++++++++--- tools/widl/header.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++- tools/widl/header.h | 3 ++ tools/widl/parser.y | 2 +- tools/widl/widl.c | 1 + tools/widl/widltypes.h | 2 +- 6 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/tools/widl/client.c b/tools/widl/client.c index eb65d83..47fb25d 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -99,16 +99,21 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) { const var_t *def = func->def; const var_t* explicit_handle_var; + const var_t* explicit_generic_handle_var = NULL; const var_t* context_handle_var = NULL; int has_full_pointer = is_full_pointer_function(func);
/* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(func); if (!explicit_handle_var) - context_handle_var = get_context_handle_var(func); + { + explicit_generic_handle_var = get_explicit_generic_handle_var(func); + if (!explicit_generic_handle_var) + context_handle_var = get_context_handle_var(func); + } if (explicit_handle) { - if (!explicit_handle_var || !context_handle_var) + if (!explicit_handle_var || !explicit_generic_handle_var || !context_handle_var) { error("%s() does not define an explicit binding handle!\n", def->name); return; @@ -148,7 +153,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) fprintf(client, " _RetVal;\n"); }
- if (implicit_handle || explicit_handle_var || context_handle_var) + if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var) print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
print_client("RPC_MESSAGE _RpcMessage;\n"); @@ -189,12 +194,20 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) print_client("_Handle = %s;\n", explicit_handle_var->name); fprintf(client, "\n"); } + else if (explicit_generic_handle_var) + { + print_client("_Handle = %s_bind(%s);\n", + get_explicit_generic_handle_type(explicit_generic_handle_var)->name, + explicit_generic_handle_var->name); + fprintf(client, "\n"); + } else if (context_handle_var) { print_client("if (%s%s != 0)\n", is_ptr(context_handle_var->type) ? "*" : "", context_handle_var->name); indent++; print_client("_Handle = NDRCContextBinding(%s%s);\n", is_ptr(context_handle_var->type) ? "*" : "", context_handle_var->name); indent--; + fprintf(client, "\n"); }
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); @@ -203,7 +216,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) indent++; print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); print_client("_StubMsg.BufferLength,\n"); - if (implicit_handle || explicit_handle_var || context_handle_var) + if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var) print_client("_Handle);\n"); else print_client("%s__MIDL_AutoBindHandle);\n", iface->name); @@ -278,6 +291,17 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
+ if (!implicit_handle && explicit_generic_handle_var) + { + fprintf(client, "\n"); + print_client("if (_Handle)\n"); + indent++; + print_client("%s_unbind(%s, _Handle);\n", + get_explicit_generic_handle_type(explicit_generic_handle_var)->name, + explicit_generic_handle_var->name); + indent--; + } + indent--; print_client("}\n"); print_client("RpcEndFinally\n"); diff --git a/tools/widl/header.c b/tools/widl/header.c index 5ffa549..f1e5a03 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -34,9 +34,12 @@ #include "parser.h" #include "header.h"
+typedef struct _user_type_t generic_handle_t; + static int indentation = 0; user_type_list_t user_type_list = LIST_INIT(user_type_list); static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); +static struct list generic_handle_list = LIST_INIT(generic_handle_list);
static void indent(FILE *h, int delta) { @@ -343,7 +346,18 @@ static int context_handle_registered(const char *name) return 0; }
-void check_for_user_types_and_context_handles(const var_list_t *list) +static int generic_handle_registered(const char *name) +{ + generic_handle_t *gh; + LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry) + if (!strcmp(name, gh->name)) + return 1; + return 0; +} + +/* check for types which require additional prototypes to be generated in the + * header */ +void check_for_additional_prototype_types(const var_list_t *list) { const var_t *v;
@@ -365,6 +379,16 @@ void check_for_user_types_and_context_handles(const var_list_t *list) /* don't carry on parsing fields within this type */ break; } + if (type->type != RPC_FC_BIND_PRIMITIVE && is_attr(type->attrs, ATTR_HANDLE)) { + if (!generic_handle_registered(name)) + { + generic_handle_t *gh = xmalloc(sizeof(*gh)); + gh->name = xstrdup(name); + list_add_tail(&generic_handle_list, &gh->entry); + } + /* don't carry on parsing fields within this type */ + break; + } if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { if (!user_type_registered(name)) { @@ -378,7 +402,7 @@ void check_for_user_types_and_context_handles(const var_list_t *list) } else { - check_for_user_types_and_context_handles(type->fields); + check_for_additional_prototype_types(type->fields); } } } @@ -407,6 +431,17 @@ void write_context_handle_rundowns(void) } }
+void write_generic_handle_routines(void) +{ + generic_handle_t *gh; + LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry) + { + const char *name = gh->name; + fprintf(header, "handle_t __RPC_USER %s_bind(%s);\n", name, name); + fprintf(header, "void __RPC_USER %s_unbind(%s, handle_t);\n", name, name); + } +} + void write_typedef(type_t *type) { fprintf(header, "typedef "); @@ -537,6 +572,29 @@ const var_t* get_explicit_handle_var(const func_t* func) return NULL; }
+const type_t* get_explicit_generic_handle_type(const var_t* var) +{ + const type_t *t; + for (t = var->type; is_ptr(t); t = t->ref) + if (t->type != RPC_FC_BIND_PRIMITIVE && is_attr(t->attrs, ATTR_HANDLE)) + return t; + return NULL; +} + +const var_t* get_explicit_generic_handle_var(const func_t* func) +{ + const var_t* var; + + if (!func->args) + return NULL; + + LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) + if (get_explicit_generic_handle_type(var)) + return var; + + return NULL; +} + int has_out_arg_or_return(const func_t *func) { const var_t *var; diff --git a/tools/widl/header.h b/tools/widl/header.h index 173bd03..3f4fee2 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -62,7 +62,10 @@ extern void write_externdef(const var_t *v); extern void write_library(const char *name, const attr_list_t *attr); extern void write_user_types(void); extern void write_context_handle_rundowns(void); +extern void write_generic_handle_routines(void); extern const var_t* get_explicit_handle_var(const func_t* func); +extern const type_t* get_explicit_generic_handle_type(const var_t* var); +extern const var_t* get_explicit_generic_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); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 3a89723..a4f383f 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2072,7 +2072,7 @@ static void check_all_user_types(ifref_list_t *ifrefs) { const func_list_t *fs = ifref->iface->funcs; if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) - check_for_user_types_and_context_handles(f->args); + check_for_additional_prototype_types(f->args); } }
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index bb3f651..13daf7e 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -601,6 +601,7 @@ int main(int argc,char *argv[]) fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "\n"); write_user_types(); + write_generic_handle_routines(); write_context_handle_rundowns(); fprintf(header, "\n"); fprintf(header, "/* End additional prototypes */\n"); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index acdc3f1..7eaacd1 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -312,7 +312,7 @@ struct _user_type_t { extern unsigned char pointer_default;
extern user_type_list_t user_type_list; -void check_for_user_types_and_context_handles(const var_list_t *list); +void check_for_additional_prototype_types(const var_list_t *list);
void init_types(void); type_t *alloc_type(void);