widl: Write some structures to the type format string on the fly.

This commit is contained in:
Dan Hipschman 2007-05-15 17:48:20 -07:00 committed by Alexandre Julliard
parent 217fc9c0f3
commit 52ca3ebada
3 changed files with 106 additions and 84 deletions

View File

@ -132,6 +132,12 @@ s_dot_pvectors(pvectors_t *p)
return p->pu->x * (*p->pv)->x + p->pu->y * (*p->pv)->y + p->pu->z * (*p->pv)->z; return p->pu->x * (*p->pv)->x + p->pu->y * (*p->pv)->y + p->pu->z * (*p->pv)->z;
} }
int
s_sum_sp(sp_t *sp)
{
return sp->x + sp->s->x;
}
void void
s_stop(void) s_stop(void)
{ {
@ -175,6 +181,8 @@ basic_tests(void)
static vector_t a = {1, 3, 7}; static vector_t a = {1, 3, 7};
static vector_t vec1 = {4, -2, 1}, vec2 = {-5, 2, 3}, *pvec2 = &vec2; static vector_t vec1 = {4, -2, 1}, vec2 = {-5, 2, 3}, *pvec2 = &vec2;
static pvectors_t pvecs = {&vec1, &pvec2}; static pvectors_t pvecs = {&vec1, &pvec2};
static sp_inner_t spi = {42};
static sp_t sp = {-13, &spi};
pints_t pints; pints_t pints;
ptypes_t ptypes; ptypes_t ptypes;
int i1, i2, i3, *pi2, *pi3, **ppi3; int i1, i2, i3, *pi2, *pi3, **ppi3;
@ -241,6 +249,7 @@ basic_tests(void)
ok(dot_pvectors(&pvecs) == -21, "RPC dot_pvectors\n"); ok(dot_pvectors(&pvecs) == -21, "RPC dot_pvectors\n");
ok(sum_fixed_array(f) == -2, "RPC sum_fixed_array\n"); ok(sum_fixed_array(f) == -2, "RPC sum_fixed_array\n");
ok(sum_sp(&sp) == 29, "RPC sum_sp\n");
} }
static void static void

View File

@ -67,5 +67,19 @@ interface IServer
int pints_sum(pints_t *pints); int pints_sum(pints_t *pints);
double ptypes_sum(ptypes_t *ptypes); double ptypes_sum(ptypes_t *ptypes);
int dot_pvectors(pvectors_t *pvectors); int dot_pvectors(pvectors_t *pvectors);
/* don't use this anywhere except in sp_t */
typedef struct
{
int x;
} sp_inner_t;
typedef struct
{
int x;
sp_inner_t *s;
} sp_t;
int sum_sp(sp_t *sp);
void stop(void); void stop(void);
} }

View File

@ -61,7 +61,8 @@ struct expr_eval_routine
static size_t type_memsize(const type_t *t, const array_dims_t *array, unsigned int *align); static size_t type_memsize(const type_t *t, const array_dims_t *array, unsigned int *align);
static size_t fields_memsize(const var_list_t *fields, unsigned int *align); static size_t fields_memsize(const var_list_t *fields, unsigned int *align);
static size_t write_struct_tfs(FILE *file, type_t *type, const char *name,
unsigned int *typestring_offset);
const char *string_of_type(unsigned char type) const char *string_of_type(unsigned char type)
{ {
switch (type) switch (type)
@ -92,6 +93,22 @@ const char *string_of_type(unsigned char type)
} }
} }
static int is_struct(unsigned char type)
{
switch (type)
{
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
return 1;
default:
return 0;
}
}
static int compare_expr(const expr_t *a, const expr_t *b) static int compare_expr(const expr_t *a, const expr_t *b)
{ {
int ret; int ret;
@ -691,83 +708,85 @@ static size_t write_simple_pointer(FILE *file, const type_t *type)
return 4; return 4;
} }
static size_t write_pointer_tfs(FILE *file, type_t *type, size_t *typestring_offset)
{
size_t offset = *typestring_offset;
print_file(file, 0, "/* %d */\n", offset);
type->typestring_offset = offset;
if (type->ref->typestring_offset)
*typestring_offset += write_nonsimple_pointer(file, type, offset);
else if (is_base_type(type->ref->type))
*typestring_offset += write_simple_pointer(file, type);
return offset;
}
static int has_known_tfs(const type_t *type)
{
return type->typestring_offset || is_base_type(type->type);
}
static int write_pointers(FILE *file, const attr_list_t *attrs, static int write_pointers(FILE *file, const attr_list_t *attrs,
type_t *type, type_t *type, const char *name,
const array_dims_t *array, int level, const array_dims_t *array, int level,
unsigned int *typestring_offset) unsigned int *typestring_offset)
{ {
int pointers_written = 0;
const var_t *v; const var_t *v;
/* don't generate a pointer for first-level arrays since we want to /* don't generate a pointer for first-level arrays since we want to
* descend into them to write their pointers, not stop here */ * descend into them to write their pointers, not stop here */
if ((level == 0 || !is_ptr(type)) && is_array_type(attrs, type, array)) if ((level == 0 || !is_ptr(type)) && is_array_type(attrs, type, array))
{ {
return write_pointers(file, NULL, type, NULL, level + 1, typestring_offset); return write_pointers(file, NULL, type, name, NULL, level + 1, typestring_offset);
} }
else if (is_ptr(type))
if (is_ptr(type))
{ {
if (!is_ptr(type->ref) && 1 < level) type_t *ref = type->ref;
if (!has_known_tfs(ref))
{ {
print_file(file, 0, "/* %d */\n", *typestring_offset); if (is_ptr(ref))
if (type->ref->typestring_offset)
{ {
type->typestring_offset = *typestring_offset; write_pointers(file, attrs, ref, name, array, level + 1,
*typestring_offset += write_nonsimple_pointer(file, type, *typestring_offset); typestring_offset);
} }
else if (is_base_type(type->ref->type)) else if (is_struct(ref->type))
{ {
type->typestring_offset = *typestring_offset; write_struct_tfs(file, ref, name, typestring_offset);
*typestring_offset += write_simple_pointer(file, type);
} }
else else
error("write_pointers: pointer doesn't point to anything recognizable (0x%02x)\n",
type->ref->type);
}
else
{
write_pointers(file, attrs, type->ref, array, level + 1, typestring_offset);
if (1 < level)
{ {
print_file(file, 0, "/* %d */\n", *typestring_offset); error("write_pointers: type format string unknown for %s (0x%02x)\n",
type->typestring_offset = *typestring_offset; name, ref->type);
*typestring_offset += write_nonsimple_pointer(file, type, *typestring_offset);
} }
} }
/* top-level pointers are handled by write_pointer_description */
if (1 < level)
write_pointer_tfs(file, type, typestring_offset);
return 1; return 1;
} }
else if (is_struct(type->type))
switch (type->type)
{ {
/* note: don't descend into complex structures or unions since these int pointers_written = 0;
* will always be generated as a separate type */ if (type->fields)
case RPC_FC_STRUCT: {
case RPC_FC_CVSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_PSTRUCT:
if (!type->fields) break;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
pointers_written += write_pointers(file, v->attrs, v->type, pointers_written += write_pointers(file, v->attrs, v->type,
v->array, v->name, v->array,
level + 1, level + 1,
typestring_offset); typestring_offset);
}
break; return pointers_written;
default:
/* nothing to do */
break;
} }
else return 0;
return pointers_written;
} }
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, size_t mem_offset, type_t *type, size_t mem_offset,
const array_dims_t *array, int level, const array_dims_t *array, int level,
size_t *typestring_offset) size_t *typestring_offset)
{ {
@ -787,43 +806,23 @@ static size_t write_pointer_description(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", mem_offset, mem_offset); print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", mem_offset, mem_offset);
print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", mem_offset, mem_offset); print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", mem_offset, mem_offset);
*typestring_offset += 6;
if (type->ref->typestring_offset) if (has_known_tfs(type->ref))
{ write_pointer_tfs(file, type, typestring_offset);
*typestring_offset
+= 6 + write_nonsimple_pointer(file, type, 6 + *typestring_offset);
}
else if (is_base_type(type->ref->type))
{
*typestring_offset += 6 + write_simple_pointer(file, type);
}
else else
error("write_pointer_description: unimplemented\n"); error("write_pointer_description: type format string unknown\n");
} }
else else if (level == 0 && is_struct(type->type))
{ {
switch (type->type) if (type->fields)
{ {
/* note: don't descend into complex structures or unions since these
* will always be generated as a separate type */
case RPC_FC_STRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_PSTRUCT:
if (!type->fields) break;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
{ mem_offset
mem_offset += write_pointer_description(file, v->attrs, v->type,
+= write_pointer_description(file, v->attrs, v->type, mem_offset, v->array,
mem_offset, v->array, level + 1,
level + 1, typestring_offset);
typestring_offset);
}
break;
default:
break;
} }
} }
@ -950,7 +949,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
const expr_t *dim = array ? LIST_ENTRY( list_head( array ), expr_t, entry ) : NULL; const expr_t *dim = array ? LIST_ENTRY( list_head( array ), expr_t, entry ) : NULL;
int has_pointer = 0; int has_pointer = 0;
if (write_pointers(file, attrs, type, array, 0, typestring_offset) > 0) if (write_pointers(file, attrs, type, name, array, 0, typestring_offset) > 0)
has_pointer = 1; has_pointer = 1;
start_offset = *typestring_offset; start_offset = *typestring_offset;
@ -1199,11 +1198,11 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
total_size = type_memsize(type, NULL, &align); total_size = type_memsize(type, NULL, &align);
if (total_size > USHRT_MAX) if (total_size > USHRT_MAX)
error("structure size for parameter %s exceeds %d bytes by %d bytes\n", error("structure size for %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX); name, USHRT_MAX, total_size - USHRT_MAX);
if (type->type == RPC_FC_PSTRUCT) if (type->type == RPC_FC_PSTRUCT)
write_pointers(file, NULL, type, NULL, 0, typestring_offset); write_pointers(file, NULL, type, name, NULL, 0, typestring_offset);
start_offset = *typestring_offset; start_offset = *typestring_offset;
type->typestring_offset = start_offset; type->typestring_offset = start_offset;
@ -1235,7 +1234,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
total_size = type_memsize(type, NULL, &align); total_size = type_memsize(type, NULL, &align);
if (total_size > USHRT_MAX) if (total_size > USHRT_MAX)
error("structure size for parameter %s exceeds %d bytes by %d bytes\n", error("structure size for %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX); name, USHRT_MAX, total_size - USHRT_MAX);
array = find_array_or_string_in_struct(type); array = find_array_or_string_in_struct(type);
@ -1246,7 +1245,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
current_structure = NULL; current_structure = NULL;
if (type->type == RPC_FC_CPSTRUCT) if (type->type == RPC_FC_CPSTRUCT)
write_pointers(file, NULL, type, NULL, 0, typestring_offset); write_pointers(file, NULL, type, name, NULL, 0, typestring_offset);
start_offset = *typestring_offset; start_offset = *typestring_offset;
type->typestring_offset = start_offset; type->typestring_offset = start_offset;
@ -1283,7 +1282,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
total_size = type_memsize(type, NULL, &align); total_size = type_memsize(type, NULL, &align);
if (total_size > USHRT_MAX) if (total_size > USHRT_MAX)
error("structure size for parameter %s exceeds %d bytes by %d bytes\n", error("structure size for %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX); name, USHRT_MAX, total_size - USHRT_MAX);
array = find_array_or_string_in_struct(type); array = find_array_or_string_in_struct(type);
@ -1298,7 +1297,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
typestring_offset); typestring_offset);
current_structure = NULL; current_structure = NULL;
has_pointers = write_pointers(file, NULL, type, NULL, 0, typestring_offset); has_pointers = write_pointers(file, NULL, type, name, NULL, 0, typestring_offset);
start_offset = *typestring_offset; start_offset = *typestring_offset;
type->typestring_offset = start_offset; type->typestring_offset = start_offset;
@ -1351,7 +1350,7 @@ static size_t write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int p
print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", print_file(file, 2, "0x%x, 0x%x,\t\t/* %s",
pointer_type, pointer_type,
flags, flags,
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP")); string_of_type(pointer_type));
if (file) if (file)
{ {
if (flags & 0x04) if (flags & 0x04)