Patches taken from !6207, no-op but should make the `write_type` helpers more readable and flexible.
-- v2: widl: Move some type name construction out of write_type_left. widl: Remove unnecessary recursion for TYPE_BITFIELD. widl: Introduce a new append_basic_type helper. widl: Wrap strappend parameters in a new struct strbuf.
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 19 ---- tools/widl/typetree.c | 235 +++++++++++++++++++++-------------------- tools/widl/typetree.h | 5 + tools/widl/utils.c | 38 +++---- tools/widl/utils.h | 10 +- tools/widl/widltypes.h | 4 - 6 files changed, 149 insertions(+), 162 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 81a789a74df..5409c79839c 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -66,25 +66,6 @@ static void write_line(FILE *f, int delta, const char *fmt, ...) fprintf(f, "\n"); }
-static char *format_parameterized_type_args(const type_t *type, const char *prefix, const char *suffix) -{ - typeref_list_t *params; - typeref_t *ref; - size_t len = 0, pos = 0; - char *buf = NULL; - - params = type->details.parameterized.params; - if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) - { - assert(ref->type->type_type != TYPE_POINTER); - pos += strappend(&buf, &len, pos, "%s%s%s", prefix, ref->type->name, suffix); - if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ", "); - } - - if (!buf) return xstrdup(""); - return buf; -} - static void write_guid(FILE *f, const char *guid_prefix, const char *name, const struct uuid *uuid) { if (!uuid) return; diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 441b6cdcea1..b8b7f3853fa 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -109,58 +109,54 @@ const char *type_get_name(const type_t *type, enum name_type name_type) return NULL; }
-static size_t append_namespace(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *separator, const char *abi_prefix) +static void append_namespace( struct strbuf *str, const struct namespace *namespace, + const char *separator, const char *abi_prefix ) { int nested = namespace && !is_global_namespace(namespace); const char *name = nested ? namespace->name : abi_prefix; - size_t n = 0; - if (!name) return 0; - if (nested) n += append_namespace(buf, len, pos + n, namespace->parent, separator, abi_prefix); - n += strappend(buf, len, pos + n, "%s%s", name, separator); - return n; + if (!name) return; + if (nested) append_namespace( str, namespace->parent, separator, abi_prefix ); + strappend( str, "%s%s", name, separator ); }
-static size_t append_namespaces(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *prefix, - const char *separator, const char *suffix, const char *abi_prefix) +static void append_namespaces( struct strbuf *str, const struct namespace *namespace, const char *prefix, + const char *separator, const char *suffix, const char *abi_prefix ) { int nested = namespace && !is_global_namespace(namespace); - size_t n = 0; - n += strappend(buf, len, pos + n, "%s", prefix); - if (nested) n += append_namespace(buf, len, pos + n, namespace, separator, abi_prefix); - if (suffix) n += strappend(buf, len, pos + n, "%s", suffix); + strappend( str, "%s", prefix ); + if (nested) append_namespace( str, namespace, separator, abi_prefix ); + if (suffix) strappend( str, "%s", suffix ); else if (nested) { - n -= strlen(separator); - (*buf)[n] = 0; + str->pos -= strlen( separator ); + str->buf[str->pos] = 0; } - return n; }
-static size_t append_pointer_stars(char **buf, size_t *len, size_t pos, type_t *type) +static void append_pointer_stars( struct strbuf *str, type_t *type ) { - size_t n = 0; - for (; type && type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) n += strappend(buf, len, pos + n, "*"); - return n; + for (; type && type_is_ptr( type ); type = type_pointer_get_ref_type( type )) + strappend( str, "*" ); }
-static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t *type); +static size_t append_type_signature( struct strbuf *str, type_t *type );
-static size_t append_var_list_signature(char **buf, size_t *len, size_t pos, var_list_t *var_list) +static size_t append_var_list_signature( struct strbuf *str, var_list_t *var_list ) { var_t *var; size_t n = 0;
- if (!var_list) n += strappend(buf, len, pos + n, ";"); + if (!var_list) strappend( str, ";" ); else LIST_FOR_EACH_ENTRY(var, var_list, var_t, entry) { - n += strappend(buf, len, pos + n, ";"); - n += append_type_signature(buf, len, pos + n, var->declspec.type); + strappend( str, ";" ); + append_type_signature( str, var->declspec.type ); }
return n; }
-static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t *type) +static size_t append_type_signature( struct strbuf *str, type_t *type ) { const struct uuid *uuid; size_t n = 0; @@ -169,72 +165,71 @@ static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t switch (type->type_type) { case TYPE_INTERFACE: - if (!strcmp(type->name, "IInspectable")) n += strappend(buf, len, pos + n, "cinterface(IInspectable)"); - else if (type->signature) n += strappend(buf, len, pos + n, "%s", type->signature); + if (!strcmp( type->name, "IInspectable" )) strappend( str, "cinterface(IInspectable)" ); + else if (type->signature) strappend( str, "%s", type->signature ); else { if (!(uuid = get_attrp( type->attrs, ATTR_UUID ))) error_at( &type->where, "cannot compute type signature, no uuid found for type %s.\n", type->name );
- n += strappend(buf, len, pos + n, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - uuid->Data1, uuid->Data2, uuid->Data3, - uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], - uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]); + strappend( str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", uuid->Data1, + uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], + uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] ); } return n; case TYPE_DELEGATE: - n += strappend(buf, len, pos + n, "delegate("); - n += append_type_signature(buf, len, pos + n, type_delegate_get_iface(type)); - n += strappend(buf, len, pos + n, ")"); + strappend( str, "delegate(" ); + append_type_signature( str, type_delegate_get_iface( type ) ); + strappend( str, ")" ); return n; case TYPE_RUNTIMECLASS: - n += strappend(buf, len, pos + n, "rc("); - n += append_namespaces(buf, len, pos + n, type->namespace, "", ".", type->name, NULL); - n += strappend(buf, len, pos + n, ";"); - n += append_type_signature(buf, len, pos + n, type_runtimeclass_get_default_iface(type, TRUE)); - n += strappend(buf, len, pos + n, ")"); + strappend( str, "rc(" ); + append_namespaces( str, type->namespace, "", ".", type->name, NULL ); + strappend( str, ";" ); + append_type_signature( str, type_runtimeclass_get_default_iface( type, TRUE ) ); + strappend( str, ")" ); return n; case TYPE_POINTER: - n += append_type_signature(buf, len, pos + n, type->details.pointer.ref.type); + append_type_signature( str, type->details.pointer.ref.type ); return n; case TYPE_ALIAS: - if (!strcmp(type->name, "boolean")) n += strappend(buf, len, pos + n, "b1"); - else if (!strcmp(type->name, "GUID")) n += strappend(buf, len, pos + n, "g16"); - else if (!strcmp(type->name, "HSTRING")) n += strappend(buf, len, pos + n, "string"); - else n += append_type_signature(buf, len, pos + n, type->details.alias.aliasee.type); + if (!strcmp( type->name, "boolean" )) strappend( str, "b1" ); + else if (!strcmp( type->name, "GUID" )) strappend( str, "g16" ); + else if (!strcmp( type->name, "HSTRING" )) strappend( str, "string" ); + else append_type_signature( str, type->details.alias.aliasee.type ); return n; case TYPE_STRUCT: - n += strappend(buf, len, pos + n, "struct("); - n += append_namespaces(buf, len, pos + n, type->namespace, "", ".", type->name, NULL); - n += append_var_list_signature(buf, len, pos + n, type->details.structure->fields); - n += strappend(buf, len, pos + n, ")"); + strappend( str, "struct(" ); + append_namespaces( str, type->namespace, "", ".", type->name, NULL ); + append_var_list_signature( str, type->details.structure->fields ); + strappend( str, ")" ); return n; case TYPE_BASIC: switch (type_basic_get_type(type)) { case TYPE_BASIC_INT16: - n += strappend(buf, len, pos + n, type_basic_get_sign(type) <= 0 ? "i2" : "u2"); + strappend( str, type_basic_get_sign( type ) <= 0 ? "i2" : "u2" ); return n; case TYPE_BASIC_INT: case TYPE_BASIC_INT32: case TYPE_BASIC_LONG: - n += strappend(buf, len, pos + n, type_basic_get_sign(type) <= 0 ? "i4" : "u4"); + strappend( str, type_basic_get_sign( type ) <= 0 ? "i4" : "u4" ); return n; case TYPE_BASIC_INT64: - n += strappend(buf, len, pos + n, type_basic_get_sign(type) <= 0 ? "i8" : "u8"); + strappend( str, type_basic_get_sign( type ) <= 0 ? "i8" : "u8" ); return n; case TYPE_BASIC_INT8: assert(type_basic_get_sign(type) > 0); /* signature string for signed char isn't specified */ - n += strappend(buf, len, pos + n, "u1"); + strappend( str, "u1" ); return n; case TYPE_BASIC_FLOAT: - n += strappend(buf, len, pos + n, "f4"); + strappend( str, "f4" ); return n; case TYPE_BASIC_DOUBLE: - n += strappend(buf, len, pos + n, "f8"); + strappend( str, "f8" ); return n; case TYPE_BASIC_BYTE: - n += strappend(buf, len, pos + n, "u1"); + strappend( str, "u1" ); return n; case TYPE_BASIC_INT3264: case TYPE_BASIC_CHAR: @@ -247,11 +242,11 @@ static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t break; } case TYPE_ENUM: - n += strappend(buf, len, pos + n, "enum("); - n += append_namespaces(buf, len, pos + n, type->namespace, "", ".", type->name, NULL); - if (is_attr(type->attrs, ATTR_FLAGS)) n += strappend(buf, len, pos + n, ";u4"); - else n += strappend(buf, len, pos + n, ";i4"); - n += strappend(buf, len, pos + n, ")"); + strappend( str, "enum(" ); + append_namespaces( str, type->namespace, "", ".", type->name, NULL ); + if (is_attr( type->attrs, ATTR_FLAGS )) strappend( str, ";u4" ); + else strappend( str, ";i4" ); + strappend( str, ")" ); return n; case TYPE_ARRAY: case TYPE_ENCAPSULATED_UNION: @@ -274,31 +269,48 @@ static size_t append_type_signature(char **buf, size_t *len, size_t pos, type_t return n; }
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix) +char *format_namespace( const struct namespace *namespace, const char *prefix, const char *separator, + const char *suffix, const char *abi_prefix ) { - size_t len = 0; - char *buf = NULL; - append_namespaces(&buf, &len, 0, namespace, prefix, separator, suffix, abi_prefix); - return buf; + struct strbuf str = {0}; + append_namespaces( &str, namespace, prefix, separator, suffix, abi_prefix ); + return str.buf; }
-char *format_parameterized_type_name(type_t *type, typeref_list_t *params) +char *format_parameterized_type_name( const type_t *type, const typeref_list_t *params ) { - size_t len = 0, pos = 0; - char *buf = NULL; + struct strbuf str = {0}; typeref_t *ref;
- pos += strappend(&buf, &len, pos, "%s<", type->name); + strappend( &str, "%s<", type->name ); if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) { type = type_pointer_get_root_type(ref->type); - pos += strappend(&buf, &len, pos, "%s", type->qualified_name); - pos += append_pointer_stars(&buf, &len, pos, ref->type); - if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ","); + strappend( &str, "%s", type->qualified_name ); + append_pointer_stars( &str, ref->type ); + if (list_next( params, &ref->entry )) strappend( &str, "," ); + } + strappend( &str, " >" ); + + return str.buf; +} + +char *format_parameterized_type_args( const type_t *type, const char *prefix, const char *suffix ) +{ + struct strbuf str = {0}; + typeref_list_t *params; + typeref_t *ref; + + params = type->details.parameterized.params; + if (params) LIST_FOR_EACH_ENTRY( ref, params, typeref_t, entry ) + { + assert( ref->type->type_type != TYPE_POINTER ); + strappend( &str, "%s%s%s", prefix, ref->type->name, suffix ); + if (list_next( params, &ref->entry )) strappend( &str, ", " ); } - pos += strappend(&buf, &len, pos, " >");
- return buf; + if (!str.buf) return xstrdup( "" ); + return str.buf; }
static char const *parameterized_type_shorthands[][2] = { @@ -310,109 +322,104 @@ static char const *parameterized_type_shorthands[][2] = {
static char *format_parameterized_type_c_name(type_t *type, typeref_list_t *params, const char *prefix, const char *separator) { + struct strbuf str = {0}; const char *tmp, *ns_prefix = "__x_", *abi_prefix = NULL; - size_t len = 0, pos = 0; - char *buf = NULL; int i, count = params ? list_count(params) : 0; typeref_t *ref;
if (!strcmp(separator, "__C")) ns_prefix = "_C"; else if (use_abi_namespace) abi_prefix = "ABI";
- pos += append_namespaces(&buf, &len, pos, type->namespace, ns_prefix, separator, "", abi_prefix); - pos += strappend(&buf, &len, pos, "%s%s_%d", prefix, type->name, count); + append_namespaces( &str, type->namespace, ns_prefix, separator, "", abi_prefix ); + strappend( &str, "%s%s_%d", prefix, type->name, count ); if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) { type = type_pointer_get_root_type(ref->type); - if ((tmp = type->param_name)) pos += strappend(&buf, &len, pos, "_%s", tmp); - else pos += append_namespaces(&buf, &len, pos, type->namespace, "_", "__C", type->name, NULL); + if ((tmp = type->param_name)) strappend( &str, "_%s", tmp ); + else append_namespaces( &str, type->namespace, "_", "__C", type->name, NULL ); }
for (i = 0; i < ARRAY_SIZE(parameterized_type_shorthands); ++i) { - if ((tmp = strstr(buf, parameterized_type_shorthands[i][0])) && - (tmp - buf) == strlen(ns_prefix) + (abi_prefix ? 5 : 0)) + if ((tmp = strstr( str.buf, parameterized_type_shorthands[i][0] )) && + (tmp - str.buf) == strlen( ns_prefix ) + (abi_prefix ? 5 : 0)) { tmp += strlen(parameterized_type_shorthands[i][0]); - strcpy(buf, parameterized_type_shorthands[i][1]); - memmove(buf + 3, tmp, len - (tmp - buf)); + strcpy( str.buf, parameterized_type_shorthands[i][1] ); + memmove( str.buf + 3, tmp, str.len - (tmp - str.buf) ); } }
- return buf; + return str.buf; }
static char *format_parameterized_type_signature(type_t *type, typeref_list_t *params) { - size_t len = 0, pos = 0; - char *buf = NULL; + struct strbuf str = {0}; typeref_t *ref; const struct uuid *uuid;
if (!(uuid = get_attrp( type->attrs, ATTR_UUID ))) error_at( &type->where, "cannot compute type signature, no uuid found for type %s.\n", type->name );
- pos += strappend(&buf, &len, pos, "pinterface({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - uuid->Data1, uuid->Data2, uuid->Data3, - uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], - uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]); + strappend( &str, "pinterface({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", uuid->Data1, + uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], + uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7] ); if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) { - pos += strappend(&buf, &len, pos, ";"); - pos += append_type_signature(&buf, &len, pos, ref->type); + strappend( &str, ";" ); + append_type_signature( &str, ref->type ); } - pos += strappend(&buf, &len, pos, ")"); + strappend( &str, ")" );
- return buf; + return str.buf; }
static char *format_parameterized_type_short_name(type_t *type, typeref_list_t *params, const char *prefix) { - size_t len = 0, pos = 0; - char *buf = NULL; + struct strbuf str = {0}; typeref_t *ref;
- pos += strappend(&buf, &len, pos, "%s%s", prefix, type->name); + strappend( &str, "%s%s", prefix, type->name ); if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) { type = type_pointer_get_root_type(ref->type); - if (type->short_name) pos += strappend(&buf, &len, pos, "_%s", type->short_name); - else pos += strappend(&buf, &len, pos, "_%s", type->name); + if (type->short_name) strappend( &str, "_%s", type->short_name ); + else strappend( &str, "_%s", type->name ); }
- return buf; + return str.buf; }
static char *format_parameterized_type_impl_name(type_t *type, typeref_list_t *params, const char *prefix) { - size_t len = 0, pos = 0; - char *buf = NULL; + struct strbuf str = {0}; typeref_t *ref; type_t *iface;
- pos += strappend(&buf, &len, pos, "%s%s_impl<", prefix, type->name); + strappend( &str, "%s%s_impl<", prefix, type->name ); if (params) LIST_FOR_EACH_ENTRY(ref, params, typeref_t, entry) { type = type_pointer_get_root_type(ref->type); if (type->type_type == TYPE_RUNTIMECLASS) { - pos += strappend(&buf, &len, pos, "ABI::Windows::Foundation::Internal::AggregateType<%s", type->qualified_name); - pos += append_pointer_stars(&buf, &len, pos, ref->type); + strappend( &str, "ABI::Windows::Foundation::Internal::AggregateType<%s", type->qualified_name ); + append_pointer_stars( &str, ref->type ); iface = type_runtimeclass_get_default_iface(type, TRUE); - pos += strappend(&buf, &len, pos, ", %s", iface->qualified_name); - pos += append_pointer_stars(&buf, &len, pos, ref->type); - pos += strappend(&buf, &len, pos, " >"); + strappend( &str, ", %s", iface->qualified_name ); + append_pointer_stars( &str, ref->type ); + strappend( &str, " >" ); } else { - pos += strappend(&buf, &len, pos, "%s", type->qualified_name); - pos += append_pointer_stars(&buf, &len, pos, ref->type); + strappend( &str, "%s", type->qualified_name ); + append_pointer_stars( &str, ref->type ); } - if (list_next(params, &ref->entry)) pos += strappend(&buf, &len, pos, ", "); + if (list_next( params, &ref->entry )) strappend( &str, ", " ); } - pos += strappend(&buf, &len, pos, " >"); + strappend( &str, " >" );
- return buf; + return str.buf; }
type_t *type_new_function(var_list_t *args) diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 6e5c606ab35..44b0c240b45 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -87,6 +87,11 @@ const char *type_get_decl_name(const type_t *type, enum name_type name_type); const char *type_get_name(const type_t *type, enum name_type name_type); char *gen_name(void);
+extern char *format_namespace( const struct namespace *namespace, const char *prefix, const char *separator, + const char *suffix, const char *abi_prefix ); +extern char *format_parameterized_type_name( const type_t *type, const typeref_list_t *params ); +extern char *format_parameterized_type_args( const type_t *type, const char *prefix, const char *suffix ); + typeref_t *make_typeref(type_t *type); typeref_list_t *append_typeref(typeref_list_t *list, typeref_t *ref);
diff --git a/tools/widl/utils.c b/tools/widl/utils.c index 4f2e9d3d602..a694ffa9841 100644 --- a/tools/widl/utils.c +++ b/tools/widl/utils.c @@ -117,41 +117,31 @@ size_t widl_getline(char **linep, size_t *lenp, FILE *fp) return n; }
-size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) +void strappend( struct strbuf *str, const char *fmt, ... ) { - size_t size; va_list ap; - char *ptr; int n;
- assert( buf && len ); - assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) ); - - if (*buf) - { - size = *len; - ptr = *buf; - } - else - { - size = 100; - ptr = xmalloc( size ); - } + assert( (str->len == 0 && str->buf == NULL) || + (str->len != 0 && str->buf != NULL) );
for (;;) { va_start( ap, fmt ); - n = vsnprintf( ptr + pos, size - pos, fmt, ap ); + n = str->len ? vsnprintf( str->buf + str->pos, str->len - str->pos, fmt, ap ) : 128; va_end( ap ); - if (n == -1) size *= 2; - else if (pos + (size_t)n >= size) size = pos + n + 1; - else break; - ptr = xrealloc( ptr, size ); + if (n >= 0 && n <= str->len && str->pos + n < str->len) break; + str->len = max( str->pos + n, str->len * 3 / 2 ); + str->buf = xrealloc( str->buf, str->len ); }
- *len = size; - *buf = ptr; - return n; + str->pos += n; +} + +void strfree( struct strbuf *str ) +{ + free( str->buf ); + memset( str, 0, sizeof(*str) ); }
/******************************************************************* diff --git a/tools/widl/utils.h b/tools/widl/utils.h index 2a6bc7d7930..5dd7869b842 100644 --- a/tools/widl/utils.h +++ b/tools/widl/utils.h @@ -31,7 +31,15 @@ void warning(const char *s, ...) __attribute__((format (printf, 1, 2))); void warning_at( const struct location *, const char *s, ... ) __attribute__((format( printf, 2, 3 ))); #define warning_loc( ... ) warning_at( NULL, ## __VA_ARGS__ ) void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); -size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) __attribute__((__format__ (__printf__, 4, 5 ))); + +struct strbuf +{ + char *buf; + size_t pos; + size_t len; +}; +extern void strappend( struct strbuf *str, const char *fmt, ... ) __attribute__((__format__( __printf__, 2, 3 ))); +extern void strfree( struct strbuf *str );
size_t widl_getline(char **linep, size_t *lenp, FILE *fp);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 1706f392670..fb540e9bc31 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -709,10 +709,6 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in var_t *make_var(char *name); var_list_t *append_var(var_list_t *list, var_t *var);
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, - const char *abi_prefix); -char *format_parameterized_type_name(type_t *type, typeref_list_t *params); - static inline enum type_type type_get_type_detect_alias(const type_t *type) { return type->type_type;
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 50 ++++--------------------------------------- tools/widl/typetree.c | 25 ++++++++++++++++++++++ tools/widl/typetree.h | 2 ++ 3 files changed, 31 insertions(+), 46 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 5409c79839c..3fd2ab9461c 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -265,6 +265,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b { type_t *t = ds->type; const char *decl_name, *name; + struct strbuf str = {0}; char *args;
if (!h) return; @@ -364,52 +365,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b break; } case TYPE_BASIC: - if (type_basic_get_type(t) != TYPE_BASIC_INT32 && - type_basic_get_type(t) != TYPE_BASIC_INT64 && - type_basic_get_type(t) != TYPE_BASIC_LONG && - type_basic_get_type(t) != TYPE_BASIC_HYPER) - { - if (type_basic_get_sign(t) < 0) fprintf(h, "signed "); - else if (type_basic_get_sign(t) > 0) fprintf(h, "unsigned "); - } - switch (type_basic_get_type(t)) - { - case TYPE_BASIC_INT8: fprintf(h, "small"); break; - case TYPE_BASIC_INT16: fprintf(h, "short"); break; - case TYPE_BASIC_INT: fprintf(h, "int"); break; - case TYPE_BASIC_INT3264: fprintf(h, "__int3264"); break; - case TYPE_BASIC_BYTE: fprintf(h, "byte"); break; - case TYPE_BASIC_CHAR: fprintf(h, "char"); break; - case TYPE_BASIC_WCHAR: fprintf(h, "wchar_t"); break; - case TYPE_BASIC_FLOAT: fprintf(h, "float"); break; - case TYPE_BASIC_DOUBLE: fprintf(h, "double"); break; - case TYPE_BASIC_ERROR_STATUS_T: fprintf(h, "error_status_t"); break; - case TYPE_BASIC_HANDLE: fprintf(h, "handle_t"); break; - case TYPE_BASIC_INT32: - if (type_basic_get_sign(t) > 0) - fprintf(h, "UINT32"); - else - fprintf(h, "INT32"); - break; - case TYPE_BASIC_LONG: - if (type_basic_get_sign(t) > 0) - fprintf(h, "ULONG"); - else - fprintf(h, "LONG"); - break; - case TYPE_BASIC_INT64: - if (type_basic_get_sign(t) > 0) - fprintf(h, "UINT64"); - else - fprintf(h, "INT64"); - break; - case TYPE_BASIC_HYPER: - if (type_basic_get_sign(t) > 0) - fprintf(h, "MIDL_uhyper"); - else - fprintf(h, "hyper"); - break; - } + append_basic_type( &str, t ); + fwrite( str.buf, 1, str.pos, h ); + strfree( &str ); break; case TYPE_INTERFACE: case TYPE_MODULE: diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index b8b7f3853fa..af622595ae6 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -109,6 +109,31 @@ const char *type_get_name(const type_t *type, enum name_type name_type) return NULL; }
+void append_basic_type( struct strbuf *str, const type_t *type ) +{ + int sign = type_basic_get_sign( type ); + const char *prefix = sign > 0 ? "unsigned " : sign < 0 ? "signed " : ""; + + switch (type_basic_get_type( type )) + { + case TYPE_BASIC_INT8: return strappend( str, "%ssmall", prefix ); + case TYPE_BASIC_INT16: return strappend( str, "%sshort", prefix ); + case TYPE_BASIC_INT: return strappend( str, "%sint", prefix ); + case TYPE_BASIC_INT3264: return strappend( str, "%s__int3264", prefix ); + case TYPE_BASIC_BYTE: return strappend( str, "%sbyte", prefix ); + case TYPE_BASIC_CHAR: return strappend( str, "%schar", prefix ); + case TYPE_BASIC_WCHAR: return strappend( str, "%swchar_t", prefix ); + case TYPE_BASIC_FLOAT: return strappend( str, "%sfloat", prefix ); + case TYPE_BASIC_DOUBLE: return strappend( str, "%sdouble", prefix ); + case TYPE_BASIC_ERROR_STATUS_T: return strappend( str, "%serror_status_t", prefix ); + case TYPE_BASIC_HANDLE: return strappend( str, "%shandle_t", prefix ); + case TYPE_BASIC_INT32: return strappend( str, sign > 0 ? "UINT32" : "INT32" ); + case TYPE_BASIC_LONG: return strappend( str, sign > 0 ? "ULONG" : "LONG" ); + case TYPE_BASIC_INT64: return strappend( str, sign > 0 ? "UINT64" : "INT64" ); + case TYPE_BASIC_HYPER: return strappend( str, sign > 0 ? "MIDL_uhyper" : "hyper" ); + } +} + static void append_namespace( struct strbuf *str, const struct namespace *namespace, const char *separator, const char *abi_prefix ) { diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 44b0c240b45..6ea64048d07 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -87,6 +87,8 @@ const char *type_get_decl_name(const type_t *type, enum name_type name_type); const char *type_get_name(const type_t *type, enum name_type name_type); char *gen_name(void);
+extern void append_basic_type( struct strbuf *str, const type_t *type ); + extern char *format_namespace( const struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix ); extern char *format_parameterized_type_name( const type_t *type, const typeref_list_t *params );
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 3fd2ab9461c..69f10870569 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -384,11 +384,12 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b fprintf(h, "void"); break; case TYPE_BITFIELD: - { - const decl_spec_t ds = {.type = type_bitfield_get_field(t)}; - write_type_left(h, &ds, name_type, define, TRUE); - break; - } + t = type_bitfield_get_field( t ); + if (!type_is_alias( t )) append_basic_type( &str, t ); + else strappend( &str, "%s", type_get_name( t, name_type ) ); + fwrite( str.buf, 1, str.pos, h ); + strfree( &str ); + break; case TYPE_ALIAS: /* handled elsewhere */ assert(0);
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 64 ++++++++++++++----------------------------- tools/widl/parser.y | 5 ++++ tools/widl/typetree.c | 58 ++++++++++++++++++++++++++++++++++----- tools/widl/typetree.h | 2 +- 4 files changed, 77 insertions(+), 52 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 69f10870569..5486fe86613 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -266,12 +266,10 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b type_t *t = ds->type; const char *decl_name, *name; struct strbuf str = {0}; - char *args;
if (!h) return;
decl_name = type_get_decl_name(t, name_type); - name = type_get_name(t, name_type);
if (ds->func_specifier & FUNCTION_SPECIFIER_INLINE) fprintf(h, "inline "); @@ -279,10 +277,11 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b if ((ds->qualifier & TYPE_QUALIFIER_CONST) && (type_is_alias(t) || !is_ptr(t))) fprintf(h, "const ");
- if (type_is_alias(t)) fprintf(h, "%s", name); + if ((name = type_get_name( t, name_type, false ))) fprintf(h, "%s", name); else { switch (type_get_type_detect_alias(t)) { case TYPE_ENUM: + name = type_get_name( t, name_type, true ); if (!define) fprintf(h, "enum %s", decl_name ? decl_name : ""); else if (!t->written) { assert(t->defined); @@ -299,6 +298,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b break; case TYPE_STRUCT: case TYPE_ENCAPSULATED_UNION: + name = type_get_name( t, name_type, true ); if (!define) fprintf(h, "struct %s", decl_name ? decl_name : ""); else if (!t->written) { assert(t->defined); @@ -317,6 +317,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b else fprintf(h, "struct %s", name ? name : ""); break; case TYPE_UNION: + name = type_get_name( t, name_type, true ); if (!define) fprintf(h, "union %s", decl_name ? decl_name : ""); else if (!t->written) { assert(t->defined); @@ -339,17 +340,11 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b break; } case TYPE_ARRAY: - if (t->name && type_array_is_decl_as_ptr(t)) - fprintf(h, "%s", t->name); - else - { - write_type_left(h, type_array_get_element(t), name_type, define, !type_array_is_decl_as_ptr(t)); - if (type_array_is_decl_as_ptr(t)) - write_pointer_left(h, type_array_get_element_type(t)); - } + write_type_left(h, type_array_get_element(t), name_type, define, !type_array_is_decl_as_ptr(t)); + if (type_array_is_decl_as_ptr(t)) + write_pointer_left(h, type_array_get_element_type(t)); break; case TYPE_FUNCTION: - { write_type_left(h, type_function_get_ret(t), name_type, define, TRUE);
/* A pointer to a function has to write the calling convention inside @@ -363,48 +358,29 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b if (callconv) fprintf(h, " %s ", callconv); } break; - } case TYPE_BASIC: - append_basic_type( &str, t ); - fwrite( str.buf, 1, str.pos, h ); - strfree( &str ); - break; - case TYPE_INTERFACE: - case TYPE_MODULE: - case TYPE_COCLASS: - fprintf(h, "%s", type_get_name(t, name_type)); - break; - case TYPE_RUNTIMECLASS: - fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t, TRUE), name_type)); - break; - case TYPE_DELEGATE: - fprintf(h, "%s", type_get_name(type_delegate_get_iface(t), name_type)); - break; - case TYPE_VOID: - fprintf(h, "void"); - break; + append_basic_type( &str, t ); + fwrite( str.buf, 1, str.pos, h ); + strfree( &str ); + break; case TYPE_BITFIELD: t = type_bitfield_get_field( t ); if (!type_is_alias( t )) append_basic_type( &str, t ); - else strappend( &str, "%s", type_get_name( t, name_type ) ); + else strappend( &str, "%s", type_get_name( t, name_type, false ) ); fwrite( str.buf, 1, str.pos, h ); strfree( &str ); break; + case TYPE_INTERFACE: + case TYPE_MODULE: + case TYPE_COCLASS: + case TYPE_RUNTIMECLASS: + case TYPE_DELEGATE: + case TYPE_VOID: case TYPE_ALIAS: - /* handled elsewhere */ - assert(0); - break; case TYPE_PARAMETERIZED_TYPE: - { - type_t *iface = type_parameterized_type_get_real_type(t); - if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface); - args = format_parameterized_type_args(t, "", "_logical"); - fprintf(h, "%s<%s>", iface->name, args); - free(args); - break; - } case TYPE_PARAMETER: - fprintf(h, "%s_abi", t->name); + /* handled elsewhere */ + assert(0); break; case TYPE_APICONTRACT: /* shouldn't be here */ diff --git a/tools/widl/parser.y b/tools/widl/parser.y index fb21a2417f1..7d0af92f643 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -2101,6 +2101,11 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in type->c_name = name; type->qualified_name = name; } + else if (type->type_type == TYPE_PARAMETER) + { + type->c_name = strmake( "%s_abi", type->name ); + type->qualified_name = strmake( "%s_abi", type->name ); + } else { type->c_name = format_namespace(namespace, "__x_", "_C", name, use_abi_namespace ? "ABI" : NULL); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index af622595ae6..7e1cdab04b3 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -96,17 +96,61 @@ const char *type_get_decl_name(const type_t *type, enum name_type name_type) return NULL; }
-const char *type_get_name(const type_t *type, enum name_type name_type) +const char *type_get_name( const type_t *type, enum name_type name_type, bool record ) { - switch(name_type) { - case NAME_DEFAULT: - return type->qualified_name ? type->qualified_name : type->name; - case NAME_C: - return type->c_name ? type->c_name : type->name; + const char *name; + char *args; + + switch (name_type) + { + case NAME_DEFAULT: name = type->qualified_name ? type->qualified_name : type->name; break; + case NAME_C: name = type->c_name ? type->c_name : type->name; break; + default: assert(0); }
+ if (type_is_alias( type )) return name; + switch (type_get_type_detect_alias( type )) + { + case TYPE_ALIAS: return NULL; + case TYPE_APICONTRACT: return NULL; + case TYPE_BASIC: return NULL; + case TYPE_BITFIELD: return NULL; + case TYPE_FUNCTION: return NULL; + case TYPE_POINTER: return NULL; + + case TYPE_ENCAPSULATED_UNION: return record ? name : NULL; + case TYPE_ENUM: return record ? name : NULL; + case TYPE_STRUCT: return record ? name : NULL; + case TYPE_UNION: return record ? name : NULL; + + case TYPE_COCLASS: return name; + case TYPE_INTERFACE: return name; + case TYPE_MODULE: return name; + case TYPE_VOID: return "void"; + case TYPE_PARAMETER: return name; + + case TYPE_RUNTIMECLASS: + return type_get_name( type_runtimeclass_get_default_iface( type, TRUE ), name_type, false ); + case TYPE_DELEGATE: + return type_get_name( type_delegate_get_iface( type ), name_type, false ); + + case TYPE_ARRAY: + if (type->name && type_array_is_decl_as_ptr( type )) return type->name; + return NULL; + + case TYPE_PARAMETERIZED_TYPE: + { + type_t *iface = type_parameterized_type_get_real_type( type ); + if (type_get_type( iface ) == TYPE_DELEGATE) iface = type_delegate_get_iface( iface ); + args = format_parameterized_type_args( type, "", "_logical" ); + name = strmake( "%s<%s>", iface->name, args ); + free( args ); + return name; + } + } + + /* shouldn't be here */ assert(0); - return NULL; }
void append_basic_type( struct strbuf *str, const type_t *type ) diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 6ea64048d07..66cf35aa9df 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -84,7 +84,7 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t type_t *type_parameterized_type_specialize_define(type_t *type); int type_is_equal(const type_t *type1, const type_t *type2); const char *type_get_decl_name(const type_t *type, enum name_type name_type); -const char *type_get_name(const type_t *type, enum name_type name_type); +extern const char *type_get_name( const type_t *type, enum name_type name_type, bool record ); char *gen_name(void);
extern void append_basic_type( struct strbuf *str, const type_t *type );
On Tue Aug 12 07:59:57 2025 +0000, Rémi Bernon wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/8696/diffs?diff_id=199806&start_sha=4790dbe7e69abd94e3377ef08cb460abfa5f9e58#06f6f5e1d8c837fb483c79004647ce3f2d069910_130_130)
I changed the `TYPE_PARAMETER` case, the `TYPE_PARAMETERIZED_TYPE` case looks more complicated because it needs the type to be fully created and it's not the case at `reg_type` time where names are usually created, so I kept it like it was instead.
On Tue Aug 12 08:06:29 2025 +0000, Rémi Bernon wrote:
I changed the `TYPE_PARAMETER` case, the `TYPE_PARAMETERIZED_TYPE` case looks more complicated because it needs the type to be fully created and it's not the case at `reg_type` time where names are usually created, so I kept it like it was instead.
Maybe it should be set outside `reg_type` then?
On Thu Aug 14 12:51:40 2025 +0000, Jacek Caban wrote:
Maybe it should be set outside `reg_type` then?
I don't think it's a good idea to spread type name initialization in more places just to avoid an allocation that was already there before. Maybe we can refactor the type creation code to make it less messy but it wasn't the purpose of this MR.
On Thu Aug 14 13:11:47 2025 +0000, Rémi Bernon wrote:
I don't think it's a good idea to spread type name initialization in more places just to avoid an allocation that was already there before. Maybe we can refactor the type creation code to make it less messy but it wasn't the purpose of this MR.
We could also move it instead of spreading. I thought that the purpose of this commit was to clean up its handling.
Alexandre Julliard (@julliard) commented about tools/widl/utils.c:
if (n >= 0 && n <= str->len && str->pos + n < str->len) break;
str->len = max( str->pos + n, str->len * 3 / 2 );
}str->buf = xrealloc( str->buf, str->len );
- *len = size;
- *buf = ptr;
- return n;
- str->pos += n;
+}
+void strfree( struct strbuf *str ) +{
- free( str->buf );
- memset( str, 0, sizeof(*str) );
}
In general we don't bother to free string buffers.