Commit 43ac6ed9 authored by Alexandre Julliard's avatar Alexandre Julliard

widl: Convert expression lists to standard Wine lists.

Add a specific type for array dimensions.
parent eed74e4e
...@@ -77,6 +77,14 @@ int is_void(const type_t *t, const var_t *v) ...@@ -77,6 +77,14 @@ int is_void(const type_t *t, const var_t *v)
return 0; return 0;
} }
int is_conformant_array( const array_dims_t *array )
{
expr_t *dim;
if (!array) return 0;
dim = LIST_ENTRY( list_head( array ), expr_t, entry );
return !dim->is_const;
}
void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)
{ {
if (!uuid) return; if (!uuid) return;
...@@ -112,19 +120,20 @@ const char* get_name(const var_t *v) ...@@ -112,19 +120,20 @@ const char* get_name(const var_t *v)
return v->name; return v->name;
} }
void write_array(FILE *h, const expr_t *v, int field) void write_array(FILE *h, array_dims_t *dims, int field)
{ {
if (!v) return; expr_t *v;
while (NEXT_LINK(v)) v = NEXT_LINK(v);
if (!dims) return;
fprintf(h, "["); fprintf(h, "[");
while (v) { LIST_FOR_EACH_ENTRY( v, dims, expr_t, entry )
{
if (v->is_const) if (v->is_const)
fprintf(h, "%ld", v->cval); /* statically sized array */ fprintf(h, "%ld", v->cval); /* statically sized array */
else else
if (field) fprintf(h, "1"); /* dynamically sized array */ if (field) fprintf(h, "1"); /* dynamically sized array */
if (PREV_LINK(v)) if (list_next( dims, &v->entry ))
fprintf(h, ", "); fprintf(h, ", ");
v = PREV_LINK(v);
} }
fprintf(h, "]"); fprintf(h, "]");
} }
......
...@@ -25,6 +25,7 @@ extern int is_attr(const attr_list_t *list, enum attr_type t); ...@@ -25,6 +25,7 @@ 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 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 unsigned long get_attrv(const attr_list_t *list, enum attr_type t);
extern int is_void(const type_t *t, const var_t *v); extern int is_void(const type_t *t, const var_t *v);
extern int is_conformant_array( const array_dims_t *array );
extern void write_name(FILE *h, const var_t *v); extern void write_name(FILE *h, const var_t *v);
extern const char* get_name(const var_t *v); extern const char* get_name(const var_t *v);
extern void write_type(FILE *h, type_t *t, const var_t *v, const char *n); extern void write_type(FILE *h, type_t *t, const var_t *v, const char *n);
...@@ -32,7 +33,7 @@ extern int is_object(const attr_list_t *list); ...@@ -32,7 +33,7 @@ extern int is_object(const attr_list_t *list);
extern int is_local(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); 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_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
extern void write_array(FILE *h, const expr_t *v, int field); extern void write_array(FILE *h, array_dims_t *v, int field);
extern void write_forward(type_t *iface); extern void write_forward(type_t *iface);
extern void write_interface(type_t *iface); extern void write_interface(type_t *iface);
extern void write_dispinterface(type_t *iface); extern void write_dispinterface(type_t *iface);
...@@ -49,13 +50,13 @@ extern int has_out_arg_or_return(const func_t *func); ...@@ -49,13 +50,13 @@ extern int has_out_arg_or_return(const func_t *func);
extern void write_guid(FILE *f, const char *guid_prefix, const char *name, extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
const UUID *uuid); const UUID *uuid);
static inline int is_string_type(const attr_list_t *attrs, int ptr_level, const expr_t *array) static inline int is_string_type(const attr_list_t *attrs, int ptr_level, const array_dims_t *array)
{ {
return (is_attr(attrs, ATTR_STRING) && return (is_attr(attrs, ATTR_STRING) &&
((ptr_level == 1 && !array) || (ptr_level == 0 && array))); ((ptr_level == 1 && !array) || (ptr_level == 0 && array)));
} }
static inline int is_array_type(const attr_list_t *attrs, int ptr_level, const expr_t *array) static inline int is_array_type(const attr_list_t *attrs, int ptr_level, const array_dims_t *array)
{ {
return ((ptr_level == 1 && !array && is_attr(attrs, ATTR_SIZEIS)) || return ((ptr_level == 1 && !array && is_attr(attrs, ATTR_SIZEIS)) ||
(ptr_level == 0 && array)); (ptr_level == 0 && array));
......
...@@ -76,10 +76,12 @@ static expr_t *make_expr1(enum expr_type type, expr_t *expr); ...@@ -76,10 +76,12 @@ static expr_t *make_expr1(enum expr_type type, expr_t *expr);
static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2);
static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3);
static type_t *make_type(unsigned char type, type_t *ref); static type_t *make_type(unsigned char type, type_t *ref);
static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
static typeref_t *make_tref(char *name, type_t *ref); static typeref_t *make_tref(char *name, type_t *ref);
static typeref_t *uniq_tref(typeref_t *ref); static typeref_t *uniq_tref(typeref_t *ref);
static type_t *type_ref(typeref_t *ref); static type_t *type_ref(typeref_t *ref);
static void set_type(var_t *v, typeref_t *ref, expr_t *arr); static void set_type(var_t *v, typeref_t *ref, array_dims_t *arr);
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
static ifref_t *make_ifref(type_t *iface); static ifref_t *make_ifref(type_t *iface);
static var_list_t *append_var(var_list_t *list, var_t *var); static var_list_t *append_var(var_list_t *list, var_t *var);
...@@ -121,6 +123,8 @@ static void check_arg(var_t *arg); ...@@ -121,6 +123,8 @@ static void check_arg(var_t *arg);
attr_t *attr; attr_t *attr;
attr_list_t *attr_list; attr_list_t *attr_list;
expr_t *expr; expr_t *expr;
expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type; type_t *type;
typeref_t *tref; typeref_t *tref;
var_t *var; var_t *var;
...@@ -219,8 +223,9 @@ static void check_arg(var_t *arg); ...@@ -219,8 +223,9 @@ static void check_arg(var_t *arg);
%type <attr> attribute %type <attr> attribute
%type <attr_list> m_attributes attributes attrib_list %type <attr_list> m_attributes attributes attrib_list
%type <expr> m_exprs /* exprs expr_list */ m_expr expr expr_list_const expr_const %type <expr> m_expr expr expr_const
%type <expr> array array_list %type <expr_list> m_exprs /* exprs expr_list */ expr_list_const
%type <array_dims> array array_list
%type <type> inherit interface interfacehdr interfacedef interfacedec %type <type> inherit interface interfacehdr interfacedef interfacedec
%type <type> dispinterface dispinterfacehdr dispinterfacedef %type <type> dispinterface dispinterfacehdr dispinterfacedef
%type <type> module modulehdr moduledef %type <type> module modulehdr moduledef
...@@ -357,12 +362,12 @@ arg: attributes type pident array { $$ = $3; ...@@ -357,12 +362,12 @@ arg: attributes type pident array { $$ = $3;
array: { $$ = NULL; } array: { $$ = NULL; }
| '[' array_list ']' { $$ = $2; } | '[' array_list ']' { $$ = $2; }
| '[' '*' ']' { $$ = make_expr(EXPR_VOID); } | '[' '*' ']' { $$ = append_array( NULL, make_expr(EXPR_VOID) ); }
; ;
array_list: m_expr /* size of first dimension is optional */ array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); }
| array_list ',' expr { LINK($3, $1); $$ = $3; } | array_list ',' expr { $$ = append_array( $1, $3 ); }
| array_list ']' '[' expr { LINK($4, $1); $$ = $4; } | array_list ']' '[' expr { $$ = append_array( $1, $4 ); }
; ;
m_attributes: { $$ = NULL; } m_attributes: { $$ = NULL; }
...@@ -434,7 +439,9 @@ attribute: { $$ = NULL; } ...@@ -434,7 +439,9 @@ attribute: { $$ = NULL; }
| tPROPPUT { $$ = make_attr(ATTR_PROPPUT); } | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); }
| tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); } | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); }
| tPUBLIC { $$ = make_attr(ATTR_PUBLIC); } | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); }
| tRANGE '(' expr_const ',' expr_const ')' { LINK($5, $3); $$ = make_attrp(ATTR_RANGE, $5); } | tRANGE '(' expr_const ',' expr_const ')' { expr_list_t *list = append_expr( NULL, $3 );
list = append_expr( list, $5 );
$$ = make_attrp(ATTR_RANGE, list); }
| tREADONLY { $$ = make_attr(ATTR_READONLY); } | tREADONLY { $$ = make_attr(ATTR_READONLY); }
| tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); } | tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); }
| tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); } | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); }
...@@ -513,8 +520,8 @@ enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM ...@@ -513,8 +520,8 @@ enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM
} }
; ;
m_exprs: m_expr m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
| m_exprs ',' m_expr { LINK($3, $1); $$ = $3; } | m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); }
; ;
/* /*
...@@ -553,8 +560,8 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } ...@@ -553,8 +560,8 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); }
| '(' expr ')' { $$ = $2; } | '(' expr ')' { $$ = $2; }
; ;
expr_list_const: expr_const expr_list_const: expr_const { $$ = append_expr( NULL, $1 ); }
| expr_list_const ',' expr_const { LINK($3, $1); $$ = $3; } | expr_list_const ',' expr_const { $$ = append_expr( $1, $3 ); }
; ;
expr_const: expr { $$ = $1; expr_const: expr { $$ = $1;
...@@ -951,7 +958,6 @@ static expr_t *make_expr(enum expr_type type) ...@@ -951,7 +958,6 @@ static expr_t *make_expr(enum expr_type type)
e->ref = NULL; e->ref = NULL;
e->u.lval = 0; e->u.lval = 0;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
return e; return e;
} }
...@@ -962,7 +968,6 @@ static expr_t *make_exprl(enum expr_type type, long val) ...@@ -962,7 +968,6 @@ static expr_t *make_exprl(enum expr_type type, long val)
e->ref = NULL; e->ref = NULL;
e->u.lval = val; e->u.lval = val;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
/* check for numeric constant */ /* check for numeric constant */
if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) { if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) {
/* make sure true/false value is valid */ /* make sure true/false value is valid */
...@@ -981,7 +986,6 @@ static expr_t *make_exprs(enum expr_type type, char *val) ...@@ -981,7 +986,6 @@ static expr_t *make_exprs(enum expr_type type, char *val)
e->ref = NULL; e->ref = NULL;
e->u.sval = val; e->u.sval = val;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
/* check for predefined constants */ /* check for predefined constants */
if (type == EXPR_IDENTIFIER) { if (type == EXPR_IDENTIFIER) {
var_t *c = find_const(val, 0); var_t *c = find_const(val, 0);
...@@ -1003,7 +1007,6 @@ static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr) ...@@ -1003,7 +1007,6 @@ static expr_t *make_exprt(enum expr_type type, typeref_t *tref, expr_t *expr)
e->ref = expr; e->ref = expr;
e->u.tref = tref; e->u.tref = tref;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
/* check for cast of constant expression */ /* check for cast of constant expression */
if (type == EXPR_SIZEOF) { if (type == EXPR_SIZEOF) {
switch (tref->ref->type) { switch (tref->ref->type) {
...@@ -1049,7 +1052,6 @@ static expr_t *make_expr1(enum expr_type type, expr_t *expr) ...@@ -1049,7 +1052,6 @@ static expr_t *make_expr1(enum expr_type type, expr_t *expr)
e->ref = expr; e->ref = expr;
e->u.lval = 0; e->u.lval = 0;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
/* check for compile-time optimization */ /* check for compile-time optimization */
if (expr->is_const) { if (expr->is_const) {
e->is_const = TRUE; e->is_const = TRUE;
...@@ -1076,7 +1078,6 @@ static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) ...@@ -1076,7 +1078,6 @@ static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
e->ref = expr1; e->ref = expr1;
e->u.ext = expr2; e->u.ext = expr2;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
/* check for compile-time optimization */ /* check for compile-time optimization */
if (expr1->is_const && expr2->is_const) { if (expr1->is_const && expr2->is_const) {
e->is_const = TRUE; e->is_const = TRUE;
...@@ -1122,7 +1123,6 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp ...@@ -1122,7 +1123,6 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp
e->u.ext = expr2; e->u.ext = expr2;
e->ext2 = expr3; e->ext2 = expr3;
e->is_const = FALSE; e->is_const = FALSE;
INIT_LINK(e);
/* check for compile-time optimization */ /* check for compile-time optimization */
if (expr1->is_const && expr2->is_const && expr3->is_const) { if (expr1->is_const && expr2->is_const && expr3->is_const) {
e->is_const = TRUE; e->is_const = TRUE;
...@@ -1138,6 +1138,30 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp ...@@ -1138,6 +1138,30 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp
return e; return e;
} }
static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
{
if (!expr) return list;
if (!list)
{
list = xmalloc( sizeof(*list) );
list_init( list );
}
list_add_tail( list, &expr->entry );
return list;
}
static array_dims_t *append_array(array_dims_t *list, expr_t *expr)
{
if (!expr) return list;
if (!list)
{
list = xmalloc( sizeof(*list) );
list_init( list );
}
list_add_tail( list, &expr->entry );
return list;
}
static type_t *make_type(unsigned char type, type_t *ref) static type_t *make_type(unsigned char type, type_t *ref)
{ {
type_t *t = xmalloc(sizeof(type_t)); type_t *t = xmalloc(sizeof(type_t));
...@@ -1157,7 +1181,6 @@ static type_t *make_type(unsigned char type, type_t *ref) ...@@ -1157,7 +1181,6 @@ static type_t *make_type(unsigned char type, type_t *ref)
t->written = FALSE; t->written = FALSE;
t->user_types_registered = FALSE; t->user_types_registered = FALSE;
t->typelib_idx = -1; t->typelib_idx = -1;
INIT_LINK(t);
return t; return t;
} }
...@@ -1198,7 +1221,7 @@ static type_t *type_ref(typeref_t *ref) ...@@ -1198,7 +1221,7 @@ static type_t *type_ref(typeref_t *ref)
return t; return t;
} }
static void set_type(var_t *v, typeref_t *ref, expr_t *arr) static void set_type(var_t *v, typeref_t *ref, array_dims_t *arr)
{ {
v->type = ref->ref; v->type = ref->ref;
v->tname = ref->name; v->tname = ref->name;
...@@ -1280,7 +1303,6 @@ static type_t *make_class(char *name) ...@@ -1280,7 +1303,6 @@ static type_t *make_class(char *name)
type_t *c = make_type(0, NULL); type_t *c = make_type(0, NULL);
c->name = name; c->name = name;
c->kind = TKIND_COCLASS; c->kind = TKIND_COCLASS;
INIT_LINK(c);
return c; return c;
} }
...@@ -1488,7 +1510,7 @@ static int get_struct_type(var_list_t *fields) ...@@ -1488,7 +1510,7 @@ static int get_struct_type(var_list_t *fields)
if (is_array_type(field->attrs, 0, field->array)) if (is_array_type(field->attrs, 0, field->array))
{ {
if (field->array && !field->array->is_const) if (field->array && is_conformant_array(field->array))
{ {
has_conformance = 1; has_conformance = 1;
if (list_next( fields, &field->entry )) if (list_next( fields, &field->entry ))
......
...@@ -59,7 +59,7 @@ struct expr_eval_routine ...@@ -59,7 +59,7 @@ struct expr_eval_routine
const expr_t *expr; const expr_t *expr;
}; };
static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array); static size_t type_memsize(const type_t *t, int ptr_level, const array_dims_t *array);
static size_t fields_memsize(const var_list_t *fields); static size_t fields_memsize(const var_list_t *fields);
static int compare_expr(const expr_t *a, const expr_t *b) static int compare_expr(const expr_t *a, const expr_t *b)
...@@ -537,7 +537,7 @@ static size_t fields_memsize(const var_list_t *fields) ...@@ -537,7 +537,7 @@ static size_t fields_memsize(const var_list_t *fields)
return size; return size;
} }
static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array) static size_t type_memsize(const type_t *t, int ptr_level, const array_dims_t *array)
{ {
size_t size = 0; size_t size = 0;
...@@ -586,10 +586,12 @@ static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array) ...@@ -586,10 +586,12 @@ static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array)
if (array) if (array)
{ {
if (array->is_const) expr_t *dim;
size *= array->cval; LIST_FOR_EACH_ENTRY( dim, array, expr_t, entry )
else if (dim->is_const)
size = 0; size *= dim->cval;
else
size = 0;
} }
return size; return size;
...@@ -602,7 +604,7 @@ size_t get_type_memsize(const type_t *type) ...@@ -602,7 +604,7 @@ size_t get_type_memsize(const type_t *type)
static int write_pointers(FILE *file, const attr_list_t *attrs, static int write_pointers(FILE *file, const attr_list_t *attrs,
const type_t *type, int ptr_level, const type_t *type, int ptr_level,
const expr_t *array, int level, const array_dims_t *array, int level,
unsigned int *typestring_offset) unsigned int *typestring_offset)
{ {
int pointers_written = 0; int pointers_written = 0;
...@@ -650,7 +652,7 @@ static int write_pointers(FILE *file, const attr_list_t *attrs, ...@@ -650,7 +652,7 @@ static int write_pointers(FILE *file, const attr_list_t *attrs,
static size_t write_pointer_description(FILE *file, const attr_list_t *attrs, static size_t write_pointer_description(FILE *file, const attr_list_t *attrs,
const type_t *type, int ptr_level, const type_t *type, int ptr_level,
const expr_t *array, int level, const array_dims_t *array, int level,
size_t typestring_offset) size_t typestring_offset)
{ {
size_t size = 0; size_t size = 0;
...@@ -700,7 +702,7 @@ static size_t write_pointer_description(FILE *file, const attr_list_t *attrs, ...@@ -700,7 +702,7 @@ static size_t write_pointer_description(FILE *file, const attr_list_t *attrs,
} }
static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
const type_t *type, const expr_t *array, const type_t *type, const array_dims_t *array,
const char *name, unsigned int *typestring_offset) const char *name, unsigned int *typestring_offset)
{ {
const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS); const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
...@@ -744,11 +746,13 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, ...@@ -744,11 +746,13 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
*typestring_offset += 2; *typestring_offset += 2;
} }
if (array && array->is_const) if (array && !is_conformant_array(array))
{ {
if (array->cval > USHRT_MAX) /* FIXME: multi-dimensional array */
const expr_t *dim = LIST_ENTRY( list_head( array ), expr_t, entry );
if (dim->cval > USHRT_MAX)
error("array size for parameter %s exceeds %d bytes by %ld bytes\n", error("array size for parameter %s exceeds %d bytes by %ld bytes\n",
name, USHRT_MAX, array->cval - USHRT_MAX); name, USHRT_MAX, dim->cval - USHRT_MAX);
if (rtype == RPC_FC_CHAR) if (rtype == RPC_FC_CHAR)
WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset); WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset);
...@@ -757,7 +761,7 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, ...@@ -757,7 +761,7 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2; *typestring_offset += 2;
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", array->cval, array->cval); print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", dim->cval, dim->cval);
*typestring_offset += 2; *typestring_offset += 2;
return start_offset; return start_offset;
...@@ -789,13 +793,13 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, ...@@ -789,13 +793,13 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
} }
static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
const type_t *type, const expr_t *array, const type_t *type, const array_dims_t *array,
const char *name, unsigned int *typestring_offset) const char *name, unsigned int *typestring_offset)
{ {
const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS); const expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS);
const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS); const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
int has_length = length_is && (length_is->type != EXPR_VOID); int has_length = length_is && (length_is->type != EXPR_VOID);
int has_size = (size_is && (size_is->type != EXPR_VOID)) || !array->is_const; int has_size = (size_is && (size_is->type != EXPR_VOID)) || is_conformant_array(array);
size_t start_offset; size_t start_offset;
int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
if (!pointer_type) if (!pointer_type)
...@@ -807,13 +811,14 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, ...@@ -807,13 +811,14 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "NdrFcShort(0x2),\n"); print_file(file, 2, "NdrFcShort(0x2),\n");
*typestring_offset += 4; *typestring_offset += 4;
if (array && NEXT_LINK(array)) /* multi-dimensional array */ if (array && list_count(array) > 1) /* multi-dimensional array */
{ {
error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name); error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name);
return 0; return 0;
} }
else else
{ {
const expr_t *dim = LIST_ENTRY( list_head( array ), expr_t, entry );
size_t pointer_start_offset = *typestring_offset; size_t pointer_start_offset = *typestring_offset;
int has_pointer = 0; int has_pointer = 0;
...@@ -866,7 +871,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, ...@@ -866,7 +871,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
{ {
/* varying array */ /* varying array */
size_t element_size = type_memsize(type, 0, NULL); size_t element_size = type_memsize(type, 0, NULL);
size_t elements = array->cval; size_t elements = dim->cval;
size_t total_size = element_size * elements; size_t total_size = element_size * elements;
if (total_size < USHRT_MAX) if (total_size < USHRT_MAX)
...@@ -930,7 +935,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, ...@@ -930,7 +935,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
*typestring_offset += write_conf_or_var_desc(file, current_func, *typestring_offset += write_conf_or_var_desc(file, current_func,
current_structure, current_structure,
size_is ? size_is : array); size_is ? size_is : dim);
if (has_pointer) if (has_pointer)
{ {
...@@ -963,7 +968,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, ...@@ -963,7 +968,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
*typestring_offset += write_conf_or_var_desc(file, current_func, *typestring_offset += write_conf_or_var_desc(file, current_func,
current_structure, current_structure,
size_is ? size_is : array); size_is ? size_is : dim);
*typestring_offset += write_conf_or_var_desc(file, current_func, *typestring_offset += write_conf_or_var_desc(file, current_func,
current_structure, current_structure,
length_is); length_is);
...@@ -1486,7 +1491,7 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje ...@@ -1486,7 +1491,7 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
} }
static unsigned int get_required_buffer_size_type( static unsigned int get_required_buffer_size_type(
const type_t *type, int ptr_level, const expr_t *array, const type_t *type, int ptr_level, const array_dims_t *array,
const char *name, unsigned int *alignment) const char *name, unsigned int *alignment)
{ {
*alignment = 0; *alignment = 0;
...@@ -1770,7 +1775,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func, ...@@ -1770,7 +1775,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
length_is = get_attrp(var->attrs, ATTR_LENGTHIS); length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
size_is = get_attrp(var->attrs, ATTR_SIZEIS); size_is = get_attrp(var->attrs, ATTR_SIZEIS);
has_length = length_is && (length_is->type != EXPR_VOID); has_length = length_is && (length_is->type != EXPR_VOID);
has_size = (size_is && (size_is->type != EXPR_VOID)) || (var->array && !var->array->is_const); has_size = (size_is && (size_is->type != EXPR_VOID)) || (var->array && is_conformant_array(var->array));
pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE); pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (!pointer_type) if (!pointer_type)
...@@ -1797,7 +1802,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func, ...@@ -1797,7 +1802,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
if (is_string_type(var->attrs, var->ptr_level, var->array)) if (is_string_type(var->attrs, var->ptr_level, var->array))
{ {
if (var->array && var->array->is_const) if (var->array && !is_conformant_array(var->array))
print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset); print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset);
else else
{ {
...@@ -1819,10 +1824,11 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func, ...@@ -1819,10 +1824,11 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{ {
const char *array_type; const char *array_type;
if (var->array && NEXT_LINK(var->array)) /* multi-dimensional array */ if (var->array && list_count(var->array) > 1) /* multi-dimensional array */
array_type = "ComplexArray"; array_type = "ComplexArray";
else else
{ {
const expr_t *dim = LIST_ENTRY( list_head( var->array ), expr_t, entry );
if (!has_length && !has_size) if (!has_length && !has_size)
array_type = "FixedArray"; array_type = "FixedArray";
else if (has_length && !has_size) else if (has_length && !has_size)
...@@ -1841,7 +1847,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func, ...@@ -1841,7 +1847,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
if (is_size_needed_for_phase(phase) && phase != PHASE_FREE) if (is_size_needed_for_phase(phase) && phase != PHASE_FREE)
{ {
print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
write_expr(file, size_is ? size_is : var->array, 1); write_expr(file, size_is ? size_is : dim, 1);
fprintf(file, ";\n\n"); fprintf(file, ";\n\n");
} }
array_type = "ConformantArray"; array_type = "ConformantArray";
...@@ -1851,7 +1857,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func, ...@@ -1851,7 +1857,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
if (is_size_needed_for_phase(phase)) if (is_size_needed_for_phase(phase))
{ {
print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)"); print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
write_expr(file, size_is ? size_is : var->array, 1); write_expr(file, size_is ? size_is : dim, 1);
fprintf(file, ";\n"); fprintf(file, ";\n");
print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */ print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)"); print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
......
...@@ -48,26 +48,10 @@ typedef struct _typelib_t typelib_t; ...@@ -48,26 +48,10 @@ typedef struct _typelib_t typelib_t;
typedef struct list attr_list_t; typedef struct list attr_list_t;
typedef struct list func_list_t; typedef struct list func_list_t;
typedef struct list expr_list_t;
typedef struct list var_list_t; typedef struct list var_list_t;
typedef struct list ifref_list_t; typedef struct list ifref_list_t;
typedef struct list array_dims_t;
#define DECL_LINK(type) \
type *l_next; \
type *l_prev
#define LINK(x,y) do { x->l_next = y; x->l_prev = NULL; if (y) y->l_prev = x; } while (0)
#define INIT_LINK(x) do { x->l_next = NULL; x->l_prev = NULL; } while (0)
#define NEXT_LINK(x) ((x)->l_next)
#define PREV_LINK(x) ((x)->l_prev)
#define END_OF_LIST(list) \
do { \
if (list) { \
while (NEXT_LINK(list)) \
list = NEXT_LINK(list); \
} \
} while(0)
enum attr_type enum attr_type
{ {
...@@ -201,7 +185,7 @@ struct _expr_t { ...@@ -201,7 +185,7 @@ struct _expr_t {
int is_const; int is_const;
long cval; long cval;
/* parser-internal */ /* parser-internal */
DECL_LINK(expr_t); struct list entry;
}; };
struct _type_t { struct _type_t {
...@@ -217,8 +201,6 @@ struct _type_t { ...@@ -217,8 +201,6 @@ struct _type_t {
int ignore, is_const, sign; int ignore, is_const, sign;
int defined, written, user_types_registered; int defined, written, user_types_registered;
int typelib_idx; int typelib_idx;
/* parser-internal */
DECL_LINK(type_t);
}; };
struct _typeref_t { struct _typeref_t {
...@@ -230,7 +212,7 @@ struct _typeref_t { ...@@ -230,7 +212,7 @@ struct _typeref_t {
struct _var_t { struct _var_t {
char *name; char *name;
int ptr_level; int ptr_level;
expr_t *array; array_dims_t *array;
type_t *type; type_t *type;
var_list_t *args; /* for function pointers */ var_list_t *args; /* for function pointers */
const char *tname; const char *tname;
......
...@@ -1104,15 +1104,11 @@ static int encode_var( ...@@ -1104,15 +1104,11 @@ static int encode_var(
} }
if(var->array) { if(var->array) {
expr_t *dim = var->array; expr_t *dim;
expr_t *array_save; array_dims_t *array_save;
int num_dims = 1, elements = 1, arrayoffset; int num_dims = list_count( var->array ), elements = 1, arrayoffset;
int *arraydata; int *arraydata;
while(NEXT_LINK(dim)) {
dim = NEXT_LINK(dim);
num_dims++;
}
chat("array with %d dimensions\n", num_dims); chat("array with %d dimensions\n", num_dims);
array_save = var->array; array_save = var->array;
var->array = NULL; var->array = NULL;
...@@ -1126,12 +1122,12 @@ static int encode_var( ...@@ -1126,12 +1122,12 @@ static int encode_var(
arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16); arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16);
arraydata += 2; arraydata += 2;
while(dim) { LIST_FOR_EACH_ENTRY( dim, var->array, expr_t, entry )
{
arraydata[0] = dim->cval; arraydata[0] = dim->cval;
arraydata[1] = 0; arraydata[1] = 0;
arraydata += 2; arraydata += 2;
elements *= dim->cval; elements *= dim->cval;
dim = PREV_LINK(dim);
} }
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);
......
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