Robert Shearman : widl: Arrays.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Jan 24 06:45:02 CST 2006
Module: wine
Branch: refs/heads/master
Commit: d07589e32f767f3904b129aedc24ba653266ca5e
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=d07589e32f767f3904b129aedc24ba653266ca5e
Author: Robert Shearman <rob at codeweavers.com>
Date: Tue Jan 24 11:07:13 2006 +0100
widl: Arrays.
Write out type format strings for arrays, except for the missing
generic functionality of conformance and variance descriptors.
---
tools/widl/typegen.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 206 insertions(+), 3 deletions(-)
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 0c8a3b0..f334d73 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -31,6 +31,7 @@
#include <assert.h>
#include <ctype.h>
#include <signal.h>
+#include <limits.h>
#include "widl.h"
#include "utils.h"
@@ -211,6 +212,75 @@ void write_procformatstring(FILE *file,
print_file(file, indent, "\n");
}
+static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array);
+
+static size_t fields_memsize(const var_t *v)
+{
+ size_t size = 0;
+ const var_t *first = v;
+ if (!v) return 0;
+ while (NEXT_LINK(v)) v = NEXT_LINK(v);
+ while (v) {
+ size += type_memsize(v->type, v->ptr_level, v->array);
+ if (v == first) break;
+ v = PREV_LINK(v);
+ }
+ return size;
+}
+
+static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array)
+{
+ size_t size = 0;
+
+ if (ptr_level)
+ return sizeof(void *);
+
+ switch (t->type)
+ {
+ case RPC_FC_BYTE:
+ case RPC_FC_CHAR:
+ case RPC_FC_USMALL:
+ case RPC_FC_SMALL:
+ size = 1;
+ break;
+ case RPC_FC_WCHAR:
+ case RPC_FC_USHORT:
+ case RPC_FC_SHORT:
+ case RPC_FC_ENUM16:
+ size = 2;
+ break;
+ case RPC_FC_ULONG:
+ case RPC_FC_LONG:
+ case RPC_FC_ERROR_STATUS_T:
+ case RPC_FC_ENUM32:
+ case RPC_FC_FLOAT:
+ size = 4;
+ break;
+ case RPC_FC_HYPER:
+ case RPC_FC_DOUBLE:
+ size = 8;
+ break;
+ case RPC_FC_STRUCT:
+ case RPC_FC_CVSTRUCT:
+ case RPC_FC_CPSTRUCT:
+ case RPC_FC_CSTRUCT:
+ case RPC_FC_PSTRUCT:
+ case RPC_FC_BOGUS_STRUCT:
+ case RPC_FC_ENCAPSULATED_UNION:
+ case RPC_FC_NON_ENCAPSULATED_UNION:
+ size = fields_memsize(t->fields);
+ break;
+ default:
+ error("type_memsize: Unknown type %d", t->type);
+ size = 0;
+ }
+
+ if (array && array->is_const)
+ size *= array->cval;
+
+ return size;
+}
+
static size_t write_string_tfs(FILE *file, const attr_t *attr,
const type_t *type, const expr_t *array,
const char *name)
@@ -219,12 +289,145 @@ static size_t write_string_tfs(FILE *fil
return 0;
}
-static size_t write_array_tfs(FILE *file, const attr_t *attr,
+static size_t write_array_tfs(FILE *file, const attr_t *attrs,
const type_t *type, const expr_t *array,
const char *name)
{
- error("write_array_tfs: Unimplemented. name: %s\n", name);
- return 0;
+ 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;
+
+ /* FIXME: need to analyse type for pointers */
+
+ if (NEXT_LINK(array)) /* multi-dimensional array */
+ {
+ error("write_array_tfs: Multi-dimensional arrays not implemented yet (param %s)\n", name);
+ return 0;
+ }
+ else
+ {
+ if (!has_length && !has_size)
+ {
+ /* fixed array */
+ size_t typestring_size;
+ size_t size = type_memsize(type, 0, array);
+ if (size < USHRT_MAX)
+ {
+ print_file(file, 2, "0x%x, /* FC_SMFARRAY */\n", RPC_FC_SMFARRAY);
+ /* alignment */
+ print_file(file, 2, "0x%x, /* 0 */\n", 0);
+ /* size */
+ print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", size, size);
+ typestring_size = 4;
+ }
+ else
+ {
+ print_file(file, 2, "0x%x, /* FC_LGFARRAY */\n", RPC_FC_LGFARRAY);
+ /* alignment */
+ print_file(file, 2, "0x%x, /* 0 */\n", 0);
+ /* size */
+ print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", size, size);
+ typestring_size = 6;
+ }
+
+ /* FIXME: write out pointer descriptor if necessary */
+
+ print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+ print_file(file, 2, "FC_END,\n");
+ typestring_size += 2;
+
+ return typestring_size;
+ }
+ else if (has_length && !has_size)
+ {
+ /* varying array */
+ size_t typestring_size;
+ size_t element_size = type_memsize(type, 0, NULL);
+ size_t elements = array->cval;
+ size_t total_size = element_size * elements;
+
+ if (total_size < USHRT_MAX)
+ {
+ print_file(file, 2, "0x%x, /* FC_SMVARRAY */\n", RPC_FC_SMVARRAY);
+ /* alignment */
+ print_file(file, 2, "0x%x, /* 0 */\n", 0);
+ /* total size */
+ print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", total_size, total_size);
+ /* number of elements */
+ print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", elements, elements);
+ typestring_size = 6;
+ }
+ else
+ {
+ print_file(file, 2, "0x%x, /* FC_LGVARRAY */\n", RPC_FC_LGVARRAY);
+ /* alignment */
+ print_file(file, 2, "0x%x, /* 0 */\n", 0);
+ /* total size */
+ print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", total_size, total_size);
+ /* number of elements */
+ print_file(file, 2, "NdrFcLong(0x%x), /* %d */\n", elements, elements);
+ typestring_size = 10;
+ }
+ /* element size */
+ print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
+ typestring_size += 2;
+
+ /* FIXME: write out variance descriptor */
+ /* FIXME: write out pointer descriptor if necessary */
+
+ print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+ print_file(file, 2, "FC_END,\n");
+ typestring_size += 2;
+
+ return typestring_size;
+ }
+ else if (!has_length && has_size)
+ {
+ /* conformant array */
+ size_t typestring_size;
+ size_t element_size = type_memsize(type, 0, NULL);
+
+ print_file(file, 2, "0x%x, /* FC_CARRAY */\n", RPC_FC_CARRAY);
+ /* alignment */
+ print_file(file, 2, "0x%x, /* 0 */\n", 0);
+ /* element size */
+ print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
+ typestring_size = 4;
+
+ /* FIXME: write out conformance descriptor */
+ /* FIXME: write out pointer descriptor if necessary */
+
+ print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+ print_file(file, 2, "FC_END,\n");
+ typestring_size += 2;
+
+ return typestring_size;
+ }
+ else
+ {
+ /* conformant varying array */
+ size_t typestring_size;
+ size_t element_size = type_memsize(type, 0, NULL);
+
+ print_file(file, 2, "0x%x, /* FC_CARRAY */\n", RPC_FC_CARRAY);
+ /* alignment */
+ print_file(file, 2, "0x%x, /* 0 */\n", 0);
+ /* element size */
+ print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
+ typestring_size = 4;
+
+ /* FIXME: write out conformance descriptor */
+ /* FIXME: write out variance descriptor */
+ /* FIXME: write out pointer descriptor if necessary */
+
+ print_file(file, 2, "0x0, /* FIXME: write out conversion data */\n");
+ print_file(file, 2, "FC_END,\n");
+ typestring_size += 2;
+
+ return typestring_size;
+ }
+ }
}
static size_t write_typeformatstring_var(FILE *file, int indent,
More information about the wine-cvs
mailing list