CVS: winex/unicode string.c,1.2,1.3

[email protected] 14 Dec 2007 20:19:56 -0000
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/unicode string.c,1.2,1.3Update of /var/lib/cvsd/cvsroot/winex/unicode
In directory agravaine:/tmp/cvs-serv15480/unicode

Modified Files:
	string.c 
Log Message:
Moved the wide-character sprintf implementations in ntdll and msvcrt into
libwine_unicode.


Index: string.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/unicode/string.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- string.c	25 Aug 2005 19:38:33 -0000	1.2
+++ string.c	14 Dec 2007 20:19:54 -0000	1.3
@@ -5,7 +5,9 @@
  * Copyright 2005 TransGaming Technologies, Inc
  */
 
+#include <stdio.h>
 #include <stdlib.h>
+#include <limits.h>
 #include "wine/unicode.h"
 
 int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
@@ -102,3 +104,149 @@
     return ret;
 }
 
+int vsnprintfW( WCHAR *str, unsigned int 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 != (WCHAR)L'%')
+    {
+     if (written++ >= len)
+       return -1;
+     *str++ = *iter++;
+    }
+    if (*iter == (WCHAR)L'%')
+    {
+      fmta = fmtbufa;
+      *fmta++ = *iter++;
+      while (*iter == (WCHAR)L'0' ||
+             *iter == (WCHAR)L'+' ||
+             *iter == (WCHAR)L'-' ||
+             *iter == (WCHAR)L' ' ||
+             *iter == (WCHAR)L'0' ||
+             *iter == (WCHAR)L'*' ||
+             *iter == (WCHAR)L'#')
+      {
+        if (*iter == (WCHAR)L'*')
+        {
+          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 == (WCHAR)L'.')
+      {
+        *fmta++ = *iter++;
+        if (*iter == (WCHAR)L'*')
+        {
+          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 == (WCHAR)L'h' ||
+          *iter == (WCHAR)L'l')
+      {
+          *fmta++ = *iter++;
+          *fmta++ = *iter++;
+      }
+
+      switch (*iter)
+      {
+      case (WCHAR)L'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 (WCHAR)L'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 == (WCHAR)L'p')
+            sprintf(bufaiter, "%08lX", va_arg(valist, long));
+          else
+          {
+            *fmta++ = *iter;
+            *fmta = '\0';
+            if (*iter == (WCHAR)L'f')
+              sprintf(bufaiter, fmtbufa, va_arg(valist, double));
+            else
+              sprintf(bufaiter, fmtbufa, va_arg(valist, void *));
+          }
+          while (*bufaiter)
+          {
+            if (written++ >= len)
+              return -1;
+            *str++ = *bufaiter++;
+          }
+          iter++;
+          break;
+        }
+      }
+    }
+  }
+  if (written >= len)
+    return -1;
+  *str++ = (WCHAR)L'\0';
+  return (int)written;
+}
+
+int vsprintfW( WCHAR* str, const WCHAR* format, va_list args )
+{
+  return vsnprintfW(str, INT_MAX, format, args);
+}
+
+int snprintfW( WCHAR *str, unsigned int len, const WCHAR *format, ... )
+{
+  int retval;
+  va_list valist;
+  va_start(valist, format);
+  retval = vsnprintfW(str, len, format, valist);
+  va_end(valist);
+  return retval;
+}
+
+int sprintfW( WCHAR *str, const WCHAR *format, ... )
+{
+  int retval;
+  va_list valist;
+  va_start(valist, format);
+  retval = vsnprintfW(str, INT_MAX, format, valist);
+  va_end(valist);
+  return retval;
+}