From 0f8b64a57b0117cf2bb4c2e4c81f5a66f511ce75 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 31 May 2011 13:30:04 +0200 Subject: [PATCH] widl: Add a more generic way of determining the type of handle for a function. --- tools/widl/client.c | 73 +++++++++++++++++++-------------------------- tools/widl/header.c | 70 ++++++++++++++++++++----------------------- tools/widl/header.h | 5 ++-- tools/widl/parser.y | 35 ++++++++-------------- tools/widl/server.c | 10 +++---- 5 files changed, 82 insertions(+), 111 deletions(-) diff --git a/tools/widl/client.c b/tools/widl/client.c index cf14c9c9781..a32661b8a9b 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -83,33 +83,22 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) { + unsigned char explicit_fc, implicit_fc; const var_t *func = stmt->u.var; - 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); const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV); const var_list_t *args = type_get_function_args(func->type); - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); - if (!explicit_handle_var) - { - explicit_generic_handle_var = get_explicit_generic_handle_var(func); - if (!explicit_generic_handle_var) - context_handle_var = get_context_handle_var(func); - } + const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ); print_client( "struct __frame_%s%s\n{\n", prefix_client, get_name(func) ); indent++; print_client( "__DECL_EXCEPTION_FRAME\n" ); print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); - if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var) + if (handle_var) { - if (!implicit_handle && explicit_generic_handle_var) + if (explicit_fc == RPC_FC_BIND_GENERIC) print_client("%s %s;\n", - get_explicit_generic_handle_type(explicit_generic_handle_var)->name, - explicit_generic_handle_var->name ); + get_explicit_generic_handle_type(handle_var)->name, handle_var->name ); print_client("RPC_BINDING_HANDLE _Handle;\n"); } @@ -130,14 +119,13 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) print_client("NdrFreeBuffer(&__frame->_StubMsg);\n"); - if (!implicit_handle && explicit_generic_handle_var) + if (explicit_fc == RPC_FC_BIND_GENERIC) { fprintf(client, "\n"); print_client("if (__frame->_Handle)\n"); indent++; print_client("%s_unbind(__frame->%s, __frame->_Handle);\n", - get_explicit_generic_handle_type(explicit_generic_handle_var)->name, - explicit_generic_handle_var->name); + get_explicit_generic_handle_type(handle_var)->name, handle_var->name); indent--; } indent--; @@ -170,12 +158,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) } print_client("RPC_MESSAGE _RpcMessage;\n"); - if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var) + if (handle_var) { print_client( "__frame->_Handle = 0;\n" ); - if (!implicit_handle && explicit_generic_handle_var) - print_client("__frame->%s = %s;\n", - explicit_generic_handle_var->name, explicit_generic_handle_var->name ); + if (explicit_fc == RPC_FC_BIND_GENERIC) + print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name ); } if (!is_void(type_function_get_rettype(func->type)) && decl_indirect(type_function_get_rettype(func->type))) @@ -210,31 +197,29 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) fprintf(client, ");\n\n"); } - if (explicit_handle_var) + switch (explicit_fc) { - print_client("__frame->_Handle = %s;\n", explicit_handle_var->name); + case RPC_FC_BIND_PRIMITIVE: + print_client("__frame->_Handle = %s;\n", handle_var->name); fprintf(client, "\n"); - } - else if (explicit_generic_handle_var) - { + break; + case RPC_FC_BIND_GENERIC: print_client("__frame->_Handle = %s_bind(%s);\n", - get_explicit_generic_handle_type(explicit_generic_handle_var)->name, - explicit_generic_handle_var->name); + get_explicit_generic_handle_type(handle_var)->name, handle_var->name); fprintf(client, "\n"); - } - else if (context_handle_var) + break; + case RPC_FC_BIND_CONTEXT: { /* if the context_handle attribute appears in the chain of types * without pointers being followed, then the context handle must * be direct, otherwise it is a pointer */ - int is_ch_ptr = is_aliaschain_attr(context_handle_var->type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE; - print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", context_handle_var->name); + int is_ch_ptr = !is_aliaschain_attr(handle_var->type, ATTR_CONTEXTHANDLE); + print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", handle_var->name); indent++; print_client("__frame->_Handle = NDRCContextBinding(%s%s);\n", - is_ch_ptr ? "*" : "", context_handle_var->name); + is_ch_ptr ? "*" : "", handle_var->name); indent--; - if (is_attr(context_handle_var->attrs, ATTR_IN) && - !is_attr(context_handle_var->attrs, ATTR_OUT)) + if (is_attr(handle_var->attrs, ATTR_IN) && !is_attr(handle_var->attrs, ATTR_OUT)) { print_client("else\n"); indent++; @@ -242,17 +227,21 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) indent--; } fprintf(client, "\n"); + break; } - else if (implicit_handle) - { - print_client("__frame->_Handle = %s;\n", implicit_handle->name); - fprintf(client, "\n"); + case 0: /* implicit handle */ + if (handle_var) + { + print_client("__frame->_Handle = %s;\n", handle_var->name); + fprintf(client, "\n"); + } + break; } write_remoting_arguments(client, indent, func, "", PASS_IN, PHASE_BUFFERSIZE); print_client("NdrGetBuffer(&__frame->_StubMsg, __frame->_StubMsg.BufferLength, "); - if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var) + if (handle_var) fprintf(client, "__frame->_Handle);\n\n"); else fprintf(client,"%s__MIDL_AutoBindHandle);\n\n", iface->name); diff --git a/tools/widl/header.c b/tools/widl/header.c index 0ba90222ee9..574f723e35b 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -615,23 +615,6 @@ static void write_library(FILE *header, const typelib_t *typelib) } -const var_t* get_explicit_handle_var(const var_t *func) -{ - const var_t* var; - - if (!type_get_function_args(func->type)) - return NULL; - - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - { - const type_t *type = var->type; - if (type_get_type(type) == TYPE_BASIC && type_basic_get_type(type) == TYPE_BASIC_HANDLE) - return var; - } - - return NULL; -} - const type_t* get_explicit_generic_handle_type(const var_t* var) { const type_t *t; @@ -644,31 +627,44 @@ const type_t* get_explicit_generic_handle_type(const var_t* var) return NULL; } -const var_t* get_explicit_generic_handle_var(const var_t *func) +const var_t *get_func_handle_var( const type_t *iface, const var_t *func, + unsigned char *explicit_fc, unsigned char *implicit_fc ) { - const var_t* var; + const var_t *var; + const var_list_t *args = type_get_function_args( func->type ); - if (!type_get_function_args(func->type)) - return NULL; - - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - if (get_explicit_generic_handle_type(var)) + *explicit_fc = *implicit_fc = 0; + if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) + { + if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue; + if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE) + { + *explicit_fc = RPC_FC_BIND_PRIMITIVE; return var; - - return NULL; -} - -const var_t* get_context_handle_var(const var_t *func) -{ - const var_t* var; - - if (!type_get_function_args(func->type)) - return NULL; - - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - if (is_attr(var->attrs, ATTR_IN) && is_context_handle(var->type)) + } + if (get_explicit_generic_handle_type( var )) + { + *explicit_fc = RPC_FC_BIND_GENERIC; return var; + } + if (is_context_handle( var->type )) + { + *explicit_fc = RPC_FC_BIND_CONTEXT; + return var; + } + } + if ((var = get_attrp( iface->attrs, ATTR_IMPLICIT_HANDLE ))) + { + if (type_get_type( var->type ) == TYPE_BASIC && + type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE) + *implicit_fc = RPC_FC_BIND_PRIMITIVE; + else + *implicit_fc = RPC_FC_BIND_GENERIC; + return var; + } + + *implicit_fc = RPC_FC_AUTO_HANDLE; return NULL; } diff --git a/tools/widl/header.h b/tools/widl/header.h index 6a37192f395..c844850ee26 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -47,10 +47,9 @@ extern int need_proxy_file(const statement_list_t *stmts); 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 const var_t* get_explicit_handle_var(const var_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 var_t *func); -extern const var_t* get_context_handle_var(const var_t *func); +extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func, + unsigned char *explicit_fc, unsigned char *implicit_fc ); extern int has_out_arg_or_return(const var_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 56d5a8bff58..24107fc6e59 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -133,7 +133,7 @@ static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs); const char *get_attr_display_name(enum attr_type type); -static void add_explicit_handle_if_necessary(var_t *func); +static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func); static void check_def(const type_t *t); static statement_t *make_statement(enum statement_type type); @@ -2598,31 +2598,20 @@ static void check_remoting_args(const var_t *func) } } -static void add_explicit_handle_if_necessary(var_t *func) +static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func) { - const var_t* explicit_handle_var; - const var_t* explicit_generic_handle_var = NULL; - const var_t* context_handle_var = NULL; + unsigned char explicit_fc, implicit_fc; /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); - if (!explicit_handle_var) + if (!get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ) || !explicit_fc) { - explicit_generic_handle_var = get_explicit_generic_handle_var(func); - if (!explicit_generic_handle_var) - { - context_handle_var = get_context_handle_var(func); - if (!context_handle_var) - { - /* no explicit handle specified so add - * "[in] handle_t IDL_handle" as the first parameter to the - * function */ - var_t *idl_handle = make_var(xstrdup("IDL_handle")); - idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN)); - idl_handle->type = find_type_or_error("handle_t", 0); - type_function_add_head_arg(func->type, idl_handle); - } - } + /* no explicit handle specified so add + * "[in] handle_t IDL_handle" as the first parameter to the + * function */ + var_t *idl_handle = make_var(xstrdup("IDL_handle")); + idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN)); + idl_handle->type = find_type_or_error("handle_t", 0); + type_function_add_head_arg(func->type, idl_handle); } } @@ -2634,7 +2623,7 @@ static void check_functions(const type_t *iface, int is_inside_library) STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) { var_t *func = stmt->u.var; - add_explicit_handle_if_necessary(func); + add_explicit_handle_if_necessary(iface, func); } } if (!is_inside_library && !is_attr(iface->attrs, ATTR_LOCAL)) diff --git a/tools/widl/server.c b/tools/widl/server.c index d02ffed66c9..8e437cd9e26 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -53,15 +53,13 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) { const statement_t *stmt; const var_t *var; - const var_t* explicit_handle_var; STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) { + unsigned char explicit_fc, implicit_fc; var_t *func = stmt->u.var; int has_full_pointer = is_full_pointer_function(func); - - /* check for a defined binding handle */ - explicit_handle_var = get_explicit_handle_var(func); + const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ); print_server("struct __frame_%s_%s\n{\n", iface->name, get_name(func)); indent++; @@ -109,9 +107,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset) write_parameters_init(server, indent, func, "__frame->"); - if (explicit_handle_var) + if (explicit_fc == RPC_FC_BIND_PRIMITIVE) { - print_server("__frame->%s = _pRpcMessage->Handle;\n", explicit_handle_var->name); + print_server("__frame->%s = _pRpcMessage->Handle;\n", handle_var->name); fprintf(server, "\n"); }