Robert Shearman : widl: Add architecture for generating pointer
layouts.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Feb 3 12:03:06 CST 2006
Module: wine
Branch: refs/heads/master
Commit: ccf509b4c60841b2ff41ef3476c6c1181cbed0d0
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=ccf509b4c60841b2ff41ef3476c6c1181cbed0d0
Author: Robert Shearman <rob at codeweavers.com>
Date: Fri Feb 3 18:51:17 2006 +0100
widl: Add architecture for generating pointer layouts.
---
tools/widl/typegen.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 144 insertions(+), 7 deletions(-)
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 1c1002e..bd0efde 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -569,6 +569,113 @@ static size_t type_memsize(const type_t
return size;
}
+static int write_pointers(FILE *file, const attr_t *attrs,
+ const type_t *type, int ptr_level,
+ const expr_t *array, int level,
+ size_t *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 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
+ {
+ return write_pointers(file, NULL, type, 0, NULL, level + 1, typestring_offset);
+ }
+
+ if (ptr_level != 0)
+ {
+ /* FIXME: only general algorithm implemented, not the actual writing */
+ error("write_pointers: Writing type format string for pointer is unimplemented\n");
+ return 1;
+ }
+
+ /* FIXME: search through all refs for pointers too */
+ while(type_has_ref(type))
+ type = type->ref;
+
+ switch (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:
+ v = type->fields;
+ if (!v) break;
+ while (NEXT_LINK(v)) v = NEXT_LINK(v);
+ for (; v; v = PREV_LINK(v))
+ pointers_written += write_pointers(file, v->attrs, v->type,
+ v->ptr_level, v->array,
+ level + 1,
+ typestring_offset);
+
+ break;
+
+ default:
+ /* nothing to do */
+ break;
+ }
+
+ return pointers_written;
+}
+
+static size_t write_pointer_description(FILE *file, const attr_t *attrs,
+ const type_t *type, int ptr_level,
+ const expr_t *array, int level,
+ size_t typestring_offset)
+{
+ size_t size = 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 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
+ {
+ return write_pointer_description(file, NULL, type, 0, NULL,
+ level + 1, typestring_offset);
+ }
+
+ if (ptr_level != 0)
+ {
+ /* FIXME: only general algorithm implemented, not the actual writing */
+ error("write_pointer_description: Writing pointer description is unimplemented\n");
+ return 0;
+ }
+
+ /* FIXME: search through all refs for pointers too */
+
+ switch (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:
+ v = type->fields;
+ if (!v) break;
+ while (NEXT_LINK(v)) v = NEXT_LINK(v);
+ for (; v; v = PREV_LINK(v))
+ size += write_pointer_description(file, v->attrs, v->type,
+ v->ptr_level, v->array,
+ level + 1,
+ typestring_offset);
+
+ break;
+
+ default:
+ /* nothing to do */
+ break;
+ }
+
+ return size;
+}
+
static size_t write_string_tfs(FILE *file, const attr_t *attrs,
const type_t *type, const expr_t *array,
const char *name, size_t *typestring_offset)
@@ -635,9 +742,7 @@ static size_t write_array_tfs(FILE *file
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;
- size_t start_offset = *typestring_offset;
-
- /* FIXME: need to analyse type for pointers */
+ size_t start_offset;
if (array && NEXT_LINK(array)) /* multi-dimensional array */
{
@@ -646,6 +751,14 @@ static size_t write_array_tfs(FILE *file
}
else
{
+ size_t pointer_start_offset = *typestring_offset;
+ int has_pointer = 0;
+
+ if (write_pointers(file, attrs, type, 0, array, 0, typestring_offset) > 0)
+ has_pointer = 1;
+
+ start_offset = *typestring_offset;
+
if (!has_length && !has_size)
{
/* fixed array */
@@ -669,7 +782,13 @@ static size_t write_array_tfs(FILE *file
*typestring_offset += 6;
}
- /* FIXME: write out pointer descriptor if necessary */
+ if (has_pointer)
+ {
+ print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
+ print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
+ write_pointer_description(file, attrs, type, 0, array, 0, pointer_start_offset);
+ print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
+ }
print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
print_file(file, 2, "FC_END,\n");
@@ -714,7 +833,13 @@ static size_t write_array_tfs(FILE *file
current_structure,
length_is);
- /* FIXME: write out pointer descriptor if necessary */
+ if (has_pointer)
+ {
+ print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
+ print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
+ write_pointer_description(file, attrs, type, 0, array, 0, pointer_start_offset);
+ print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
+ }
print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
print_file(file, 2, "FC_END,\n");
@@ -738,7 +863,13 @@ static size_t write_array_tfs(FILE *file
current_structure,
size_is ? size_is : array);
- /* FIXME: write out pointer descriptor if necessary */
+ if (has_pointer)
+ {
+ print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
+ print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
+ write_pointer_description(file, attrs, type, 0, array, 0, pointer_start_offset);
+ print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
+ }
print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
print_file(file, 2, "FC_END,\n");
@@ -765,7 +896,13 @@ static size_t write_array_tfs(FILE *file
current_structure,
length_is);
- /* FIXME: write out pointer descriptor if necessary */
+ if (has_pointer)
+ {
+ print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
+ print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
+ write_pointer_description(file, attrs, type, 0, array, 0, pointer_start_offset);
+ print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
+ }
print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
print_file(file, 2, "FC_END,\n");
More information about the wine-cvs
mailing list