widl: Add support for generating old-style interpreted stubs for clients.

This commit is contained in:
Alexandre Julliard 2011-06-03 12:27:14 +02:00
parent 33ba9731a3
commit 9c4d01f329

View file

@ -72,23 +72,58 @@ static void check_pointers(const var_t *func)
}
}
static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
static void write_client_func_decl( const type_t *iface, const var_t *func )
{
const statement_t *stmt;
const var_t *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int method_count = 0;
if (!implicit_handle)
print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
{
unsigned char explicit_fc, implicit_fc;
const var_t *func = stmt->u.var;
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);
type_t *rettype = type_function_get_rettype(func->type);
write_type_decl_left(client, rettype);
if (needs_space_after(rettype)) fprintf(client, " ");
if (callconv) fprintf(client, "%s ", callconv);
fprintf(client, "%s%s(\n", prefix_client, get_name(func));
indent++;
if (args)
write_args(client, args, iface->name, 0, TRUE);
else
print_client("void");
fprintf(client, ")\n");
indent--;
}
static void write_function_stub( const type_t *iface, const var_t *func,
int method_count, unsigned int proc_offset )
{
unsigned char explicit_fc, implicit_fc;
int has_full_pointer = is_full_pointer_function(func);
type_t *rettype = type_function_get_rettype(func->type);
const var_list_t *args = type_get_function_args(func->type);
const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
int has_ret = !is_void(rettype);
if (is_interpreted_func( iface, func ))
{
write_client_func_decl( iface, func );
fprintf(client, "{\n");
indent++;
if (has_ret) print_client( "%s", "CLIENT_CALL_RETURN _RetVal;\n\n" );
print_client( "%sNdrClientCall( &%s_StubDesc, &__MIDL_ProcFormatString.Format[%u], ",
has_ret ? "_RetVal = " : "", iface->name, proc_offset );
if (args)
fprintf( client, "(unsigned char *)&%s );\n",
LIST_ENTRY( list_head(args), const var_t, entry )->name );
else
fprintf( client, "(unsigned char *)0 );\n" );
if (has_ret)
{
print_client( "return (" );
write_type_decl_left(client, rettype);
fprintf( client, ")*(LONG_PTR *)&_RetVal;\n" );
}
indent--;
print_client( "}\n\n");
return;
}
print_client( "struct __frame_%s%s\n{\n", prefix_client, get_name(func) );
indent++;
@ -102,8 +137,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("RPC_BINDING_HANDLE _Handle;\n");
}
if (!is_void(type_function_get_rettype(func->type)) &&
decl_indirect(type_function_get_rettype(func->type)))
if (has_ret && decl_indirect(rettype))
{
print_client("void *_p_%s;\n", "_RetVal" );
}
@ -131,18 +165,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent--;
print_client( "}\n\n" );
write_type_decl_left(client, type_function_get_rettype(func->type));
if (needs_space_after(type_function_get_rettype(func->type)))
fprintf(client, " ");
if (callconv) fprintf(client, "%s ", callconv);
fprintf(client, "%s%s(\n", prefix_client, get_name(func));
indent++;
if (args)
write_args(client, args, iface->name, 0, TRUE);
else
print_client("void");
fprintf(client, ")\n");
indent--;
write_client_func_decl( iface, func );
/* write the functions body */
fprintf(client, "{\n");
@ -150,10 +173,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client( "struct __frame_%s%s __f, * const __frame = &__f;\n", prefix_client, get_name(func) );
/* declare return value '_RetVal' */
if (!is_void(type_function_get_rettype(func->type)))
if (has_ret)
{
print_client("%s", "");
write_type_decl_left(client, type_function_get_rettype(func->type));
write_type_decl_left(client, rettype);
fprintf(client, " _RetVal;\n");
}
print_client("RPC_MESSAGE _RpcMessage;\n");
@ -164,8 +187,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
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)))
if (has_ret && decl_indirect(rettype))
{
print_client("__frame->_p_%s = &%s;\n",
"_RetVal", "_RetVal");
@ -265,7 +287,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
indent++;
print_client("NdrConvert(&__frame->_StubMsg, (PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n",
*proc_offset);
proc_offset);
indent--;
}
@ -274,19 +296,15 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
write_remoting_arguments(client, indent, func, "", PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */
if (!is_void(type_function_get_rettype(func->type)))
if (has_ret)
{
if (decl_indirect(type_function_get_rettype(func->type)))
if (decl_indirect(rettype))
print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal");
else if (is_ptr(type_function_get_rettype(func->type)) ||
is_array(type_function_get_rettype(func->type)))
else if (is_ptr(rettype) || is_array(rettype))
print_client("%s = 0;\n", "_RetVal");
write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
}
/* update proc_offset */
*proc_offset += get_size_procformatstring_func( iface, func );
indent--;
print_client("}\n");
print_client("RpcFinally\n");
@ -299,7 +317,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* emit return code */
if (!is_void(type_function_get_rettype(func->type)))
if (has_ret)
{
fprintf(client, "\n");
print_client("return _RetVal;\n");
@ -308,8 +326,22 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent--;
fprintf(client, "}\n");
fprintf(client, "\n");
}
method_count++;
static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{
const statement_t *stmt;
const var_t *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int method_count = 0;
if (!implicit_handle)
print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
{
const var_t *func = stmt->u.var;
write_function_stub( iface, func, method_count++, *proc_offset );
*proc_offset += get_size_procformatstring_func( iface, func );
}
}
@ -510,8 +542,11 @@ static void write_client_routines(const statement_list_t *stmts)
unsigned int proc_offset = 0;
int expr_eval_routines;
if (need_inline_stubs_file( stmts ))
{
write_exceptions( client );
print_client( "\n");
}
write_formatstringsdecl(client, indent, stmts, need_stub);
expr_eval_routines = write_expr_eval_routines(client, client_token);