widl: Introduce new strappend helper.

And use it for format_namespace to grow buffer as needed.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-02-11 17:37:28 +01:00 committed by Alexandre Julliard
parent ed21c29481
commit 6341546fde
3 changed files with 53 additions and 31 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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);