From 52ca3ebadac7eb1132fce34e750d4d96b48e052c Mon Sep 17 00:00:00 2001 From: Dan Hipschman Date: Tue, 15 May 2007 17:48:20 -0700 Subject: [PATCH] widl: Write some structures to the type format string on the fly. --- dlls/rpcrt4/tests/server.c | 9 ++ dlls/rpcrt4/tests/server.idl | 14 +++ tools/widl/typegen.c | 167 +++++++++++++++++------------------ 3 files changed, 106 insertions(+), 84 deletions(-) diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 8fd107b1e95..ae84a41a265 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -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; } +int +s_sum_sp(sp_t *sp) +{ + return sp->x + sp->s->x; +} + void s_stop(void) { @@ -175,6 +181,8 @@ basic_tests(void) static vector_t a = {1, 3, 7}; static vector_t vec1 = {4, -2, 1}, vec2 = {-5, 2, 3}, *pvec2 = &vec2; static pvectors_t pvecs = {&vec1, &pvec2}; + static sp_inner_t spi = {42}; + static sp_t sp = {-13, &spi}; pints_t pints; ptypes_t ptypes; int i1, i2, i3, *pi2, *pi3, **ppi3; @@ -241,6 +249,7 @@ basic_tests(void) ok(dot_pvectors(&pvecs) == -21, "RPC dot_pvectors\n"); ok(sum_fixed_array(f) == -2, "RPC sum_fixed_array\n"); + ok(sum_sp(&sp) == 29, "RPC sum_sp\n"); } static void diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index e087f1e7812..2d671aba941 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -67,5 +67,19 @@ interface IServer int pints_sum(pints_t *pints); double ptypes_sum(ptypes_t *ptypes); 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); } diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index caff4307f46..3d616159864 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -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 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) { 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) { int ret; @@ -691,83 +708,85 @@ static size_t write_simple_pointer(FILE *file, const type_t *type) 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, - type_t *type, + type_t *type, const char *name, const array_dims_t *array, int level, unsigned int *typestring_offset) { - int pointers_written = 0; const var_t *v; /* don't generate a pointer for first-level arrays since we want to * descend into them to write their pointers, not stop here */ 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); } - - if (is_ptr(type)) + else 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 (type->ref->typestring_offset) + if (is_ptr(ref)) { - type->typestring_offset = *typestring_offset; - *typestring_offset += write_nonsimple_pointer(file, type, *typestring_offset); + write_pointers(file, attrs, ref, name, array, level + 1, + typestring_offset); } - else if (is_base_type(type->ref->type)) + else if (is_struct(ref->type)) { - type->typestring_offset = *typestring_offset; - *typestring_offset += write_simple_pointer(file, type); + write_struct_tfs(file, ref, name, typestring_offset); } 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); - type->typestring_offset = *typestring_offset; - *typestring_offset += write_nonsimple_pointer(file, type, *typestring_offset); + error("write_pointers: type format string unknown for %s (0x%02x)\n", + name, ref->type); } } + /* top-level pointers are handled by write_pointer_description */ + if (1 < level) + write_pointer_tfs(file, type, typestring_offset); + return 1; } - - switch (type->type) + else if (is_struct(type->type)) { - /* 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; + int pointers_written = 0; + if (type->fields) + { LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) pointers_written += write_pointers(file, v->attrs, v->type, - v->array, + v->name, v->array, level + 1, typestring_offset); - - break; - - default: - /* nothing to do */ - break; + } + return pointers_written; } - - return pointers_written; + else return 0; } 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, 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, "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) - { - *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); - } + if (has_known_tfs(type->ref)) + write_pointer_tfs(file, type, typestring_offset); 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 ) - { - mem_offset - += write_pointer_description(file, v->attrs, v->type, - mem_offset, v->array, - level + 1, - typestring_offset); - } - break; - - default: - break; + mem_offset + += write_pointer_description(file, v->attrs, v->type, + mem_offset, v->array, + level + 1, + typestring_offset); } } @@ -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; 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; 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); 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); 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; 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); 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); 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; 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; 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); 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); 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); 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; 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", pointer_type, 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 (flags & 0x04)