Dan Hipschman : widl:
Add more complete pointer handling to write_typeformatstring_var.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Sep 8 05:15:31 CDT 2006
Module: wine
Branch: master
Commit: 6ff8ae327f783252407192c5ac431ec13f8e0db8
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=6ff8ae327f783252407192c5ac431ec13f8e0db8
Author: Dan Hipschman <dsh at linux.ucla.edu>
Date: Thu Sep 7 16:57:16 2006 -0700
widl: Add more complete pointer handling to write_typeformatstring_var.
---
tools/widl/typegen.c | 108 ++++++++++++++++++++++++++++++++++++++++--------
tools/widl/typelib.c | 2 -
tools/widl/widltypes.h | 2 -
3 files changed, 93 insertions(+), 19 deletions(-)
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index b46f0b1..84a2958 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -721,9 +721,17 @@ static size_t write_string_tfs(FILE *fil
int has_size = size_is && (size_is->type != EXPR_VOID);
size_t start_offset = *typestring_offset;
unsigned char flags = 0;
- int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
+ int pointer_type;
unsigned char rtype;
+ if (is_ptr(type))
+ {
+ pointer_type = type->type;
+ type = type->ref;
+ }
+ else
+ pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
+
if (!pointer_type)
pointer_type = RPC_FC_RP;
@@ -1226,12 +1234,11 @@ static size_t write_struct_tfs(FILE *fil
}
}
-static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, size_t offset, unsigned int *typeformat_offset)
+static void write_pointer_only_tfs(FILE *file, const attr_t *attrs, int pointer_type,
+ unsigned char flags, size_t offset,
+ unsigned int *typeformat_offset)
{
int in_attr, out_attr;
- unsigned char flags = 0;
- int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
- if (!pointer_type) pointer_type = RPC_FC_RP;
in_attr = is_attr(attrs, ATTR_IN);
out_attr = is_attr(attrs, ATTR_OUT);
if (!in_attr && !out_attr) in_attr = 1;
@@ -1239,11 +1246,19 @@ static void write_pointer_only_tfs(FILE
if (out_attr && !in_attr && pointer_type == RPC_FC_RP)
flags |= 0x04;
- print_file(file, 2, "0x%x, 0x%x,\t\t/* %s%s */\n",
+ 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"),
- (flags & 0x04) ? " [allocated_on_stack]" : "");
+ pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"));
+ if (file)
+ {
+ if (flags & 0x04)
+ fprintf(file, " [allocated_on_stack]");
+ if (flags & 0x10)
+ fprintf(file, " [pointer_deref]");
+ fprintf(file, " */\n");
+ }
+
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", offset, offset);
*typeformat_offset += 4;
}
@@ -1281,19 +1296,71 @@ static size_t write_ip_tfs(FILE *file, c
return start_offset;
}
+static int get_ptr_attr(const type_t *t, int def_type)
+{
+ while (TRUE)
+ {
+ int ptr_attr = get_attrv(t->attrs, ATTR_POINTERTYPE);
+ if (ptr_attr)
+ return ptr_attr;
+ if (t->kind != TKIND_ALIAS)
+ return def_type;
+ t = t->orig;
+ }
+}
+
static size_t write_typeformatstring_var(FILE *file, int indent,
const var_t *var, unsigned int *typeformat_offset)
{
const type_t *type = var->type;
- int ptr_level = var->ptr_level;
+ int var_ptrs = var->ptr_level, type_ptrs = 0;
+ int is_str = is_attr(var->attrs, ATTR_STRING);
chat("write_typeformatstring_var: %s\n", var->name);
while (TRUE)
{
+ is_str = is_str || is_attr(type->attrs, ATTR_STRING);
+ if (type->kind == TKIND_ALIAS)
+ type = type->orig;
+ else if (is_ptr(type))
+ {
+ ++type_ptrs;
+ type = type->ref;
+ }
+ else
+ {
+ type = var->type;
+ break;
+ }
+ }
+
+ while (TRUE)
+ {
+ int ptr_level = var_ptrs + type_ptrs;
+ int pointer_type = 0;
+
chat("write_typeformatstring: type->type = 0x%x, type->name = %s, ptr_level = %d\n", type->type, type->name, ptr_level);
- if (is_string_type(var->attrs, ptr_level, var->array))
+ /* var attrs only effect the rightmost pointer */
+ if ((0 < var->ptr_level && var_ptrs == var->ptr_level)
+ || (var->ptr_level == 0 && type == var->type))
+ {
+ int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE);
+ if (pointer_attr)
+ {
+ if (! ptr_level)
+ error("'%s': pointer attribute applied to non-pointer type",
+ var->name);
+ pointer_type = pointer_attr;
+ }
+ else
+ pointer_type = RPC_FC_RP;
+ }
+ else /* pointers below other pointers default to unique */
+ pointer_type = var_ptrs ? RPC_FC_UP : get_ptr_attr(type, RPC_FC_UP);
+
+ if (is_str && ptr_level + (var->array != NULL) == 1)
return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
if (is_array_type(var->attrs, ptr_level, var->array))
@@ -1330,16 +1397,15 @@ static size_t write_typeformatstring_var
size_t start_offset = *typeformat_offset;
int in_attr = is_attr(var->attrs, ATTR_IN);
int out_attr = is_attr(var->attrs, ATTR_OUT);
- int pointer_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
- if (!pointer_type) pointer_type = RPC_FC_RP;
+ const type_t *base = is_ptr(type) ? type->ref : type;
- if (type->type == RPC_FC_IP)
+ if (base->type == RPC_FC_IP)
{
- return write_ip_tfs(file, type->attrs, type, type->name, typeformat_offset);
+ return write_ip_tfs(file, base->attrs, base, base->name, typeformat_offset);
}
/* special case for pointers to base types */
- switch (type->type)
+ switch (base->type)
{
#define CASE_BASETYPE(fctype) \
case RPC_##fctype: \
@@ -1377,9 +1443,17 @@ #define CASE_BASETYPE(fctype) \
if (file)
fprintf(file, "/* %2u */\n", *typeformat_offset);
- write_pointer_only_tfs(file, var->attrs, 2, typeformat_offset);
+ write_pointer_only_tfs(file, var->attrs, pointer_type,
+ 1 < ptr_level ? 0x10 : 0,
+ 2, typeformat_offset);
- ptr_level--;
+ if (var_ptrs)
+ --var_ptrs;
+ else
+ {
+ --type_ptrs;
+ type = type->ref;
+ }
}
}
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index ae5cca8..1476e1a 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -73,7 +73,7 @@ type_t *alias(type_t *t, const char *nam
return a;
}
-int is_ptr(type_t *t)
+int is_ptr(const type_t *t)
{
unsigned char c = t->type;
return c == RPC_FC_RP
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 6d51b51..3eb027d 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -295,7 +295,7 @@ void init_types(void);
type_t *duptype(type_t *t, int dupname);
type_t *alias(type_t *t, const char *name);
-int is_ptr(type_t *t);
+int is_ptr(const type_t *t);
int is_var_ptr(var_t *v);
int cant_be_null(var_t *v);
More information about the wine-cvs
mailing list