Resend: Re-implement MSVCRT *printf functions

Aneurin Price wine at shadovald.dyndns.org
Sat Nov 27 14:37:21 CST 2004


Well I recently got re-motivated, by forgetting I was using an unpatched 
version of Wine, and getting my WC3 campaign file nuked :(.

So, I've had a go over this all, and here is a new version. Is it a step 
in the right direction? I still don't really know what I should be doing 
to improve this.
Aneurin Price
-------------- next part --------------
Index: dlls/msvcrt/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/Makefile.in,v
retrieving revision 1.17
diff -u -u -r1.17 Makefile.in
--- dlls/msvcrt/Makefile.in	8 Nov 2004 22:10:43 -0000	1.17
+++ dlls/msvcrt/Makefile.in	27 Nov 2004 21:27:58 -0000
@@ -27,6 +27,7 @@
 	math.c \
 	mbcs.c \
 	misc.c \
+	printf.c \
 	process.c \
 	scanf.c \
 	string.c \
Index: dlls/msvcrt/file.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/file.c,v
retrieving revision 1.73
diff -u -u -r1.73 file.c
--- dlls/msvcrt/file.c	3 Nov 2004 22:17:05 -0000	1.73
+++ dlls/msvcrt/file.c	27 Nov 2004 21:28:00 -0000
@@ -2614,113 +2614,6 @@
   return file;
 }
 
-/*********************************************************************
- *		vfprintf (MSVCRT.@)
- */
-int MSVCRT_vfprintf(MSVCRT_FILE* file, const char *format, va_list valist)
-{
-  char buf[2048], *mem = buf;
-  int written, resize = sizeof(buf), retval;
-  /* There are two conventions for vsnprintf failing:
-   * Return -1 if we truncated, or
-   * Return the number of bytes that would have been written
-   * The code below handles both cases
-   */
-  while ((written = vsnprintf(mem, resize, format, valist)) == -1 ||
-          written > resize)
-  {
-    resize = (written == -1 ? resize * 2 : written + 1);
-    if (mem != buf)
-      MSVCRT_free (mem);
-    if (!(mem = (char *)MSVCRT_malloc(resize)))
-      return MSVCRT_EOF;
-  }
-  retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file);
-  if (mem != buf)
-    MSVCRT_free (mem);
-  return retval;
-}
-
-/*********************************************************************
- *		vfwprintf (MSVCRT.@)
- * FIXME:
- * Is final char included in written (then resize is too big) or not
- * (then we must test for equality too)?
- */
-int MSVCRT_vfwprintf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, va_list valist)
-{
-  MSVCRT_wchar_t buf[2048], *mem = buf;
-  int written, resize = sizeof(buf) / sizeof(MSVCRT_wchar_t), retval;
-  /* See vfprintf comments */
-  while ((written = _vsnwprintf(mem, resize, format, valist)) == -1 ||
-          written > resize)
-  {
-    resize = (written == -1 ? resize * 2 : written + sizeof(MSVCRT_wchar_t));
-    if (mem != buf)
-      MSVCRT_free (mem);
-    if (!(mem = (MSVCRT_wchar_t *)MSVCRT_malloc(resize*sizeof(*mem))))
-      return MSVCRT_EOF;
-  }
-  retval = MSVCRT_fwrite(mem, sizeof(*mem), written, file);
-  if (mem != buf)
-    MSVCRT_free (mem);
-  return retval;
-}
-
-/*********************************************************************
- *		vprintf (MSVCRT.@)
- */
-int MSVCRT_vprintf(const char *format, va_list valist)
-{
-  return MSVCRT_vfprintf(MSVCRT_stdout,format,valist);
-}
-
-/*********************************************************************
- *		vwprintf (MSVCRT.@)
- */
-int MSVCRT_vwprintf(const MSVCRT_wchar_t *format, va_list valist)
-{
-  return MSVCRT_vfwprintf(MSVCRT_stdout,format,valist);
-}
-
-/*********************************************************************
- *		fprintf (MSVCRT.@)
- */
-int MSVCRT_fprintf(MSVCRT_FILE* file, const char *format, ...)
-{
-    va_list valist;
-    int res;
-    va_start(valist, format);
-    res = MSVCRT_vfprintf(file, format, valist);
-    va_end(valist);
-    return res;
-}
-
-/*********************************************************************
- *		fwprintf (MSVCRT.@)
- */
-int MSVCRT_fwprintf(MSVCRT_FILE* file, const MSVCRT_wchar_t *format, ...)
-{
-    va_list valist;
-    int res;
-    va_start(valist, format);
-    res = MSVCRT_vfwprintf(file, format, valist);
-    va_end(valist);
-    return res;
-}
-
-/*********************************************************************
- *		printf (MSVCRT.@)
- */
-int MSVCRT_printf(const char *format, ...)
-{
-    va_list valist;
-    int res;
-    va_start(valist, format);
-    res = MSVCRT_vfprintf(MSVCRT_stdout, format, valist);
-    va_end(valist);
-    return res;
-}
 
 /*********************************************************************
  *		ungetc (MSVCRT.@)
@@ -2753,17 +2646,4 @@
 			return MSVCRT_WEOF;
 	}
 	return mwc;
-}
-
-/*********************************************************************
- *		wprintf (MSVCRT.@)
- */
-int MSVCRT_wprintf(const MSVCRT_wchar_t *format, ...)
-{
-    va_list valist;
-    int res;
-    va_start(valist, format);
-    res = MSVCRT_vwprintf(format, valist);
-    va_end(valist);
-    return res;
 }
Index: dlls/msvcrt/msvcrt.spec
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/msvcrt.spec,v
retrieving revision 1.93
diff -u -u -r1.93 msvcrt.spec
--- dlls/msvcrt/msvcrt.spec	14 Oct 2004 00:26:39 -0000	1.93
+++ dlls/msvcrt/msvcrt.spec	27 Nov 2004 21:28:00 -0000
@@ -433,8 +433,8 @@
 @ cdecl _setmode(long long)
 @ stub _setsystime #(ptr long)
 @ cdecl _sleep(long)
-@ varargs _snprintf(str long str) snprintf
-@ varargs _snwprintf(wstr long wstr) ntdll._snwprintf
+@ varargs _snprintf(str long str)
+@ varargs _snwprintf(wstr long wstr)
 @ varargs _sopen(str long long) MSVCRT__sopen
 @ varargs _spawnl(long str str)
 @ varargs _spawnle(long str str)
@@ -484,7 +484,7 @@
 @ cdecl _unloaddll(long)
 @ cdecl _unlock(long)
 @ cdecl _utime(str ptr)
-@ cdecl _vsnprintf(ptr long ptr ptr) vsnprintf
+@ cdecl _vsnprintf(ptr long ptr ptr)
 @ cdecl _vsnwprintf(ptr long wstr long)
 @ cdecl _waccess(wstr long)
 @ stub _wasctime #(ptr) MSVCRT__wasctime
@@ -693,7 +693,7 @@
 @ cdecl signal(long long) MSVCRT_signal
 @ cdecl sin(double)
 @ cdecl sinh(double)
-@ varargs sprintf(ptr str)
+@ varargs sprintf(ptr str) MSVCRT_sprintf
 @ cdecl sqrt(double)
 @ cdecl srand(long)
 @ varargs sscanf(str str) MSVCRT_sscanf
@@ -735,7 +735,7 @@
 @ cdecl vfprintf(ptr str long) MSVCRT_vfprintf
 @ cdecl vfwprintf(ptr wstr long) MSVCRT_vfwprintf
 @ cdecl vprintf(str long) MSVCRT_vprintf
-@ cdecl vsprintf(ptr str ptr)
+@ cdecl vsprintf(ptr str ptr) MSVCRT_vsprintf
 @ cdecl vswprintf(ptr wstr long) MSVCRT_vswprintf
 @ cdecl vwprintf(wstr long) MSVCRT_vwprintf
 @ cdecl wcscat(wstr wstr) ntdll.wcscat
Index: dlls/msvcrt/wcs.c
===================================================================
RCS file: /home/wine/wine/dlls/msvcrt/wcs.c,v
retrieving revision 1.18
diff -u -u -r1.18 wcs.c
--- dlls/msvcrt/wcs.c	25 Jun 2004 01:19:15 -0000	1.18
+++ dlls/msvcrt/wcs.c	27 Nov 2004 21:28:00 -0000
@@ -178,194 +178,6 @@
   return ret;
 }
 
-static int MSVCRT_vsnprintfW(WCHAR *str, size_t len, const WCHAR *format, va_list valist)
-{
-    unsigned int written = 0;
-    const WCHAR *iter = format;
-    char bufa[256], fmtbufa[64], *fmta;
-
-    while (*iter)
-    {
-        while (*iter && *iter != '%')
-        {
-            if (written++ >= len)
-                return -1;
-            *str++ = *iter++;
-        }
-        if (*iter == '%')
-        {
-            if (iter[1] == '%')
-            {
-                if (written++ >= len)
-                    return -1;
-                *str++ = '%'; /* "%%"->'%' */
-                iter += 2;
-                continue;
-            }
-
-            fmta = fmtbufa;
-            *fmta++ = *iter++;
-            while (*iter == '0' ||
-                   *iter == '+' ||
-                   *iter == '-' ||
-                   *iter == ' ' ||
-                   *iter == '*' ||
-                   *iter == '#')
-            {
-                if (*iter == '*')
-                {
-                    char *buffiter = bufa;
-                    int fieldlen = va_arg(valist, int);
-                    sprintf(buffiter, "%d", fieldlen);
-                    while (*buffiter)
-                        *fmta++ = *buffiter++;
-                }
-                else
-                    *fmta++ = *iter;
-                iter++;
-            }
-
-            while (isdigit(*iter))
-                *fmta++ = *iter++;
-
-            if (*iter == '.')
-            {
-                *fmta++ = *iter++;
-                if (*iter == '*')
-                {
-                    char *buffiter = bufa;
-                    int fieldlen = va_arg(valist, int);
-                    sprintf(buffiter, "%d", fieldlen);
-                    while (*buffiter)
-                        *fmta++ = *buffiter++;
-                }
-                else
-                    while (isdigit(*iter))
-                        *fmta++ = *iter++;
-            }
-            if (*iter == 'h' || *iter == 'l')
-                *fmta++ = *iter++;
-
-            switch (*iter)
-            {
-            case 'S':
-            {
-                static const char *none = "(null)";
-                const char *astr = va_arg(valist, const char *);
-                const char *striter = astr ? astr : none;
-                int r, n;
-                while (*striter)
-                {
-                    if (written >= len)
-                        return -1;
-                    n = 1;
-                    if( IsDBCSLeadByte( *striter ) )
-                        n++;
-                    r = MultiByteToWideChar( CP_ACP, 0,
-                               striter, n, str, len - written );
-                    striter += n;
-                    str += r;
-                    written += r;
-                }
-                iter++;
-                break;
-            }
-
-            case 's':
-            {
-                static const WCHAR none[] = { '(','n','u','l','l',')',0 };
-                const WCHAR *wstr = va_arg(valist, const WCHAR *);
-                const WCHAR *striter = wstr ? wstr : none;
-                while (*striter)
-                {
-                    if (written++ >= len)
-                        return -1;
-                    *str++ = *striter++;
-                }
-                iter++;
-                break;
-            }
-
-            case 'c':
-                if (written++ >= len)
-                    return -1;
-                *str++ = (WCHAR)va_arg(valist, int);
-                iter++;
-                break;
-
-            default:
-            {
-                /* For non wc types, use system sprintf and append to wide char output */
-                /* FIXME: for unrecognised types, should ignore % when printing */
-                char *bufaiter = bufa;
-                if (*iter == 'p')
-                    sprintf(bufaiter, "%08lX", va_arg(valist, long));
-                else
-                {
-                    *fmta++ = *iter;
-                    *fmta = '\0';
-                    if (*iter == 'a' || *iter == 'A' ||
-                        *iter == 'e' || *iter == 'E' ||
-                        *iter == 'f' || *iter == 'F' || 
-                        *iter == 'g' || *iter == 'G')
-                        sprintf(bufaiter, fmtbufa, va_arg(valist, double));
-                    else
-                    {
-                        /* FIXME: On 32 bit systems this doesn't handle int 64's.
-                         *        on 64 bit systems this doesn't work for 32 bit types
-			 */
-                        sprintf(bufaiter, fmtbufa, va_arg(valist, void *));
-                    }
-                }
-                while (*bufaiter)
-                {
-                    if (written++ >= len)
-                        return -1;
-                    *str++ = *bufaiter++;
-                }
-                iter++;
-                break;
-            }
-            }
-        }
-    }
-    if (written >= len)
-        return -1;
-    *str++ = 0;
-    return (int)written;
-}
-
-/*********************************************************************
- *		swprintf (MSVCRT.@)
- */
-int MSVCRT_swprintf( MSVCRT_wchar_t *str, const MSVCRT_wchar_t *format, ... )
-{
-    va_list ap;
-    int r;
-
-    va_start( ap, format );
-    r = MSVCRT_vsnprintfW( str, INT_MAX, format, ap );
-    va_end( ap );
-    return r;
-}
-
-/*********************************************************************
- *		_vsnwprintf (MSVCRT.@)
- */
-int _vsnwprintf(MSVCRT_wchar_t *str, unsigned int len,
-                const MSVCRT_wchar_t *format, va_list valist)
-{
-    return MSVCRT_vsnprintfW(str, len, format, valist);
-}
-
-/*********************************************************************
- *		vswprintf (MSVCRT.@)
- */
-int MSVCRT_vswprintf( MSVCRT_wchar_t* str, const MSVCRT_wchar_t* format, va_list args )
-{
-    return MSVCRT_vsnprintfW( str, INT_MAX, format, args );
-}
-
 /*********************************************************************
  *		wcscoll (MSVCRT.@)
  */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: printf.c
Type: text/x-csrc
Size: 11460 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20041127/5fa0be0c/printf.c
-------------- next part --------------
A non-text attachment was scrubbed...
Name: printfhelpers.c
Type: text/x-csrc
Size: 29701 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20041127/5fa0be0c/printfhelpers.c


More information about the wine-devel mailing list