Commit 978b4d4f authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

widl: Represent arrays with type_t.

parent f5baddf8
......@@ -162,6 +162,47 @@ s_test_list_length(test_list_t *list)
: 0);
}
int
s_sum_fixed_int_3d(int m[2][3][4])
{
int i, j, k;
int sum = 0;
for (i = 0; i < 2; ++i)
for (j = 0; j < 3; ++j)
for (k = 0; k < 4; ++k)
sum += m[i][j][k];
return sum;
}
int
s_sum_conf_array(int x[], int n)
{
int *p = x, *end = p + n;
int sum = 0;
while (p < end)
sum += *p++;
return sum;
}
int
s_sum_var_array(int x[20], int n)
{
ok(0 <= n, "RPC sum_var_array\n");
ok(n <= 20, "RPC sum_var_array\n");
return s_sum_conf_array(x, n);
}
int
s_dot_two_vectors(vector_t vs[2])
{
return vs[0].x * vs[1].x + vs[0].y * vs[1].y + vs[0].z * vs[1].z;
}
void
s_stop(void)
{
......@@ -336,6 +377,41 @@ pointer_tests(void)
}
static void
array_tests(void)
{
static int m[2][3][4] =
{
{{1, 2, 3, 4}, {-1, -3, -5, -7}, {0, 2, 4, 6}},
{{1, -2, 3, -4}, {2, 3, 5, 7}, {-4, -1, -14, 4114}}
};
static int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static vector_t vs[2] = {{1, -2, 3}, {4, -5, -6}};
ok(sum_fixed_int_3d(m) == 4116, "RPC sum_fixed_int_3d\n");
ok(sum_conf_array(c, 10) == 45, "RPC sum_conf_array\n");
ok(sum_conf_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
ok(sum_conf_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
ok(sum_conf_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
ok(sum_var_array(c, 10) == 45, "RPC sum_conf_array\n");
ok(sum_var_array(&c[5], 2) == 11, "RPC sum_conf_array\n");
ok(sum_var_array(&c[7], 1) == 7, "RPC sum_conf_array\n");
ok(sum_var_array(&c[2], 0) == 0, "RPC sum_conf_array\n");
ok(dot_two_vectors(vs) == -4, "RPC dot_two_vectors\n");
}
static void
run_tests(void)
{
basic_tests();
union_tests();
pointer_tests();
array_tests();
}
static void
client(const char *test)
{
if (strcmp(test, "tcp_basic") == 0)
......@@ -348,9 +424,7 @@ client(const char *test)
ok(RPC_S_OK == RpcStringBindingCompose(NULL, iptcp, address, port, NULL, &binding), "RpcStringBindingCompose\n");
ok(RPC_S_OK == RpcBindingFromStringBinding(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
basic_tests();
union_tests();
pointer_tests();
run_tests();
ok(RPC_S_OK == RpcStringFree(&binding), "RpcStringFree\n");
ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n");
......@@ -365,9 +439,7 @@ client(const char *test)
ok(RPC_S_OK == RpcStringBindingCompose(NULL, np, address, pipe, NULL, &binding), "RpcStringBindingCompose\n");
ok(RPC_S_OK == RpcBindingFromStringBinding(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n");
basic_tests();
union_tests();
pointer_tests();
run_tests();
stop();
ok(RPC_S_OK == RpcStringFree(&binding), "RpcStringFree\n");
......
......@@ -108,5 +108,9 @@ interface IServer
} test_list_t;
int test_list_length(test_list_t *ls);
int sum_fixed_int_3d(int m[2][3][4]);
int sum_conf_array([size_is(n)] int x[], int n);
int sum_var_array([length_is(n)] int x[20], int n);
int dot_two_vectors(vector_t vs[2]);
void stop(void);
}
......@@ -115,8 +115,9 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
}
}
write_type(client, def->type);
fprintf(client, " ");
write_type_left(client, def->type);
if (needs_space_after(def->type))
fprintf(client, " ");
write_prefix_name(client, prefix_client, def);
fprintf(client, "(\n");
indent++;
......@@ -135,7 +136,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
if (!is_void(def->type))
{
print_client("");
write_type(client, def->type);
write_type_left(client, def->type);
fprintf(client, " _RetVal;\n");
}
......
......@@ -20,6 +20,7 @@
#include "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
......@@ -96,22 +97,9 @@ int is_void(const type_t *t)
return 0;
}
int is_conformant_array( const array_dims_t *array )
int is_conformant_array(const type_t *t)
{
expr_t *dim;
if (!array) return 0;
dim = LIST_ENTRY( list_head( array ), expr_t, entry );
return !dim->is_const;
}
int is_non_void(const expr_list_t *list)
{
const expr_t *expr;
if (list)
LIST_FOR_EACH_ENTRY( expr, list, const expr_t, entry )
if (expr->type != EXPR_VOID) return 1;
return 0;
return t->type == RPC_FC_CARRAY || t->type == RPC_FC_CVARRAY;
}
void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)
......@@ -141,34 +129,12 @@ void write_prefix_name(FILE *h, const char *prefix, const var_t *v)
write_name(h, v);
}
void write_array(FILE *h, array_dims_t *dims, int field)
{
expr_t *v;
if (!dims) return;
fprintf(h, "[");
LIST_FOR_EACH_ENTRY( v, dims, expr_t, entry )
{
if (v->is_const)
fprintf(h, "%ld", v->cval); /* statically sized array */
else
if (field) fprintf(h, "1"); /* dynamically sized array */
if (list_next( dims, &v->entry ))
fprintf(h, ", ");
}
fprintf(h, "]");
}
static void write_field(FILE *h, var_t *v)
{
if (!v) return;
if (v->type) {
indent(h, 0);
write_type(h, v->type);
if (v->name)
fprintf(h, " %s", v->name);
else {
/* not all C/C++ compilers support anonymous structs and unions */
const char *name = v->name;
if (name == NULL) {
switch (v->type->type) {
case RPC_FC_STRUCT:
case RPC_FC_CVSTRUCT:
......@@ -177,17 +143,18 @@ static void write_field(FILE *h, var_t *v)
case RPC_FC_PSTRUCT:
case RPC_FC_BOGUS_STRUCT:
case RPC_FC_ENCAPSULATED_UNION:
fprintf(h, " DUMMYSTRUCTNAME");
name = "DUMMYSTRUCTNAME";
break;
case RPC_FC_NON_ENCAPSULATED_UNION:
fprintf(h, " DUMMYUNIONNAME");
name = "DUMMYUNIONNAME";
break;
default:
/* ? */
break;
}
}
write_array(h, v->array, 1);
indent(h, 0);
write_type(h, v->type, TRUE, "%s", name);
fprintf(h, ";\n");
}
}
......@@ -218,16 +185,18 @@ static void write_enums(FILE *h, var_list_t *enums)
fprintf(h, "\n");
}
static int needs_space_after(type_t *t)
int needs_space_after(type_t *t)
{
return t->kind == TKIND_ALIAS || ! is_ptr(t);
return (t->kind == TKIND_ALIAS
|| (!is_ptr(t) && (!is_conformant_array(t) || t->declarray)));
}
void write_type(FILE *h, type_t *t)
void write_type_left(FILE *h, type_t *t)
{
if (t->is_const) fprintf(h, "const ");
if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name);
else if (t->declarray) write_type_left(h, t->ref);
else {
if (t->sign > 0) fprintf(h, "signed ");
else if (t->sign < 0) fprintf(h, "unsigned ");
......@@ -279,7 +248,9 @@ void write_type(FILE *h, type_t *t)
case RPC_FC_UP:
case RPC_FC_FP:
case RPC_FC_OP:
if (t->ref) write_type(h, t->ref);
case RPC_FC_CARRAY:
case RPC_FC_CVARRAY:
write_type_left(h, t->ref);
fprintf(h, "%s*", needs_space_after(t->ref) ? " " : "");
break;
default:
......@@ -288,6 +259,32 @@ void write_type(FILE *h, type_t *t)
}
}
void write_type_right(FILE *h, type_t *t, int is_field)
{
if (t->declarray) {
if (is_conformant_array(t)) {
fprintf(h, "[%s]", is_field ? "1" : "");
t = t->ref;
}
for ( ; t->declarray; t = t->ref)
fprintf(h, "[%lu]", t->dim);
}
}
void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...)
{
write_type_left(h, t);
if (fmt) {
va_list args;
va_start(args, fmt);
if (needs_space_after(t))
fprintf(h, " ");
vfprintf(h, fmt, args);
va_end(args);
}
write_type_right(h, t, is_field);
}
struct user_type
{
......@@ -354,8 +351,8 @@ void write_user_types(void)
void write_typedef(type_t *type)
{
fprintf(header, "typedef ");
write_type(header, type->orig);
fprintf(header, "%s%s;\n", needs_space_after(type->orig) ? " " : "", type->name);
write_type(header, type->orig, FALSE, "%s", type->name);
fprintf(header, ";\n");
}
void write_expr(FILE *h, const expr_t *e, int brackets)
......@@ -392,13 +389,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
break;
case EXPR_CAST:
fprintf(h, "(");
write_type(h, e->u.tref);
write_type(h, e->u.tref, FALSE, NULL);
fprintf(h, ")");
write_expr(h, e->ref, 1);
break;
case EXPR_SIZEOF:
fprintf(h, "sizeof(");
write_type(h, e->u.tref);
write_type(h, e->u.tref, FALSE, NULL);
fprintf(h, ")");
break;
case EXPR_SHL:
......@@ -447,9 +444,7 @@ void write_constdef(const var_t *v)
void write_externdef(const var_t *v)
{
fprintf(header, "extern const ");
write_type(header, v->type);
if (v->name)
fprintf(header, " %s", v->name);
write_type(header, v->type, FALSE, "%s", v->name);
fprintf(header, ";\n\n");
}
......@@ -573,9 +568,9 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
}
else fprintf(h, ",");
}
write_type(h, arg->type);
if (arg->args)
{
write_type_left(h, arg->type);
fprintf(h, " (STDMETHODCALLTYPE *");
write_name(h,arg);
fprintf(h, ")(");
......@@ -583,12 +578,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
fprintf(h, ")");
}
else
{
if (needs_space_after(arg->type))
fprintf(h, " ");
write_name(h, arg);
}
write_array(h, arg->array, 0);
write_type(h, arg->type, FALSE, "%s", arg->name);
count++;
}
if (do_indent) indentation--;
......@@ -606,7 +596,7 @@ static void write_cpp_method_def(const type_t *iface)
if (!is_callas(def->attrs)) {
indent(header, 0);
fprintf(header, "virtual ");
write_type(header, def->type);
write_type_left(header, def->type);
fprintf(header, " STDMETHODCALLTYPE ");
write_name(header, def);
fprintf(header, "(\n");
......@@ -631,7 +621,7 @@ static void do_write_c_method_def(const type_t *iface, const char *name)
const var_t *def = cur->def;
if (!is_callas(def->attrs)) {
indent(header, 0);
write_type(header, def->type);
write_type_left(header, def->type);
fprintf(header, " (STDMETHODCALLTYPE *");
write_name(header, def);
fprintf(header, ")(\n");
......@@ -664,7 +654,7 @@ static void write_method_proto(const type_t *iface)
if (!is_local(def->attrs)) {
/* proxy prototype */
write_type(header, def->type);
write_type_left(header, def->type);
fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, def);
fprintf(header, "_Proxy(\n");
......@@ -687,14 +677,14 @@ static void write_method_proto(const type_t *iface)
if (&m->entry != iface->funcs) {
const var_t *mdef = m->def;
/* proxy prototype - use local prototype */
write_type(header, mdef->type);
write_type_left(header, mdef->type);
fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, mdef);
fprintf(header, "_Proxy(\n");
write_args(header, m->args, iface->name, 1, TRUE);
fprintf(header, ");\n");
/* stub prototype - use remotable prototype */
write_type(header, def->type);
write_type_left(header, def->type);
fprintf(header, " __RPC_STUB %s_", iface->name);
write_name(header, mdef);
fprintf(header, "_Stub(\n");
......@@ -713,7 +703,7 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c
var_t *def = fun->def;
/* FIXME: do we need to handle call_as? */
write_type(header, def->type);
write_type_left(header, def->type);
fprintf(header, " ");
write_prefix_name(header, prefix, def);
fprintf(header, "(\n");
......
......@@ -28,11 +28,14 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t);
extern int is_void(const type_t *t);
extern int is_conformant_array( const array_dims_t *array );
extern int is_non_void(const expr_list_t *list);
extern int is_conformant_array(const type_t *t);
extern void write_name(FILE *h, const var_t *v);
extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v);
extern void write_type(FILE *h, type_t *t);
extern const char* get_name(const var_t *v);
extern void write_type_left(FILE *h, type_t *t);
extern void write_type_right(FILE *h, type_t *t, int is_field);
extern void write_type(FILE *h, type_t *t, int is_field, const char *fmt, ...);
extern int needs_space_after(type_t *t);
extern int is_object(const attr_list_t *list);
extern int is_local(const attr_list_t *list);
extern const var_t *is_callas(const attr_list_t *list);
......@@ -59,16 +62,14 @@ static inline int last_ptr(const type_t *type)
return is_ptr(type) && !is_ptr(type->ref);
}
static inline int is_string_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array)
static inline int last_array(const type_t *type)
{
return (is_attr(attrs, ATTR_STRING) &&
((last_ptr(type) && !array) || (!is_ptr(type) && array)));
return is_array(type) && !is_array(type->ref);
}
static inline int is_array_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array)
static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
{
return ((last_ptr(type) && !array && is_attr(attrs, ATTR_SIZEIS)) ||
(!is_ptr(type) && array));
return is_attr(attrs, ATTR_STRING) && (last_ptr(type) || last_array(type));
}
#endif
......@@ -38,6 +38,7 @@
#include "parser.h"
#include "header.h"
#include "typelib.h"
#include "typegen.h"
#if defined(YYBYACC)
/* Berkeley yacc (byacc) doesn't seem to know about these */
......@@ -303,12 +304,24 @@ int_statements: { $$ = NULL; }
statement: ';' {}
| constdef ';' { if (!parse_only && do_header) { write_constdef($1); } }
| cppquote {}
| enumdef ';' { if (!parse_only && do_header) { write_type(header, $1); fprintf(header, ";\n\n"); } }
| enumdef ';' { if (!parse_only && do_header) {
write_type(header, $1, FALSE, NULL);
fprintf(header, ";\n\n");
}
}
| externdef ';' { if (!parse_only && do_header) { write_externdef($1); } }
| import {}
| structdef ';' { if (!parse_only && do_header) { write_type(header, $1); fprintf(header, ";\n\n"); } }
| structdef ';' { if (!parse_only && do_header) {
write_type(header, $1, FALSE, NULL);
fprintf(header, ";\n\n");
}
}
| typedef ';' {}
| uniondef ';' { if (!parse_only && do_header) { write_type(header, $1); fprintf(header, ";\n\n"); } }
| uniondef ';' { if (!parse_only && do_header) {
write_type(header, $1, FALSE, NULL);
fprintf(header, ";\n\n");
}
}
;
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
......@@ -346,18 +359,18 @@ args: arg { check_arg($1); $$ = append_var( NULL, $1 ); }
/* split into two rules to get bison to resolve a tVOID conflict */
arg: attributes type pident array { $$ = $3->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level, $4);
free($3);
$$->attrs = $1;
}
| type pident array { $$ = $2->var;
set_type($$, $1, $2->ptr_level, $3);
free($2);
}
| attributes type pident '(' m_args ')' { $$ = $3->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level - 1, NULL);
free($3);
$$->attrs = $1;
$$->args = $5;
}
| type pident '(' m_args ')' { $$ = $2->var;
......@@ -597,18 +610,18 @@ field: s_field ';' { $$ = $1; }
;
s_field: m_attributes type pident array { $$ = $3->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level, $4);
free($3);
$$->attrs = $1;
}
;
funcdef:
m_attributes type callconv pident
'(' m_args ')' { var_t *v = $4->var;
v->attrs = $1;
set_type(v, $2, $4->ptr_level, NULL);
free($4);
v->attrs = $1;
$$ = make_func(v, $6);
if (is_attr(v->attrs, ATTR_IN)) {
yyerror("inapplicable attribute [in] for function '%s'",$$->def->name);
......@@ -1199,7 +1212,11 @@ static type_t *make_type(unsigned char type, type_t *ref)
t->funcs = NULL;
t->fields = NULL;
t->ifaces = NULL;
t->dim = 0;
t->size_is = NULL;
t->length_is = NULL;
t->typestring_offset = 0;
t->declarray = FALSE;
t->ignore = (parse_only != 0);
t->is_const = FALSE;
t->sign = 0;
......@@ -1213,11 +1230,106 @@ static type_t *make_type(unsigned char type, type_t *ref)
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr)
{
expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
int sizeless, has_varconf;
expr_t *dim;
type_t *atype, **ptype;
v->type = type;
v->array = arr;
for ( ; 0 < ptr_level; --ptr_level)
v->type = make_type(RPC_FC_RP, v->type);
sizeless = FALSE;
if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
{
if (sizeless)
error("%s: only the first array dimension can be unspecified\n", v->name);
if (dim->is_const)
{
unsigned int align = 0;
size_t size = type_memsize(v->type, &align);
if (dim->cval <= 0)
error("%s: array dimension must be positive\n", v->name);
if (0xffffffffuL / size < (unsigned long) dim->cval)
error("%s: total array size is too large", v->name);
else if (0xffffuL < size * dim->cval)
v->type = make_type(RPC_FC_LGFARRAY, v->type);
else
v->type = make_type(RPC_FC_SMFARRAY, v->type);
}
else
{
sizeless = TRUE;
v->type = make_type(RPC_FC_CARRAY, v->type);
}
v->type->declarray = TRUE;
v->type->dim = dim->cval;
}
ptype = &v->type;
has_varconf = FALSE;
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
{
if (dim->type != EXPR_VOID)
{
has_varconf = TRUE;
atype = *ptype = duptype(*ptype, 0);
if (atype->type == RPC_FC_SMFARRAY || atype->type == RPC_FC_LGFARRAY)
error("%s: cannot specify size_is for a fixed sized array\n", v->name);
if (atype->type != RPC_FC_CARRAY && !is_ptr(atype))
error("%s: size_is attribute applied to illegal type\n", v->name);
atype->type = RPC_FC_CARRAY;
atype->size_is = dim;
}
ptype = &(*ptype)->ref;
if (*ptype == NULL)
error("%s: too many expressions in size_is attribute\n", v->name);
}
ptype = &v->type;
if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
{
if (dim->type != EXPR_VOID)
{
has_varconf = TRUE;
atype = *ptype = duptype(*ptype, 0);
if (atype->type == RPC_FC_SMFARRAY)
atype->type = RPC_FC_SMVARRAY;
else if (atype->type == RPC_FC_LGFARRAY)
atype->type = RPC_FC_LGVARRAY;
else if (atype->type == RPC_FC_CARRAY)
atype->type = RPC_FC_CVARRAY;
else
error("%s: length_is attribute applied to illegal type\n", v->name);
atype->length_is = dim;
}
ptype = &(*ptype)->ref;
if (*ptype == NULL)
error("%s: too many expressions in length_is attribute\n", v->name);
}
if (has_varconf && !last_array(v->type))
{
ptype = &v->type;
for (ptype = &v->type; is_array(*ptype); ptype = &(*ptype)->ref)
{
*ptype = duptype(*ptype, 0);
(*ptype)->type = RPC_FC_BOGUS_ARRAY;
}
}
}
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface)
......@@ -1259,7 +1371,6 @@ static var_t *make_var(char *name)
v->type = NULL;
v->args = NULL;
v->attrs = NULL;
v->array = NULL;
v->eval = NULL;
v->corrdesc = 0;
return v;
......@@ -1513,24 +1624,29 @@ static int get_struct_type(var_list_t *fields)
continue;
}
if (is_string_type(field->attrs, field->type, field->array))
if (field->type->declarray)
{
has_conformance = 1;
has_variance = 1;
continue;
}
if (is_string_type(field->attrs, field->type))
{
has_conformance = 1;
has_variance = 1;
continue;
}
if (is_array_type(field->attrs, field->type, field->array))
{
if (field->array && is_conformant_array(field->array))
if (is_array(field->type->ref))
return RPC_FC_BOGUS_STRUCT;
if (is_conformant_array(field->type))
{
has_conformance = 1;
if (list_next( fields, &field->entry ))
if (field->type->declarray && list_next(fields, &field->entry))
yyerror("field '%s' deriving from a conformant array must be the last field in the structure",
field->name);
}
if (is_attr(field->attrs, ATTR_LENGTHIS))
if (field->type->length_is)
has_variance = 1;
t = field->type->ref;
}
switch (t->type)
......@@ -1565,13 +1681,9 @@ static int get_struct_type(var_list_t *fields)
case RPC_FC_UP:
case RPC_FC_FP:
case RPC_FC_OP:
has_pointer = 1;
break;
case RPC_FC_CARRAY:
has_conformance = 1;
if (list_next( fields, &field->entry ))
yyerror("field '%s' deriving from a conformant array must be the last field in the structure",
field->name);
case RPC_FC_CVARRAY:
has_pointer = 1;
break;
/*
......
......@@ -261,7 +261,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
int has_ret = !is_void(def->type);
indent = 0;
write_type(proxy, def->type);
write_type_left(proxy, def->type);
print_proxy( " STDMETHODCALLTYPE %s_", iface->name);
write_name(proxy, def);
print_proxy( "_Proxy(\n");
......@@ -272,7 +272,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
/* local variables */
if (has_ret) {
print_proxy( "" );
write_type(proxy, def->type);
write_type_left(proxy, def->type);
print_proxy( " _RetVal;\n");
}
print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
......@@ -408,7 +408,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
LIST_FOR_EACH_ENTRY( arg, cur->args, const var_t, entry )
{
fprintf(proxy, ", ");
if (arg->array)
if (arg->type->declarray)
fprintf(proxy, "*");
write_name(proxy, arg);
}
......
......@@ -207,7 +207,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
else
fprintf(server, ",\n");
print_server("");
if (var->array)
if (var->type->declarray)
fprintf(server, "*");
write_name(server, var);
}
......
......@@ -49,3 +49,4 @@ void declare_stub_args( FILE *file, int indent, const func_t *func );
int write_expr_eval_routines(FILE *file, const char *iface);
void write_expr_eval_routine_list(FILE *file, const char *iface);
void write_endpoints( FILE *f, const char *prefix, const str_list_t *list );
size_t type_memsize(const type_t *t, unsigned int *align);
......@@ -69,6 +69,7 @@ type_t *alias(type_t *t, const char *name)
a->name = xstrdup(name);
a->kind = TKIND_ALIAS;
a->attrs = NULL;
a->declarray = FALSE;
return a;
}
......@@ -82,6 +83,23 @@ int is_ptr(const type_t *t)
|| c == RPC_FC_OP;
}
int is_array(const type_t *t)
{
switch (t->type)
{
case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY:
case RPC_FC_SMVARRAY:
case RPC_FC_LGVARRAY:
case RPC_FC_CARRAY:
case RPC_FC_CVARRAY:
case RPC_FC_BOGUS_ARRAY:
return TRUE;
default:
return FALSE;
}
}
/* List of oleauto types that should be recognized by name.
* (most of) these seem to be intrinsic types in mktyplib. */
......
......@@ -206,9 +206,12 @@ struct _type_t {
func_list_t *funcs; /* interfaces and modules */
var_list_t *fields; /* interfaces, structures and enumerations */
ifref_list_t *ifaces; /* coclasses */
unsigned long dim; /* array dimension */
expr_t *size_is, *length_is;
type_t *orig; /* dup'd types */
unsigned int typestring_offset;
int typelib_idx;
unsigned int declarray : 1; /* if declared as an array */
unsigned int ignore : 1;
unsigned int is_const : 1;
unsigned int defined : 1;
......@@ -220,7 +223,6 @@ struct _type_t {
struct _var_t {
char *name;
array_dims_t *array;
type_t *type;
var_list_t *args; /* for function pointers */
attr_list_t *attrs;
......@@ -300,6 +302,7 @@ type_t *duptype(type_t *t, int dupname);
type_t *alias(type_t *t, const char *name);
int is_ptr(const type_t *t);
int is_array(const type_t *t);
int is_var_ptr(const var_t *v);
int cant_be_null(const var_t *v);
......
......@@ -1071,6 +1071,45 @@ static int encode_var(
chat("encode_var: var %p type %p type->name %s type->ref %p\n",
var, type, type->name ? type->name : "NULL", type->ref);
if (type->declarray) {
int num_dims, elements = 1, arrayoffset;
type_t *atype;
int *arraydata;
num_dims = 0;
for (atype = type; atype->declarray; atype = atype->ref)
++num_dims;
chat("array with %d dimensions\n", num_dims);
encode_var(typelib, atype, var, &target_type, width, alignment, NULL);
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0);
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
arraydata[0] = target_type;
arraydata[1] = num_dims;
arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16);
arraydata += 2;
for (atype = type; atype->declarray; atype = atype->ref)
{
arraydata[0] = atype->dim;
arraydata[1] = 0;
arraydata += 2;
elements *= atype->dim;
}
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
typedata[0] = (0x7ffe << 16) | VT_CARRAY;
typedata[1] = arrayoffset;
*encoded_type = typeoffset;
*width = *width * elements;
*decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
return 0;
}
vt = get_type_vt(type);
if (vt == VT_PTR) {
int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size);
......@@ -1114,44 +1153,6 @@ static int encode_var(
return 0;
}
if(var->array) {
expr_t *dim;
array_dims_t *array_save;
int num_dims = list_count( var->array ), elements = 1, arrayoffset;
int *arraydata;
chat("array with %d dimensions\n", num_dims);
array_save = var->array;
var->array = NULL;
encode_var(typelib, type, var, &target_type, width, alignment, NULL);
var->array = array_save;
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0);
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
arraydata[0] = target_type;
arraydata[1] = num_dims;
arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16);
arraydata += 2;
LIST_FOR_EACH_ENTRY( dim, var->array, expr_t, entry )
{
arraydata[0] = dim->cval;
arraydata[1] = 0;
arraydata += 2;
elements *= dim->cval;
}
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
typedata[0] = (0x7ffe << 16) | VT_CARRAY;
typedata[1] = arrayoffset;
*encoded_type = typeoffset;
*width = *width * elements;
*decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
return 0;
}
dump_type(type);
encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size);
......@@ -1557,7 +1558,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
char *namedata;
int var_num = (typeinfo->typeinfo->cElement >> 16) & 0xffff;
chat("add_var_desc(%d,%s) array %p\n", index, var->name, var->array);
chat("add_var_desc(%d, %s)\n", index, var->name);
id = 0x40000000 + index;
......
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