From: "Rémi Bernon" Subject: [PATCH 1/4] widl: Introduce format_namespace_buffer helper. Message-Id: <20201123112457.282037-1-rbernon@codeweavers.com> Date: Mon, 23 Nov 2020 12:24:54 +0100 To compute format_namespace length and write to an existing buffer. Also add explicit abi_prefix parameter. Signed-off-by: Rémi Bernon --- This series adds support for WinRT contracts type and attribute parsing, and generation of MIDL-compatible #ifdefs to the generated header files. Each contract generates a predefined macro, guarding the corresponding versioned elements, which can be redefined to change the targeted contract version. tools/widl/header.c | 2 +- tools/widl/parser.y | 2 +- tools/widl/typetree.c | 58 +++++++++++++++++++++--------------------- tools/widl/widltypes.h | 3 ++- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/tools/widl/header.c b/tools/widl/header.c index 015bbe2ece7..a892243fb54 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -132,7 +132,7 @@ static void write_guid(FILE *f, const char *guid_prefix, const char *name, const static void write_uuid_decl(FILE *f, type_t *type, const UUID *uuid) { - char *name = format_namespace(type->namespace, "", "::", type->name); + char *name = format_namespace(type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL); fprintf(f, "#ifdef __CRT_UUID_DECL\n"); fprintf(f, "__CRT_UUID_DECL(%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 160e4029a6e..1bbb2e78f7e 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1922,7 +1922,7 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in if (is_global_namespace(namespace)) type->c_name = name; else - type->c_name = format_namespace(namespace, "__x_", "_C", name); + type->c_name = format_namespace(namespace, "__x_", "_C", name, use_abi_namespace ? "ABI" : NULL); nt->type = type; nt->t = t; nt->next = namespace->type_hash[hash]; diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index c0547b36a96..d211fa8d277 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -89,41 +89,41 @@ const char *type_get_name(const type_t *type, enum name_type name_type) return NULL; } -static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator) +#define append_buf(f, ...) \ + do { \ + int r = f(buf + ret, max(ret, len) - ret, ## __VA_ARGS__); \ + assert(r >= 0); \ + ret += r; \ + } while(0) + +static int append_namespace(char *buf, size_t len, struct namespace *namespace, const char *separator, const char *abi_prefix) { - if(is_global_namespace(namespace)) { - if(!use_abi_namespace) - return ptr; - strcpy(ptr, "ABI"); - strcat(ptr, separator); - return ptr + strlen(ptr); - } - - ptr = append_namespace(ptr, namespace->parent, separator); - strcpy(ptr, namespace->name); - strcat(ptr, separator); - return ptr + strlen(ptr); + const char *name = namespace && !is_global_namespace(namespace) ? namespace->name : abi_prefix; + int ret = 0; + if (!name) return 0; + if (namespace && !is_global_namespace(namespace)) append_buf(append_namespace, namespace->parent, separator, abi_prefix); + append_buf(snprintf, "%s%s", name, separator); + return ret; } -char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix) +static int format_namespace_buffer(char *buf, size_t len, struct namespace *namespace, const char *prefix, + const char *separator, const char *suffix, const char *abi_prefix) { - unsigned len = strlen(prefix) + strlen(suffix); - unsigned sep_len = strlen(separator); - struct namespace *iter; - char *ret, *ptr; - - if(use_abi_namespace && !is_global_namespace(namespace)) - len += 3 /* strlen("ABI") */ + sep_len; - - for(iter = namespace; !is_global_namespace(iter); iter = iter->parent) - len += strlen(iter->name) + sep_len; + int ret = 0; + append_buf(snprintf, "%s", prefix); + append_buf(append_namespace, namespace, separator, abi_prefix); + append_buf(snprintf, "%s", suffix); + return ret; +} - ret = xmalloc(len+1); - strcpy(ret, prefix); - ptr = append_namespace(ret + strlen(ret), namespace, separator); - strcpy(ptr, suffix); +#undef append_buf - return ret; +char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix) +{ + int len = format_namespace_buffer(NULL, 0, namespace, prefix, separator, suffix, abi_prefix); + char *buf = xmalloc(len + 1); + format_namespace_buffer(buf, len + 1, namespace, prefix, separator, suffix, abi_prefix); + return buf; } type_t *type_new_function(var_list_t *args) diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index b02b80e122c..7a43e517698 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -613,7 +613,8 @@ var_list_t *append_var(var_list_t *list, var_t *var); void init_loc_info(loc_info_t *); -char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix); +char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, + const char *abi_prefix); static inline enum type_type type_get_type_detect_alias(const type_t *type) { -- 2.29.2