widl: Handle wire_marshal types.

This commit is contained in:
Dan Hipschman 2007-06-13 16:13:04 -07:00 committed by Alexandre Julliard
parent c2bf60b004
commit c0982b42c5
10 changed files with 246 additions and 63 deletions

View File

@ -225,6 +225,13 @@ s_sum_cps(cps_t *cps)
return sum; return sum;
} }
int
s_square_puint(puint_t p)
{
int n = atoi(p);
return n * n;
}
void void
s_stop(void) s_stop(void)
{ {
@ -388,12 +395,44 @@ free_list(test_list_t *list)
HeapFree(GetProcessHeap(), 0, list); HeapFree(GetProcessHeap(), 0, list);
} }
ULONG __RPC_USER
puint_t_UserSize(ULONG *flags, ULONG start, puint_t *p)
{
return start + sizeof(int);
}
unsigned char * __RPC_USER
puint_t_UserMarshal(ULONG *flags, unsigned char *buffer, puint_t *p)
{
int n = atoi(*p);
memcpy(buffer, &n, sizeof n);
return buffer + sizeof n;
}
unsigned char * __RPC_USER
puint_t_UserUnmarshal(ULONG *flags, unsigned char *buffer, puint_t *p)
{
int n;
memcpy(&n, buffer, sizeof n);
*p = HeapAlloc(GetProcessHeap(), 0, 10);
sprintf(*p, "%d", n);
return buffer + sizeof n;
}
void __RPC_USER
puint_t_UserFree(ULONG *flags, puint_t *p)
{
HeapFree(GetProcessHeap(), 0, *p);
}
static void static void
pointer_tests(void) pointer_tests(void)
{ {
static char p1[] = "11";
test_list_t *list = make_list(make_list(make_list(null_list()))); test_list_t *list = make_list(make_list(make_list(null_list())));
ok(test_list_length(list) == 3, "RPC test_list_length\n"); ok(test_list_length(list) == 3, "RPC test_list_length\n");
ok(square_puint(p1) == 121, "RPC square_puint\n");
free_list(list); free_list(list);
} }

View File

@ -130,5 +130,7 @@ interface IServer
int sum_cs(cs_t *cs); int sum_cs(cs_t *cs);
int sum_cps(cps_t *cps); int sum_cps(cps_t *cps);
typedef [wire_marshal(int)] void *puint_t;
int square_puint(puint_t p);
void stop(void); void stop(void);
} }

View File

@ -305,7 +305,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
print_client("0,\n"); print_client("0,\n");
print_client("0x50100a4, /* MIDL Version 5.1.164 */\n"); print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
print_client("0,\n"); print_client("0,\n");
print_client("0,\n"); print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
print_client("0, /* notify & notify_flag routine table */\n"); print_client("0, /* notify & notify_flag routine table */\n");
print_client("1, /* Flags */\n"); print_client("1, /* Flags */\n");
print_client("0, /* Reserved3 */\n"); print_client("0, /* Reserved3 */\n");
@ -434,6 +434,7 @@ void write_client(ifref_list_t *ifaces)
expr_eval_routines = write_expr_eval_routines(client, iface->iface->name); expr_eval_routines = write_expr_eval_routines(client, iface->iface->name);
if (expr_eval_routines) if (expr_eval_routines)
write_expr_eval_routine_list(client, iface->iface->name); write_expr_eval_routine_list(client, iface->iface->name);
write_user_quad_list(client);
write_stubdescriptor(iface->iface, expr_eval_routines); write_stubdescriptor(iface->iface, expr_eval_routines);
} }
} }

View File

@ -285,25 +285,18 @@ void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...)
write_type_right(h, t, is_field); write_type_right(h, t, is_field);
} }
user_type_list_t user_type_list = LIST_INIT(user_type_list);
struct user_type
{
struct user_type *next;
char name[1];
};
static struct user_type *user_type_list;
static int user_type_registered(const char *name) static int user_type_registered(const char *name)
{ {
struct user_type *ut; user_type_t *ut;
for (ut = user_type_list; ut; ut = ut->next) LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
if (!strcmp(name, ut->name)) if (!strcmp(name, ut->name))
return 1; return 1;
return 0; return 0;
} }
static void check_for_user_types(const var_list_t *list) void check_for_user_types(const var_list_t *list)
{ {
const var_t *v; const var_t *v;
@ -318,10 +311,9 @@ static void check_for_user_types(const var_list_t *list)
if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
if (!user_type_registered(name)) if (!user_type_registered(name))
{ {
struct user_type *ut = xmalloc(sizeof(struct user_type) + strlen(name)); user_type_t *ut = xmalloc(sizeof *ut);
strcpy(ut->name, name); ut->name = xstrdup(name);
ut->next = user_type_list; list_add_tail(&user_type_list, &ut->entry);
user_type_list = ut;
} }
/* don't carry on parsing fields within this type as we are already /* don't carry on parsing fields within this type as we are already
* using a wire marshaled type */ * using a wire marshaled type */
@ -337,8 +329,8 @@ static void check_for_user_types(const var_list_t *list)
void write_user_types(void) void write_user_types(void)
{ {
struct user_type *ut; user_type_t *ut;
for (ut = user_type_list; ut; ut = ut->next) LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
{ {
const char *name = ut->name; const char *name = ut->name;
fprintf(header, "ULONG __RPC_USER %s_UserSize (ULONG *, ULONG, %s *);\n", name, name); fprintf(header, "ULONG __RPC_USER %s_UserSize (ULONG *, ULONG, %s *);\n", name, name);
@ -668,7 +660,6 @@ static void write_method_proto(const type_t *iface)
fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n");
fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n");
fprintf(header, " DWORD* pdwStubPhase);\n"); fprintf(header, " DWORD* pdwStubPhase);\n");
check_for_user_types(cur->args);
} }
if (cas) { if (cas) {
const func_t *m; const func_t *m;

View File

@ -125,6 +125,7 @@ static int compute_method_indexes(type_t *iface);
static char *gen_name(void); static char *gen_name(void);
static void process_typedefs(var_list_t *names); static void process_typedefs(var_list_t *names);
static void check_arg(var_t *arg); static void check_arg(var_t *arg);
static void check_all_user_types(ifref_list_t *ifaces);
#define tsENUM 1 #define tsENUM 1
#define tsSTRUCT 2 #define tsSTRUCT 2
@ -275,6 +276,7 @@ static void check_arg(var_t *arg);
%% %%
input: gbl_statements { fix_incomplete(); input: gbl_statements { fix_incomplete();
check_all_user_types($1);
write_proxies($1); write_proxies($1);
write_client($1); write_client($1);
write_server($1); write_server($1);
@ -1932,3 +1934,16 @@ static void check_arg(var_t *arg)
if (t->type == 0 && ! is_var_ptr(arg)) if (t->type == 0 && ! is_var_ptr(arg))
yyerror("argument '%s' has void type", arg->name); yyerror("argument '%s' has void type", arg->name);
} }
static void check_all_user_types(ifref_list_t *ifrefs)
{
const ifref_t *ifref;
const func_t *f;
if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry)
{
const func_list_t *fs = ifref->iface->funcs;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
check_for_user_types(f->args);
}
}

View File

@ -85,7 +85,7 @@ static void write_stubdesc(void)
print_proxy( "0,\n"); print_proxy( "0,\n");
print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n"); print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n");
print_proxy( "0,\n"); print_proxy( "0,\n");
print_proxy( "0,\n"); print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
print_proxy( "0, /* notify & notify_flag routine table */\n"); print_proxy( "0, /* notify & notify_flag routine table */\n");
print_proxy( "1, /* Flags */\n"); print_proxy( "1, /* Flags */\n");
print_proxy( "0, /* Reserved3 */\n"); print_proxy( "0, /* Reserved3 */\n");
@ -373,9 +373,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
print_proxy("NdrStubInitialize(_pRpcMessage, &_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n"); print_proxy("NdrStubInitialize(_pRpcMessage, &_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n");
fprintf(proxy, "\n"); fprintf(proxy, "\n");
if (cur->args) write_parameters_init(cur);
LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry )
print_proxy("%s = 0;\n", arg->name);
print_proxy("RpcTryFinally\n"); print_proxy("RpcTryFinally\n");
print_proxy("{\n"); print_proxy("{\n");
@ -589,6 +587,7 @@ void write_proxies(ifref_list_t *ifaces)
if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs)) if (is_object(cur->iface->attrs) && !is_local(cur->iface->attrs))
write_proxy(cur->iface, &proc_offset); write_proxy(cur->iface, &proc_offset);
write_user_quad_list(proxy);
write_stubdesc(); write_stubdesc();
print_proxy( "#if !defined(__RPC_WIN32__)\n"); print_proxy( "#if !defined(__RPC_WIN32__)\n");

View File

@ -61,7 +61,7 @@ static int print_server(const char *format, ...)
} }
static void write_parameters_init(const func_t *func) void write_parameters_init(const func_t *func)
{ {
const var_t *var; const var_t *var;
@ -69,8 +69,14 @@ static void write_parameters_init(const func_t *func)
return; return;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) 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); const type_t *t = var->type;
const char *n = var->name;
if (decl_indirect(t))
print_server("MIDL_memset(&%s, 0, sizeof %s);\n", n, n);
else if (is_ptr(t) || is_array(t))
print_server("%s = 0;\n", n);
}
fprintf(server, "\n"); fprintf(server, "\n");
} }
@ -337,7 +343,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
print_server("0,\n"); print_server("0,\n");
print_server("0x50100a4, /* MIDL Version 5.1.164 */\n"); print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
print_server("0,\n"); print_server("0,\n");
print_server("0,\n"); print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
print_server("0, /* notify & notify_flag routine table */\n"); print_server("0, /* notify & notify_flag routine table */\n");
print_server("1, /* Flags */\n"); print_server("1, /* Flags */\n");
print_server("0, /* Reserved3 */\n"); print_server("0, /* Reserved3 */\n");
@ -454,6 +460,7 @@ void write_server(ifref_list_t *ifaces)
if (expr_eval_routines) if (expr_eval_routines)
write_expr_eval_routine_list(server, iface->iface->name); write_expr_eval_routine_list(server, iface->iface->name);
write_user_quad_list(server);
write_stubdescriptor(iface->iface, expr_eval_routines); write_stubdescriptor(iface->iface, expr_eval_routines);
write_dispatchtable(iface->iface); write_dispatchtable(iface->iface);
} }

View File

@ -137,6 +137,20 @@ int is_union(unsigned char type)
} }
} }
static unsigned short user_type_offset(const char *name)
{
user_type_t *ut;
unsigned short off = 0;
LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
{
if (strcmp(name, ut->name) == 0)
return off;
++off;
}
error("user_type_offset: couldn't find type (%s)\n", name);
return 0;
}
static void update_tfsoff(type_t *type, unsigned int offset, FILE *file) static void update_tfsoff(type_t *type, unsigned int offset, FILE *file)
{ {
type->typestring_offset = offset; type->typestring_offset = offset;
@ -154,10 +168,34 @@ static void guard_rec(type_t *type)
type->typestring_offset = 1; type->typestring_offset = 1;
} }
static type_t *get_user_type(const type_t *t, const char **pname)
{
for (;;)
{
type_t *ut = get_attrp(t->attrs, ATTR_WIREMARSHAL);
if (ut)
{
if (pname)
*pname = t->name;
return ut;
}
if (t->kind == TKIND_ALIAS)
t = t->orig;
else
return 0;
}
}
static int is_user_type(const type_t *t)
{
return get_user_type(t, NULL) != NULL;
}
static int is_embedded_complex(const type_t *type) static int is_embedded_complex(const type_t *type)
{ {
unsigned char tc = type->type; unsigned char tc = type->type;
return is_struct(tc) || is_union(tc) || is_array(type); return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type);
} }
static int compare_expr(const expr_t *a, const expr_t *b) static int compare_expr(const expr_t *a, const expr_t *b)
@ -257,20 +295,6 @@ void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, int for_
print_file(f, indent, "\n"); print_file(f, indent, "\n");
} }
static int is_user_derived(const var_t *v)
{
const type_t *type = v->type;
if (v->attrs && is_attr( v->attrs, ATTR_WIREMARSHAL )) return 1;
while (type)
{
if (type->attrs && is_attr( type->attrs, ATTR_WIREMARSHAL )) return 1;
type = type->ref;
}
return 0;
}
static inline int is_base_type(unsigned char type) static inline int is_base_type(unsigned char type)
{ {
switch (type) switch (type)
@ -299,6 +323,14 @@ static inline int is_base_type(unsigned char type)
} }
} }
int decl_indirect(const type_t *t)
{
return is_user_type(t)
|| (!is_base_type(t->type)
&& !is_ptr(t)
&& !is_array(t));
}
static size_t write_procformatstring_var(FILE *file, int indent, static size_t write_procformatstring_var(FILE *file, int indent,
const var_t *var, int is_return) const var_t *var, int is_return)
{ {
@ -794,6 +826,48 @@ static int processed(const type_t *type)
return type->typestring_offset && !type->tfswrite; return type->typestring_offset && !type->tfswrite;
} }
static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
{
unsigned int start, absoff;
unsigned int align = 0, ualign = 0;
const char *name;
type_t *utype = get_user_type(type, &name);
size_t usize = type_memsize(utype, &ualign);
size_t size = type_memsize(type, &align);
unsigned short funoff = user_type_offset(name);
short reloff;
guard_rec(type);
if (is_base_type(utype->type))
{
absoff = *tfsoff;
print_file(file, 0, "/* %d */\n", absoff);
print_file(file, 2, "0x%x,\t/* %s */\n", utype->type, string_of_type(utype->type));
print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
*tfsoff += 2;
}
else
{
if (!processed(utype))
write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
absoff = utype->typestring_offset;
}
start = *tfsoff;
update_tfsoff(type, start, file);
print_file(file, 0, "/* %d */\n", start);
print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", RPC_FC_USER_MARSHAL);
print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff);
print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", usize, usize);
print_file(file, 2, "NdrFcShort(0x%lx),\t/* %lu */\n", size, size);
*tfsoff += 8;
reloff = absoff - *tfsoff;
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n", reloff, reloff, absoff);
*tfsoff += 2;
}
static void write_member_type(FILE *file, type_t *type, const var_t *field, static void write_member_type(FILE *file, type_t *type, const var_t *field,
unsigned int *corroff, unsigned int *tfsoff) unsigned int *corroff, unsigned int *tfsoff)
{ {
@ -1396,6 +1470,12 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
int pointer_type; int pointer_type;
size_t offset; size_t offset;
if (is_user_type(type))
{
write_user_tfs(file, type, typeformat_offset);
return type->typestring_offset;
}
if (type == var->type) /* top-level pointers */ if (type == var->type) /* top-level pointers */
{ {
int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE); int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE);
@ -1482,8 +1562,13 @@ static void set_tfswrite(type_t *type, int val)
{ {
while (type->tfswrite != val) while (type->tfswrite != val)
{ {
type_t *utype = get_user_type(type, NULL);
type->tfswrite = val; type->tfswrite = val;
if (utype)
set_tfswrite(utype, val);
if (type->kind == TKIND_ALIAS) if (type->kind == TKIND_ALIAS)
type = type->orig; type = type->orig;
else if (is_ptr(type) || is_array(type)) else if (is_ptr(type) || is_array(type))
@ -1508,7 +1593,11 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
{ {
int retmask = 0; int retmask = 0;
if (is_ptr(type)) if (is_user_type(type))
{
write_user_tfs(file, type, tfsoff);
}
else if (is_ptr(type))
{ {
type_t *ref = type->ref; type_t *ref = type->ref;
@ -1795,7 +1884,7 @@ static unsigned int get_function_buffer_size( const func_t *func, enum pass pass
static void print_phase_function(FILE *file, int indent, const char *type, static void print_phase_function(FILE *file, int indent, const char *type,
enum remoting_phase phase, enum remoting_phase phase,
const char *varname, unsigned int type_offset) const var_t *var, unsigned int type_offset)
{ {
const char *function; const char *function;
switch (phase) switch (phase)
@ -1820,9 +1909,11 @@ static void print_phase_function(FILE *file, int indent, const char *type,
print_file(file, indent, "Ndr%s%s(\n", type, function); print_file(file, indent, "Ndr%s%s(\n", type, function);
indent++; indent++;
print_file(file, indent, "&_StubMsg,\n"); print_file(file, indent, "&_StubMsg,\n");
print_file(file, indent, "%s%s,\n", print_file(file, indent, "%s%s%s%s,\n",
(phase == PHASE_UNMARSHAL) ? "(unsigned char **)&" : "(unsigned char *)", (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)",
varname); (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "",
(phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "",
var->name);
print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n", print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");"); type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
if (phase == PHASE_UNMARSHAL) if (phase == PHASE_UNMARSHAL)
@ -1971,14 +2062,14 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
rtype = type->type; rtype = type->type;
if (is_user_derived( var )) if (is_user_type(var->type))
{ {
print_phase_function(file, indent, "UserMarshal", phase, var->name, start_offset); print_phase_function(file, indent, "UserMarshal", phase, var, start_offset);
} }
else if (is_string_type(var->attrs, var->type)) else if (is_string_type(var->attrs, var->type))
{ {
if (is_array(type) && !is_conformant_array(type)) if (is_array(type) && !is_conformant_array(type))
print_phase_function(file, indent, "NonConformantString", phase, var->name, start_offset); print_phase_function(file, indent, "NonConformantString", phase, var, start_offset);
else else
{ {
if (type->size_is && is_size_needed_for_phase(phase)) if (type->size_is && is_size_needed_for_phase(phase))
@ -1989,9 +2080,9 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
} }
if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP)) if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP))
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset); print_phase_function(file, indent, "Pointer", phase, var, start_offset);
else else
print_phase_function(file, indent, "ConformantString", phase, var->name, print_phase_function(file, indent, "ConformantString", phase, var,
start_offset + (type->size_is ? 4 : 2)); start_offset + (type->size_is ? 4 : 2));
} }
} }
@ -2049,9 +2140,9 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
else if (phase != PHASE_FREE) else if (phase != PHASE_FREE)
{ {
if (pointer_type == RPC_FC_UP) if (pointer_type == RPC_FC_UP)
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset); print_phase_function(file, indent, "Pointer", phase, var, start_offset);
else else
print_phase_function(file, indent, array_type, phase, var->name, start_offset); print_phase_function(file, indent, array_type, phase, var, start_offset);
} }
} }
else if (!is_ptr(var->type) && is_base_type(rtype)) else if (!is_ptr(var->type) && is_base_type(rtype))
@ -2064,17 +2155,17 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{ {
case RPC_FC_STRUCT: case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT: case RPC_FC_PSTRUCT:
print_phase_function(file, indent, "SimpleStruct", phase, var->name, start_offset); print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset);
break; break;
case RPC_FC_CSTRUCT: case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT: case RPC_FC_CPSTRUCT:
print_phase_function(file, indent, "ConformantStruct", phase, var->name, start_offset); print_phase_function(file, indent, "ConformantStruct", phase, var, start_offset);
break; break;
case RPC_FC_CVSTRUCT: case RPC_FC_CVSTRUCT:
print_phase_function(file, indent, "ConformantVaryingStruct", phase, var->name, start_offset); print_phase_function(file, indent, "ConformantVaryingStruct", phase, var, start_offset);
break; break;
case RPC_FC_BOGUS_STRUCT: case RPC_FC_BOGUS_STRUCT:
print_phase_function(file, indent, "ComplexStruct", phase, var->name, start_offset); print_phase_function(file, indent, "ComplexStruct", phase, var, start_offset);
break; break;
case RPC_FC_RP: case RPC_FC_RP:
if (is_base_type( var->type->ref->type )) if (is_base_type( var->type->ref->type ))
@ -2084,14 +2175,14 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
else if (var->type->ref->type == RPC_FC_STRUCT) else if (var->type->ref->type == RPC_FC_STRUCT)
{ {
if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
print_phase_function(file, indent, "SimpleStruct", phase, var->name, start_offset + 4); print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4);
} }
else else
{ {
const var_t *iid; const var_t *iid;
if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name ); print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name );
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset); print_phase_function(file, indent, "Pointer", phase, var, start_offset);
} }
break; break;
default: default:
@ -2107,14 +2198,14 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
else if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT)) else if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT))
{ {
if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE) if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
print_phase_function(file, indent, "SimpleStruct", phase, var->name, start_offset + 4); print_phase_function(file, indent, "SimpleStruct", phase, var, start_offset + 4);
} }
else else
{ {
const var_t *iid; const var_t *iid;
if ((iid = get_attrp( var->attrs, ATTR_IIDIS ))) if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name ); print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name );
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset); print_phase_function(file, indent, "Pointer", phase, var, start_offset);
} }
} }
fprintf(file, "\n"); fprintf(file, "\n");
@ -2308,6 +2399,10 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
write_name(file, var); write_name(file, var);
write_type_right(file, var->type, FALSE); write_type_right(file, var->type, FALSE);
fprintf(file, ";\n"); fprintf(file, ";\n");
if (decl_indirect(var->type))
print_file(file, indent, "void *_p_%s = &%s;\n",
var->name, var->name);
} }
} }
@ -2414,6 +2509,27 @@ void write_expr_eval_routine_list(FILE *file, const char *iface)
fprintf(file, "};\n\n"); fprintf(file, "};\n\n");
} }
void write_user_quad_list(FILE *file)
{
user_type_t *ut;
if (list_empty(&user_type_list))
return;
fprintf(file, "static const USER_MARSHAL_ROUTINE_QUADRUPLE UserMarshalRoutines[] =\n");
fprintf(file, "{\n");
LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry)
{
const char *sep = &ut->entry == list_tail(&user_type_list) ? "" : ",";
print_file(file, 1, "{\n");
print_file(file, 2, "%s_UserSize,\n", ut->name);
print_file(file, 2, "%s_UserMarshal,\n", ut->name);
print_file(file, 2, "%s_UserUnmarshal,\n", ut->name);
print_file(file, 2, "%s_UserFree\n", ut->name);
print_file(file, 1, "}%s\n", sep);
}
fprintf(file, "};\n\n");
}
void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ) void write_endpoints( FILE *f, const char *prefix, const str_list_t *list )
{ {

View File

@ -48,5 +48,8 @@ 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 ); void declare_stub_args( FILE *file, int indent, const func_t *func );
int write_expr_eval_routines(FILE *file, const char *iface); int write_expr_eval_routines(FILE *file, const char *iface);
void write_expr_eval_routine_list(FILE *file, const char *iface); void write_expr_eval_routine_list(FILE *file, const char *iface);
void write_user_quad_list(FILE *file);
void write_endpoints( FILE *f, const char *prefix, const str_list_t *list ); void write_endpoints( FILE *f, const char *prefix, const str_list_t *list );
size_t type_memsize(const type_t *t, unsigned int *align); size_t type_memsize(const type_t *t, unsigned int *align);
int decl_indirect(const type_t *t);
void write_parameters_init(const func_t *func);

View File

@ -46,6 +46,7 @@ typedef struct _typelib_entry_t typelib_entry_t;
typedef struct _importlib_t importlib_t; typedef struct _importlib_t importlib_t;
typedef struct _importinfo_t importinfo_t; typedef struct _importinfo_t importinfo_t;
typedef struct _typelib_t typelib_t; typedef struct _typelib_t typelib_t;
typedef struct _user_type_t user_type_t;
typedef struct list attr_list_t; typedef struct list attr_list_t;
typedef struct list str_list_t; typedef struct list str_list_t;
@ -55,6 +56,7 @@ typedef struct list var_list_t;
typedef struct list pident_list_t; typedef struct list pident_list_t;
typedef struct list ifref_list_t; typedef struct list ifref_list_t;
typedef struct list array_dims_t; typedef struct list array_dims_t;
typedef struct list user_type_list_t;
enum attr_type enum attr_type
{ {
@ -295,6 +297,14 @@ struct _typelib_t {
struct list importlibs; struct list importlibs;
}; };
struct _user_type_t {
struct list entry;
const char *name;
};
extern user_type_list_t user_type_list;
void check_for_user_types(const var_list_t *list);
void init_types(void); void init_types(void);
type_t *duptype(type_t *t, int dupname); type_t *duptype(type_t *t, int dupname);