Alexandre Julliard : kernel32: Reimplement GetNumberFormatA().

Alexandre Julliard julliard at winehq.org
Tue May 3 15:39:23 CDT 2022


Module: wine
Branch: master
Commit: b6bf69ef804146f81b803719a72d8c6afde184ba
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b6bf69ef804146f81b803719a72d8c6afde184ba

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue May  3 10:35:27 2022 +0200

kernel32: Reimplement GetNumberFormatA().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/kernel32/lcformat.c | 90 ------------------------------------------------
 dlls/kernel32/locale.c   | 53 ++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 90 deletions(-)

diff --git a/dlls/kernel32/lcformat.c b/dlls/kernel32/lcformat.c
index 7f112767880..a38edcc7758 100644
--- a/dlls/kernel32/lcformat.c
+++ b/dlls/kernel32/lcformat.c
@@ -986,96 +986,6 @@ INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
                                 lpFormat, lpTimeStr, cchOut);
 }
 
-/**************************************************************************
- *              GetNumberFormatA	(KERNEL32.@)
- *
- * Format a number string for a given locale.
- *
- * PARAMS
- *  lcid        [I] Locale to format for
- *  dwFlags     [I] LOCALE_ flags from "winnls.h"
- *  lpszValue   [I] String to format
- *  lpFormat    [I] Formatting overrides
- *  lpNumberStr [O] Destination for formatted string
- *  cchOut      [I] Size of lpNumberStr, or 0 to calculate the resulting size
- *
- * NOTES
- *  - lpszValue can contain only '0' - '9', '-' and '.'.
- *  - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
- *    be formatted according to the format details returned by GetLocaleInfoA().
- *  - This function rounds the number string if the number of decimals exceeds the
- *    locales normal number of decimal places.
- *  - If cchOut is 0, this function does not write to lpNumberStr.
- *  - The ANSI version of this function fails if lcid is Unicode only.
- *
- * RETURNS
- *  Success: The number of character written to lpNumberStr, or that would
- *           have been written, if cchOut is 0.
- *  Failure: 0. Use GetLastError() to determine the cause.
- */
-INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags,
-                            LPCSTR lpszValue,  const NUMBERFMTA *lpFormat,
-                            LPSTR lpNumberStr, int cchOut)
-{
-  DWORD cp = CP_ACP;
-  WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
-  NUMBERFMTW fmt;
-  const NUMBERFMTW *pfmt = NULL;
-  INT iRet;
-
-  TRACE("(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
-        lpFormat, lpNumberStr, cchOut);
-
-  if (NLS_IsUnicodeOnlyLcid(lcid))
-  {
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return 0;
-  }
-
-  if (!(dwFlags & LOCALE_USE_CP_ACP))
-  {
-    const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
-    if (!node)
-    {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return 0;
-    }
-
-    cp = node->dwCodePage;
-  }
-
-  if (lpFormat)
-  {
-    memcpy(&fmt, lpFormat, sizeof(fmt));
-    pfmt = &fmt;
-    if (lpFormat->lpDecimalSep)
-    {
-      MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
-      fmt.lpDecimalSep = szDec;
-    }
-    if (lpFormat->lpThousandSep)
-    {
-      MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
-      fmt.lpThousandSep = szGrp;
-    }
-  }
-
-  if (lpszValue)
-    MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
-
-  if (cchOut > (int) ARRAY_SIZE(szOut))
-    cchOut = ARRAY_SIZE(szOut);
-
-  szOut[0] = '\0';
-
-  iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
-                          lpNumberStr ? szOut : NULL, cchOut);
-
-  if (szOut[0] && lpNumberStr)
-    WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
-  return iRet;
-}
-
 /* Number parsing state flags */
 #define NF_ISNEGATIVE 0x1  /* '-' found */
 #define NF_ISREAL     0x2  /* '.' found */
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c
index 2187d3e2883..c6cbec870e2 100644
--- a/dlls/kernel32/locale.c
+++ b/dlls/kernel32/locale.c
@@ -411,6 +411,59 @@ int WINAPI SetCalendarInfoA( LCID lcid, CALID id, CALTYPE type, LPCSTR data )
 }
 
 
+/**************************************************************************
+ *           GetNumberFormatA (KERNEL32.@)
+ */
+int WINAPI GetNumberFormatA( LCID lcid, DWORD flags, const char *value,
+                             const NUMBERFMTA *format, char *buffer, int len )
+{
+    UINT cp = get_lcid_codepage( lcid, flags );
+    WCHAR input[128], output[128];
+    int ret;
+
+    TRACE( "(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, flags, debugstr_a(value), format, buffer, len );
+
+    if (len < 0 || (len && !buffer) || !value)
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+    MultiByteToWideChar( cp, 0, value, -1, input, ARRAY_SIZE(input) );
+
+    if (len > (int)ARRAY_SIZE(output)) len = ARRAY_SIZE(output);
+
+    if (format)
+    {
+        NUMBERFMTW fmt;
+        WCHAR fmt_decimal[4], fmt_thousand[4];
+
+        if (flags & LOCALE_NOUSEROVERRIDE)
+        {
+            SetLastError( ERROR_INVALID_FLAGS );
+            return 0;
+        }
+        if (!format->lpDecimalSep || !format->lpThousandSep)
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            return 0;
+        }
+        MultiByteToWideChar( cp, 0, format->lpDecimalSep, -1, fmt_decimal, ARRAY_SIZE(fmt_decimal) );
+        MultiByteToWideChar( cp, 0, format->lpThousandSep, -1, fmt_thousand, ARRAY_SIZE(fmt_thousand) );
+        fmt.NumDigits     = format->NumDigits;
+        fmt.LeadingZero   = format->LeadingZero;
+        fmt.Grouping      = format->Grouping;
+        fmt.NegativeOrder = format->NegativeOrder;
+        fmt.lpDecimalSep  = fmt_decimal;
+        fmt.lpThousandSep = fmt_thousand;
+        ret = GetNumberFormatW( lcid, flags, input, &fmt, output, len );
+    }
+    else ret = GetNumberFormatW( lcid, flags, input, NULL, output, len );
+
+    if (ret) ret = WideCharToMultiByte( cp, 0, output, -1, buffer, len, 0, 0 );
+    return ret;
+}
+
+
 /******************************************************************************
  *           GetGeoInfoA (KERNEL32.@)
  */




More information about the wine-cvs mailing list