Alexandre Julliard : msvcrt: Rewrite va_list to string conversions to avoid depending on va_copy.
Alexandre Julliard
julliard at winehq.org
Wed Dec 17 09:39:35 CST 2008
Module: wine
Branch: master
Commit: 6718b9bce7ef7a40f9d64b3bfc7105dbc13ec1da
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6718b9bce7ef7a40f9d64b3bfc7105dbc13ec1da
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Dec 17 12:55:30 2008 +0100
msvcrt: Rewrite va_list to string conversions to avoid depending on va_copy.
---
dlls/msvcrt/process.c | 141 ++++++++++++++++++------------------------------
1 files changed, 53 insertions(+), 88 deletions(-)
diff --git a/dlls/msvcrt/process.c b/dlls/msvcrt/process.c
index 5298520..bb57b9f 100644
--- a/dlls/msvcrt/process.c
+++ b/dlls/msvcrt/process.c
@@ -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)
{
- va_list alist2;
- unsigned long len;
- const MSVCRT_wchar_t *arg;
- MSVCRT_wchar_t *p, *ret;
-
-#ifdef HAVE_VA_COPY
- va_copy(alist2,alist);
-#else
-# ifdef HAVE___VA_COPY
- __va_copy(alist2,alist);
-# else
- alist2 = alist;
-# endif
-#endif
-
- if (!arg0)
- {
- /* Return NULL for an empty environment list */
- return NULL;
- }
+ unsigned int size = 0, pos = 0;
+ const MSVCRT_wchar_t *arg;
+ MSVCRT_wchar_t *new, *ret = NULL;
- /* get length */
- arg = arg0;
- len = 0;
- do {
- len += strlenW(arg) + 1;
- arg = va_arg(alist, MSVCRT_wchar_t*);
- } while (arg != NULL);
-
- 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;
+ for (arg = arg0; arg; arg = va_arg( alist, MSVCRT_wchar_t * ))
+ {
+ unsigned int len = strlenW( arg ) + 1;
+ if (pos + len >= size)
+ {
+ size = max( 256, size * 2 );
+ size = max( size, pos + len + 1 );
+ if (!(new = MSVCRT_realloc( ret, size * sizeof(MSVCRT_wchar_t) )))
+ {
+ MSVCRT_free( ret );
+ return NULL;
+ }
+ ret = new;
+ }
+ strcpyW( ret + pos, arg );
+ pos += len;
+ ret[pos - 1] = delim;
+ }
+ if (pos)
+ {
+ if (delim) ret[pos - 1] = 0;
+ else ret[pos] = 0;
+ }
+ return ret;
}
/* 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)
{
- va_list alist2;
- unsigned long len;
- const char *arg;
- MSVCRT_wchar_t *p, *ret;
-
-#ifdef HAVE_VA_COPY
- va_copy(alist2,alist);
-#else
-# ifdef HAVE___VA_COPY
- __va_copy(alist2,alist);
-# else
- alist2 = alist;
-# endif
-#endif
-
- if (!arg0)
- {
- /* Return NULL for an empty environment list */
- return NULL;
- }
+ unsigned int size = 0, pos = 0;
+ const char *arg;
+ MSVCRT_wchar_t *new, *ret = NULL;
- /* get length */
- arg = arg0;
- len = 0;
- do {
- len += MultiByteToWideChar(CP_ACP, 0, arg, -1, NULL, 0);
- arg = va_arg(alist, char*);
- } while (arg != NULL);
-
- 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;
+ for (arg = arg0; arg; arg = va_arg( alist, char * ))
+ {
+ unsigned int len = MultiByteToWideChar( CP_ACP, 0, arg, -1, NULL, 0 );
+ if (pos + len >= size)
+ {
+ size = max( 256, size * 2 );
+ size = max( size, pos + len + 1 );
+ if (!(new = MSVCRT_realloc( ret, size * sizeof(MSVCRT_wchar_t) )))
+ {
+ MSVCRT_free( ret );
+ return NULL;
+ }
+ ret = new;
+ }
+ pos += MultiByteToWideChar( CP_ACP, 0, arg, -1, ret + pos, size - pos );
+ ret[pos - 1] = delim;
+ }
+ if (pos)
+ {
+ if (delim) ret[pos - 1] = 0;
+ else ret[pos] = 0;
+ }
+ return ret;
}
/* INTERNAL: retrieve COMSPEC environment variable */
More information about the wine-cvs
mailing list