widl: Convert expression lists to standard Wine lists.

Add a specific type for array dimensions.
This commit is contained in:
Alexandre Julliard 2007-01-22 14:31:40 +01:00
parent eed74e4e4a
commit 43ac6ed995
6 changed files with 104 additions and 88 deletions

View File

@ -77,6 +77,14 @@ int is_void(const type_t *t, const var_t *v)
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)
{
if (!uuid) return;
@ -112,19 +120,20 @@ const char* get_name(const var_t *v)
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;
while (NEXT_LINK(v)) v = NEXT_LINK(v);
expr_t *v;
if (!dims) return;
fprintf(h, "[");
while (v) {
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 (PREV_LINK(v))
if (list_next( dims, &v->entry ))
fprintf(h, ", ");
v = PREV_LINK(v);
}
fprintf(h, "]");
}

View File

@ -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 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_conformant_array( const array_dims_t *array );
extern void write_name(FILE *h, 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);
@ -32,7 +33,7 @@ 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);
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_interface(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);
extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
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) &&
((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)) ||
(ptr_level == 0 && array));

View File

@ -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_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 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 *uniq_tref(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_t *make_ifref(type_t *iface);
static var_list_t *append_var(var_list_t *list, var_t *var);
@ -121,6 +123,8 @@ static void check_arg(var_t *arg);
attr_t *attr;
attr_list_t *attr_list;
expr_t *expr;
expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type;
typeref_t *tref;
var_t *var;
@ -219,8 +223,9 @@ static void check_arg(var_t *arg);
%type <attr> attribute
%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> array array_list
%type <expr> m_expr expr expr_const
%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> dispinterface dispinterfacehdr dispinterfacedef
%type <type> module modulehdr moduledef
@ -357,12 +362,12 @@ arg: attributes type pident array { $$ = $3;
array: { $$ = NULL; }
| '[' 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 ',' expr { LINK($3, $1); $$ = $3; }
| array_list ']' '[' expr { LINK($4, $1); $$ = $4; }
array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); }
| array_list ',' expr { $$ = append_array( $1, $3 ); }
| array_list ']' '[' expr { $$ = append_array( $1, $4 ); }
;
m_attributes: { $$ = NULL; }
@ -434,7 +439,9 @@ attribute: { $$ = NULL; }
| tPROPPUT { $$ = make_attr(ATTR_PROPPUT); }
| tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); }
| 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); }
| tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); }
| tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); }
@ -513,8 +520,8 @@ enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM
}
;
m_exprs: m_expr
| m_exprs ',' m_expr { LINK($3, $1); $$ = $3; }
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
| m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); }
;
/*
@ -553,8 +560,8 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); }
| '(' expr ')' { $$ = $2; }
;
expr_list_const: expr_const
| expr_list_const ',' expr_const { LINK($3, $1); $$ = $3; }
expr_list_const: expr_const { $$ = append_expr( NULL, $1 ); }
| expr_list_const ',' expr_const { $$ = append_expr( $1, $3 ); }
;
expr_const: expr { $$ = $1;
@ -951,7 +958,6 @@ static expr_t *make_expr(enum expr_type type)
e->ref = NULL;
e->u.lval = 0;
e->is_const = FALSE;
INIT_LINK(e);
return e;
}
@ -962,7 +968,6 @@ static expr_t *make_exprl(enum expr_type type, long val)
e->ref = NULL;
e->u.lval = val;
e->is_const = FALSE;
INIT_LINK(e);
/* check for numeric constant */
if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) {
/* make sure true/false value is valid */
@ -981,7 +986,6 @@ static expr_t *make_exprs(enum expr_type type, char *val)
e->ref = NULL;
e->u.sval = val;
e->is_const = FALSE;
INIT_LINK(e);
/* check for predefined constants */
if (type == EXPR_IDENTIFIER) {
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)
e->ref = expr;
e->u.tref = tref;
e->is_const = FALSE;
INIT_LINK(e);
/* check for cast of constant expression */
if (type == EXPR_SIZEOF) {
switch (tref->ref->type) {
@ -1049,7 +1052,6 @@ static expr_t *make_expr1(enum expr_type type, expr_t *expr)
e->ref = expr;
e->u.lval = 0;
e->is_const = FALSE;
INIT_LINK(e);
/* check for compile-time optimization */
if (expr->is_const) {
e->is_const = TRUE;
@ -1076,7 +1078,6 @@ static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
e->ref = expr1;
e->u.ext = expr2;
e->is_const = FALSE;
INIT_LINK(e);
/* check for compile-time optimization */
if (expr1->is_const && expr2->is_const) {
e->is_const = TRUE;
@ -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->ext2 = expr3;
e->is_const = FALSE;
INIT_LINK(e);
/* check for compile-time optimization */
if (expr1->is_const && expr2->is_const && expr3->is_const) {
e->is_const = TRUE;
@ -1138,6 +1138,30 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp
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)
{
type_t *t = xmalloc(sizeof(type_t));
@ -1157,7 +1181,6 @@ static type_t *make_type(unsigned char type, type_t *ref)
t->written = FALSE;
t->user_types_registered = FALSE;
t->typelib_idx = -1;
INIT_LINK(t);
return t;
}
@ -1198,7 +1221,7 @@ static type_t *type_ref(typeref_t *ref)
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->tname = ref->name;
@ -1280,7 +1303,6 @@ static type_t *make_class(char *name)
type_t *c = make_type(0, NULL);
c->name = name;
c->kind = TKIND_COCLASS;
INIT_LINK(c);
return c;
}
@ -1488,7 +1510,7 @@ static int get_struct_type(var_list_t *fields)
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;
if (list_next( fields, &field->entry ))

View File

@ -59,7 +59,7 @@ struct expr_eval_routine
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 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)
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;
@ -586,10 +586,12 @@ static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array)
if (array)
{
if (array->is_const)
size *= array->cval;
else
size = 0;
expr_t *dim;
LIST_FOR_EACH_ENTRY( dim, array, expr_t, entry )
if (dim->is_const)
size *= dim->cval;
else
size = 0;
}
return size;
@ -602,7 +604,7 @@ size_t get_type_memsize(const type_t *type)
static int write_pointers(FILE *file, const attr_list_t *attrs,
const type_t *type, int ptr_level,
const expr_t *array, int level,
const array_dims_t *array, int level,
unsigned int *typestring_offset)
{
int pointers_written = 0;
@ -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,
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 size = 0;
@ -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,
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 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,
*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",
name, USHRT_MAX, array->cval - USHRT_MAX);
name, USHRT_MAX, dim->cval - USHRT_MAX);
if (rtype == RPC_FC_CHAR)
WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset);
@ -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);
*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;
return start_offset;
@ -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,
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 expr_t *length_is = get_attrp(attrs, ATTR_LENGTHIS);
const expr_t *size_is = get_attrp(attrs, ATTR_SIZEIS);
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;
int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
if (!pointer_type)
@ -807,13 +811,14 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "NdrFcShort(0x2),\n");
*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);
return 0;
}
else
{
const expr_t *dim = LIST_ENTRY( list_head( array ), expr_t, entry );
size_t pointer_start_offset = *typestring_offset;
int has_pointer = 0;
@ -866,7 +871,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
{
/* varying array */
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;
if (total_size < USHRT_MAX)
@ -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,
current_structure,
size_is ? size_is : array);
size_is ? size_is : dim);
if (has_pointer)
{
@ -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,
current_structure,
size_is ? size_is : array);
size_is ? size_is : dim);
*typestring_offset += write_conf_or_var_desc(file, current_func,
current_structure,
length_is);
@ -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(
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)
{
*alignment = 0;
@ -1770,7 +1775,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
size_is = get_attrp(var->attrs, ATTR_SIZEIS);
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);
if (!pointer_type)
@ -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 (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);
else
{
@ -1819,10 +1824,11 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{
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";
else
{
const expr_t *dim = LIST_ENTRY( list_head( var->array ), expr_t, entry );
if (!has_length && !has_size)
array_type = "FixedArray";
else if (has_length && !has_size)
@ -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)
{
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");
}
array_type = "ConformantArray";
@ -1851,7 +1857,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
if (is_size_needed_for_phase(phase))
{
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");
print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");

View File

@ -48,26 +48,10 @@ typedef struct _typelib_t typelib_t;
typedef struct list attr_list_t;
typedef struct list func_list_t;
typedef struct list expr_list_t;
typedef struct list var_list_t;
typedef struct list ifref_list_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)
typedef struct list array_dims_t;
enum attr_type
{
@ -201,7 +185,7 @@ struct _expr_t {
int is_const;
long cval;
/* parser-internal */
DECL_LINK(expr_t);
struct list entry;
};
struct _type_t {
@ -217,8 +201,6 @@ struct _type_t {
int ignore, is_const, sign;
int defined, written, user_types_registered;
int typelib_idx;
/* parser-internal */
DECL_LINK(type_t);
};
struct _typeref_t {
@ -230,7 +212,7 @@ struct _typeref_t {
struct _var_t {
char *name;
int ptr_level;
expr_t *array;
array_dims_t *array;
type_t *type;
var_list_t *args; /* for function pointers */
const char *tname;

View File

@ -1104,15 +1104,11 @@ static int encode_var(
}
if(var->array) {
expr_t *dim = var->array;
expr_t *array_save;
int num_dims = 1, elements = 1, arrayoffset;
expr_t *dim;
array_dims_t *array_save;
int num_dims = list_count( var->array ), elements = 1, arrayoffset;
int *arraydata;
while(NEXT_LINK(dim)) {
dim = NEXT_LINK(dim);
num_dims++;
}
chat("array with %d dimensions\n", num_dims);
array_save = var->array;
var->array = NULL;
@ -1126,12 +1122,12 @@ static int encode_var(
arraydata[1] |= ((num_dims * 2 * sizeof(long)) << 16);
arraydata += 2;
while(dim) {
LIST_FOR_EACH_ENTRY( dim, var->array, expr_t, entry )
{
arraydata[0] = dim->cval;
arraydata[1] = 0;
arraydata += 2;
elements *= dim->cval;
dim = PREV_LINK(dim);
}
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);