Commit d458a599 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Add support for non-basetype return types.

parent a95420a0
......@@ -497,6 +497,12 @@ s_sum_L1_norms(int n, vector_t *vs)
return sum;
}
str_t
s_get_filename(void)
{
return (char *)__FILE__;
}
void
s_stop(void)
{
......@@ -558,6 +564,7 @@ basic_tests(void)
int x;
str_struct_t ss = {string};
wstr_struct_t ws = {wstring};
str_t str;
ok(int_return() == INT_CODE, "RPC int_return\n");
......@@ -652,6 +659,9 @@ basic_tests(void)
ok(sum_bogus(&bogus) == 12, "RPC sum_bogus\n");
check_null(NULL);
str = get_filename();
ok(!strcmp(str, __FILE__), "get_filename() returned %s instead of %s\n", str, __FILE__);
}
static void
......
......@@ -300,5 +300,7 @@ cpp_quote("#endif")
int sum_pcarr2(int n, [size_is(, n)] int **pa);
int sum_L1_norms(int n, [size_is(n)] vector_t *vs);
str_t get_filename(void);
void stop(void);
}
......@@ -139,6 +139,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("RPC_MESSAGE _RpcMessage;\n");
print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
if (!is_void(def->type) && decl_indirect(def->type))
{
print_client("void *_p_%s = &%s;\n",
"_RetVal", "_RetVal");
}
fprintf(client, "\n");
/* check pointers */
......@@ -216,7 +221,13 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* unmarshal return value */
if (!is_void(def->type))
print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
{
if (decl_indirect(def->type))
print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal");
else if (is_ptr(def->type) || is_array(def->type))
print_client("%s = 0;\n", "_RetVal");
write_remoting_arguments(client, indent, func, PASS_RETURN, PHASE_UNMARSHAL);
}
/* update proc_offset */
if (func->args)
......
......@@ -272,6 +272,11 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
}
print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" );
if (has_ret) {
if (decl_indirect(def->type))
print_proxy("void *_p_%s = &%s;\n",
"_RetVal", "_RetVal");
}
print_proxy( "\n");
/* FIXME: trace */
......@@ -307,7 +312,13 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_UNMARSHAL);
if (has_ret)
print_phase_basetype(proxy, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
{
if (decl_indirect(def->type))
print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal");
else if (is_ptr(def->type) || is_array(def->type))
print_proxy("%s = 0;\n", "_RetVal");
write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_UNMARSHAL);
}
indent--;
print_proxy( "}\n");
......
......@@ -209,6 +209,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE);
if (!is_void(def->type))
write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_BUFFERSIZE);
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
fprintf(server, "\n");
print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n");
......@@ -226,7 +229,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
/* marshall the return value */
if (!is_void(def->type))
print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal");
write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_MARSHAL);
indent--;
print_server("}\n");
......@@ -236,6 +239,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_FREE);
if (!is_void(def->type))
write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_FREE);
indent--;
print_server("}\n");
print_server("RpcEndFinally\n");
......
......@@ -325,22 +325,27 @@ void print(FILE *file, int indent, const char *format, va_list va)
}
}
static void write_var_init(FILE *file, int indent, const type_t *t, const char *n)
{
if (decl_indirect(t))
print_file(file, indent, "MIDL_memset(&%s, 0, sizeof(%s));\n", n, n);
else if (is_ptr(t) || is_array(t))
print_file(file, indent, "%s = 0;\n", n);
}
void write_parameters_init(FILE *file, int indent, const func_t *func)
{
const var_t *var;
if (!is_void(func->def->type))
write_var_init(file, indent, func->def->type, "_RetVal");
if (!func->args)
return;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
{
const type_t *t = var->type;
const char *n = var->name;
if (decl_indirect(t))
print_file(file, indent, "MIDL_memset(&%s, 0, sizeof %s);\n", n, n);
else if (is_ptr(t) || is_array(t))
print_file(file, indent, "%s = 0;\n", n);
}
write_var_init(file, indent, var->type, var->name);
fprintf(file, "\n");
}
......@@ -2621,23 +2626,11 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
return x;
}
void write_remoting_arguments(FILE *file, int indent, const func_t *func,
enum pass pass, enum remoting_phase phase)
static void write_remoting_arg(FILE *file, int indent, const func_t *func,
enum pass pass, enum remoting_phase phase,
const var_t *var)
{
int in_attr, out_attr, pointer_type;
const var_t *var;
if (!func->args)
return;
if (phase == PHASE_BUFFERSIZE)
{
unsigned int size = get_function_buffer_size( func, pass );
print_file(file, indent, "_StubMsg.BufferLength = %u;\n", size);
}
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
{
const type_t *type = var->type;
unsigned char rtype;
size_t start_offset = type->typestring_offset;
......@@ -2654,16 +2647,16 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
if (phase == PHASE_FREE)
{
if (!needs_freeing(var->attrs, type, out_attr))
continue;
return;
}
else
switch (pass)
{
case PASS_IN:
if (!in_attr) continue;
if (!in_attr) return;
break;
case PASS_OUT:
if (!out_attr) continue;
if (!out_attr) return;
break;
case PASS_RETURN:
break;
......@@ -2882,6 +2875,32 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
}
}
fprintf(file, "\n");
}
void write_remoting_arguments(FILE *file, int indent, const func_t *func,
enum pass pass, enum remoting_phase phase)
{
if (phase == PHASE_BUFFERSIZE && pass != PASS_RETURN)
{
unsigned int size = get_function_buffer_size( func, pass );
print_file(file, indent, "_StubMsg.BufferLength = %u;\n", size);
}
if (pass == PASS_RETURN)
{
var_t var;
var = *func->def;
var.name = xstrdup( "_RetVal" );
write_remoting_arg( file, indent, func, pass, phase, &var );
free( var.name );
}
else
{
const var_t *var;
if (!func->args)
return;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
write_remoting_arg( file, indent, func, pass, phase, var );
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment