[PATCH v2 2/4] widl: Introduce new strappend helper.
Rémi Bernon
rbernon at codeweavers.com
Thu Feb 11 10:37:28 CST 2021
And use it for format_namespace to grow buffer as needed.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
tools/widl/typetree.c | 46 ++++++++++++++-----------------------------
tools/widl/utils.c | 37 ++++++++++++++++++++++++++++++++++
tools/widl/utils.h | 1 +
3 files changed, 53 insertions(+), 31 deletions(-)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index f696d30a5f5..203fffcdee6 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -89,41 +89,25 @@ 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, const char *abi_prefix)
+static size_t append_namespace(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *separator, const char *abi_prefix)
{
- if(is_global_namespace(namespace)) {
- if(!abi_prefix) return ptr;
- strcpy(ptr, abi_prefix);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
- }
-
- ptr = append_namespace(ptr, namespace->parent, separator, abi_prefix);
- strcpy(ptr, namespace->name);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
+ 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;
}
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
- const char *abi_prefix)
+char *format_namespace(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(abi_prefix)
- len += strlen(abi_prefix) + sep_len;
-
- for(iter = namespace; !is_global_namespace(iter); iter = iter->parent)
- len += strlen(iter->name) + sep_len;
-
- ret = xmalloc(len+1);
- strcpy(ret, prefix);
- ptr = append_namespace(ret + strlen(ret), namespace, separator, abi_prefix);
- strcpy(ptr, suffix);
-
- return ret;
+ size_t len = 0, pos = 0;
+ char *buf = NULL;
+ pos += strappend(&buf, &len, pos, "%s", prefix);
+ pos += append_namespace(&buf, &len, pos, namespace, separator, abi_prefix);
+ pos += strappend(&buf, &len, pos, "%s", suffix);
+ return buf;
}
type_t *type_new_function(var_list_t *args)
diff --git a/tools/widl/utils.c b/tools/widl/utils.c
index ea92372c8c7..634bd12a0ba 100644
--- a/tools/widl/utils.c
+++ b/tools/widl/utils.c
@@ -245,6 +245,43 @@ char *strmake( const char* fmt, ... )
}
}
+size_t strappend(char **buf, size_t *len, size_t pos, 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 );
+ }
+
+ for (;;)
+ {
+ va_start( ap, fmt );
+ n = vsnprintf( ptr + pos, size - pos, fmt, ap );
+ 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 );
+ }
+
+ *len = size;
+ *buf = ptr;
+ return n;
+}
+
char *xstrdup(const char *str)
{
char *s;
diff --git a/tools/widl/utils.h b/tools/widl/utils.h
index 37406656504..82e0a6ae489 100644
--- a/tools/widl/utils.h
+++ b/tools/widl/utils.h
@@ -45,6 +45,7 @@ void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning_loc_info(const loc_info_t *, const char *s, ...) __attribute__((format (printf, 2, 3)));
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
char *strmake(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2 )));
+size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) __attribute__((__format__ (__printf__, 4, 5 )));
char *dup_basename(const char *name, const char *ext);
size_t widl_getline(char **linep, size_t *lenp, FILE *fp);
--
2.30.0
More information about the wine-devel
mailing list