widl: Represent arrays with type_t.
This commit is contained in:
parent
f5baddf88a
commit
978b4d4f4e
|
@ -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)
|
||||
{
|
||||
|
@ -335,6 +376,41 @@ pointer_tests(void)
|
|||
free_list(list);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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_array_type(field->attrs, field->type, field->array))
|
||||
{
|
||||
if (field->array && is_conformant_array(field->array))
|
||||
if (is_string_type(field->attrs, field->type))
|
||||
{
|
||||
has_conformance = 1;
|
||||
if (list_next( fields, &field->entry ))
|
||||
has_variance = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array(field->type->ref))
|
||||
return RPC_FC_BOGUS_STRUCT;
|
||||
|
||||
if (is_conformant_array(field->type))
|
||||
{
|
||||
has_conformance = 1;
|
||||
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);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue