From: Eric Pouech eric.pouech@gmail.com
this will append a string with potentially prepending ' ' as separator
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/msvcrt/undname.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/dlls/msvcrt/undname.c b/dlls/msvcrt/undname.c index 0aa22b485ac..8a30e0b45b6 100644 --- a/dlls/msvcrt/undname.c +++ b/dlls/msvcrt/undname.c @@ -227,8 +227,12 @@ static char* str_array_get_ref(struct array* cref, unsigned idx)
/****************************************************************** * str_build - * Helper for printf type of command (only %s and %c are implemented) - * while dynamically allocating the buffer + * Helper for printf type of command while dynamically allocating the buffer + * Supported operators: + * + %s inserts the string (as printf does) ; argument can be NULL (inserts nothing) + * + %S same as %s, but insert before the string a ' ' as separator if in + * previous contiguous %s or %S something has been inserted and argument isn't NULL + * + %c inserts a char */ static char* WINAPIV str_build(struct parsed_symbol* sym, const char* format, ...) { @@ -237,6 +241,7 @@ static char* WINAPIV str_build(struct parsed_symbol* sym, const char* format, .. char* tmp; char* p; char* t; + BOOL needs_delim = FALSE;
va_start(args, format); for (i = 0; format[i]; i++) @@ -245,10 +250,12 @@ static char* WINAPIV str_build(struct parsed_symbol* sym, const char* format, .. { switch (format[++i]) { + case 'S': len++; /* fall through */ case 's': t = va_arg(args, char*); if (t) len += strlen(t); break; case 'c': (void)va_arg(args, int); len++; break; - default: i--; /* fall through */ - case '%': len++; break; + default: + ERR("Unsupported escape '%c' in format\n", format[i]); + return NULL; } } else len++; @@ -262,23 +269,30 @@ static char* WINAPIV str_build(struct parsed_symbol* sym, const char* format, .. { switch (format[++i]) { + case 'S': case 's': t = va_arg(args, char*); - if (t) + if (t && *t) { + if (format[i] == 'S' && needs_delim) + *p++ = ' '; sz = strlen(t); memcpy(p, t, sz); p += sz; + needs_delim = TRUE; } break; case 'c': *p++ = (char)va_arg(args, int); + needs_delim = FALSE; break; - default: i--; /* fall through */ - case '%': *p++ = '%'; break; } } - else *p++ = format[i]; + else + { + *p++ = format[i]; + needs_delim = FALSE; + } } va_end(args); *p = '\0'; @@ -466,11 +480,7 @@ static BOOL get_modified_type(struct datatype_t *ct, struct parsed_symbol* sym, default: return FALSE; } if (ref || str_modif || xdt.left || xdt.right) - ct->left = str_build(sym, " %s%s%s%s%s%s%s", - xdt.left, - xdt.left && ref ? " " : NULL, ref, - (xdt.left || ref) && xdt.right ? " " : NULL, xdt.right, - (xdt.left || ref || xdt.right) && str_modif ? " " : NULL, str_modif); + ct->left = str_build(sym, " %s%S%S%S", xdt.left, ref, xdt.right, str_modif); else ct->left = NULL; ct->right = NULL; @@ -1153,10 +1163,7 @@ static BOOL handle_data(struct parsed_symbol* sym) } if (sym->flags & UNDNAME_NAME_ONLY) ct.left = ct.right = xdt.left = NULL;
- sym->result = str_build(sym, "%s%s%s%s%s%s%s%s", access, - member_type, ct.left, - xdt.left && ct.left ? " " : NULL, xdt.left, - xdt.left || ct.left ? " " : NULL, name, ct.right); + sym->result = str_build(sym, "%s%s%s%S%S%s", access, member_type, ct.left, xdt.left, name, ct.right); ret = TRUE; done: return ret;