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;