msvcrt: Rewrite va_list to string conversions to avoid depending on va_copy.

This commit is contained in:
Alexandre Julliard 2008-12-17 12:55:30 +01:00
parent 561cf9f746
commit 6718b9bce7
1 changed files with 53 additions and 88 deletions

View File

@ -271,52 +271,34 @@ static MSVCRT_wchar_t *msvcrt_argvtos_aw(const char * const *arg, MSVCRT_wchar_t
*/ */
static MSVCRT_wchar_t *msvcrt_valisttos(const MSVCRT_wchar_t *arg0, va_list alist, MSVCRT_wchar_t delim) static MSVCRT_wchar_t *msvcrt_valisttos(const MSVCRT_wchar_t *arg0, va_list alist, MSVCRT_wchar_t delim)
{ {
va_list alist2; unsigned int size = 0, pos = 0;
unsigned long len; const MSVCRT_wchar_t *arg;
const MSVCRT_wchar_t *arg; MSVCRT_wchar_t *new, *ret = NULL;
MSVCRT_wchar_t *p, *ret;
#ifdef HAVE_VA_COPY for (arg = arg0; arg; arg = va_arg( alist, MSVCRT_wchar_t * ))
va_copy(alist2,alist); {
#else unsigned int len = strlenW( arg ) + 1;
# ifdef HAVE___VA_COPY if (pos + len >= size)
__va_copy(alist2,alist); {
# else size = max( 256, size * 2 );
alist2 = alist; size = max( size, pos + len + 1 );
# endif if (!(new = MSVCRT_realloc( ret, size * sizeof(MSVCRT_wchar_t) )))
#endif {
MSVCRT_free( ret );
if (!arg0) return NULL;
{ }
/* Return NULL for an empty environment list */ ret = new;
return NULL; }
} strcpyW( ret + pos, arg );
pos += len;
/* get length */ ret[pos - 1] = delim;
arg = arg0; }
len = 0; if (pos)
do { {
len += strlenW(arg) + 1; if (delim) ret[pos - 1] = 0;
arg = va_arg(alist, MSVCRT_wchar_t*); else ret[pos] = 0;
} while (arg != NULL); }
return ret;
ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t));
if (!ret)
return NULL;
/* fill string */
arg = arg0;
p = ret;
do {
len = strlenW(arg);
memcpy(p, arg, len * sizeof(MSVCRT_wchar_t));
p += len;
*p++ = delim;
arg = va_arg(alist2, MSVCRT_wchar_t*);
} while (arg != NULL);
if (delim && p > ret) p[-1] = 0;
else *p = 0;
return ret;
} }
/* INTERNAL: Convert ansi va_list to a single 'delim'-separated wide string, with an /* INTERNAL: Convert ansi va_list to a single 'delim'-separated wide string, with an
@ -324,50 +306,33 @@ static MSVCRT_wchar_t *msvcrt_valisttos(const MSVCRT_wchar_t *arg0, va_list alis
*/ */
static MSVCRT_wchar_t *msvcrt_valisttos_aw(const char *arg0, va_list alist, MSVCRT_wchar_t delim) static MSVCRT_wchar_t *msvcrt_valisttos_aw(const char *arg0, va_list alist, MSVCRT_wchar_t delim)
{ {
va_list alist2; unsigned int size = 0, pos = 0;
unsigned long len; const char *arg;
const char *arg; MSVCRT_wchar_t *new, *ret = NULL;
MSVCRT_wchar_t *p, *ret;
#ifdef HAVE_VA_COPY for (arg = arg0; arg; arg = va_arg( alist, char * ))
va_copy(alist2,alist); {
#else unsigned int len = MultiByteToWideChar( CP_ACP, 0, arg, -1, NULL, 0 );
# ifdef HAVE___VA_COPY if (pos + len >= size)
__va_copy(alist2,alist); {
# else size = max( 256, size * 2 );
alist2 = alist; size = max( size, pos + len + 1 );
# endif if (!(new = MSVCRT_realloc( ret, size * sizeof(MSVCRT_wchar_t) )))
#endif {
MSVCRT_free( ret );
if (!arg0) return NULL;
{ }
/* Return NULL for an empty environment list */ ret = new;
return NULL; }
} pos += MultiByteToWideChar( CP_ACP, 0, arg, -1, ret + pos, size - pos );
ret[pos - 1] = delim;
/* get length */ }
arg = arg0; if (pos)
len = 0; {
do { if (delim) ret[pos - 1] = 0;
len += MultiByteToWideChar(CP_ACP, 0, arg, -1, NULL, 0); else ret[pos] = 0;
arg = va_arg(alist, char*); }
} while (arg != NULL); return ret;
ret = MSVCRT_malloc((len + 1) * sizeof(MSVCRT_wchar_t));
if (!ret)
return NULL;
/* fill string */
arg = arg0;
p = ret;
do {
p += MultiByteToWideChar(CP_ACP, 0, arg, strlen(arg), p, len - (p - ret));
*p++ = delim;
arg = va_arg(alist2, char*);
} while (arg != NULL);
if (delim && p > ret) p[-1] = 0;
else *p = 0;
return ret;
} }
/* INTERNAL: retrieve COMSPEC environment variable */ /* INTERNAL: retrieve COMSPEC environment variable */