1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************************
383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius*   Copyright (C) 2005-2011, International Business Machines
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File WINNMTST.CPP
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************************
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/format.h"
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/numfmt.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/locid.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/testlog.h"
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utmscale.h"
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "winnmfmt.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "winutil.h"
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "winnmtst.h"
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h"
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "locmap.h"
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "wintz.h"
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h"
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define WIN32_LEAN_AND_MEAN
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define VC_EXTRALEAN
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOUSER
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOSERVICE
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOIME
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   define NOMCX
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <windows.h>
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <stdio.h>
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <time.h>
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <float.h>
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#   include <locale.h>
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define NEW_ARRAY(type,count) (type *) uprv_malloc((count) * sizeof(type))
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DELETE_ARRAY(array) uprv_free((void *) (array))
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define STACK_BUFFER_SIZE 32
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LOOP_COUNT 1000
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool initialized = FALSE;
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return a random int64_t where U_INT64_MIN <= ran <= U_INT64_MAX.
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint64_t randomInt64(void)
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int64_t ran = 0;
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i;
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!initialized) {
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        srand((unsigned)time(NULL));
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        initialized = TRUE;
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Assume rand has at least 12 bits of precision */
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (i = 0; i < sizeof(ran); i += 1) {
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4);
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ran;
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return a random double where U_DOUBLE_MIN <= ran <= U_DOUBLE_MAX.
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic double randomDouble(void)
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    double ran = 0;
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!initialized) {
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        srand((unsigned)time(NULL));
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        initialized = TRUE;
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i;
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    do {
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* Assume rand has at least 12 bits of precision */
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        for (i = 0; i < sizeof(ran); i += 1) {
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4);
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } while (_isnan(ran));
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	int64_t numerator = randomInt64();
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	int64_t denomenator;
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    do {
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        denomenator = randomInt64();
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (denomenator == 0);
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru	ran = (double)numerator / (double)denomenator;
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ran;
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Return a random int32_t where U_INT32_MIN <= ran <= U_INT32_MAX.
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t randomInt32(void)
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t ran = 0;
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t i;
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!initialized) {
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        srand((unsigned)time(NULL));
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        initialized = TRUE;
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Assume rand has at least 12 bits of precision */
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (i = 0; i < sizeof(ran); i += 1) {
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        ((char*)&ran)[i] = (char)((rand() & 0x0FF0) >> 4);
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return ran;
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UnicodeString &getWindowsFormat(int32_t lcid, UBool currency, UnicodeString &appendTo, const wchar_t *fmt, ...)
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    wchar_t nStackBuffer[STACK_BUFFER_SIZE];
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    wchar_t *nBuffer = nStackBuffer;
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    va_list args;
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int result;
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    nBuffer[0] = 0x0000;
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Due to the arguments causing a result to be <= 23 characters (+2 for NULL and minus),
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    we don't need to reallocate the buffer. */
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    va_start(args, fmt);
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    result = _vsnwprintf(nBuffer, STACK_BUFFER_SIZE, fmt, args);
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    va_end(args);
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Just to make sure of the above statement, we add this assert */
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_ASSERT(result >=0);
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // The following code is not used because _vscwprintf isn't available on MinGW at the moment.
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*if (result < 0) {
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int newLength;
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        va_start(args, fmt);
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newLength = _vscwprintf(fmt, args);
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        va_end(args);
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        nBuffer = NEW_ARRAY(UChar, newLength + 1);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        va_start(args, fmt);
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result = _vsnwprintf(nBuffer, newLength + 1, fmt, args);
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        va_end(args);
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }*/
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // vswprintf is sensitive to the locale set by setlocale. For some locales
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // it doesn't use "." as the decimal separator, which is what GetNumberFormatW
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // and GetCurrencyFormatW both expect to see.
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // To fix this, we scan over the string and replace the first non-digits, except
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // for a leading "-", with a "."
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    //
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Note: (nBuffer[0] == L'-') will evaluate to 1 if there is a leading '-' in the
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // number, and 0 otherwise.
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (wchar_t *p = &nBuffer[nBuffer[0] == L'-']; *p != L'\0'; p += 1) {
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (*p < L'0' || *p > L'9') {
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *p = L'.';
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    wchar_t stackBuffer[STACK_BUFFER_SIZE];
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    wchar_t *buffer = stackBuffer;
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    buffer[0] = 0x0000;
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (currency) {
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result = GetCurrencyFormatW(lcid, 0, nBuffer, NULL, buffer, STACK_BUFFER_SIZE);
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (result == 0) {
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            DWORD lastError = GetLastError();
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (lastError == ERROR_INSUFFICIENT_BUFFER) {
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                int newLength = GetCurrencyFormatW(lcid, 0, nBuffer, NULL, NULL, 0);
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                buffer = NEW_ARRAY(UChar, newLength);
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                buffer[0] = 0x0000;
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                GetCurrencyFormatW(lcid, 0, nBuffer, NULL, buffer, newLength);
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result = GetNumberFormatW(lcid, 0, nBuffer, NULL, buffer, STACK_BUFFER_SIZE);
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (result == 0) {
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            DWORD lastError = GetLastError();
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (lastError == ERROR_INSUFFICIENT_BUFFER) {
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                int newLength = GetNumberFormatW(lcid, 0, nBuffer, NULL, NULL, 0);
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                buffer = NEW_ARRAY(UChar, newLength);
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                buffer[0] = 0x0000;
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                GetNumberFormatW(lcid, 0, nBuffer, NULL, buffer, newLength);
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    appendTo.append(buffer, (int32_t) wcslen(buffer));
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (buffer != stackBuffer) {
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        DELETE_ARRAY(buffer);
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*if (nBuffer != nStackBuffer) {
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        DELETE_ARRAY(nBuffer);
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }*/
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return appendTo;
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void testLocale(const char *localeID, int32_t lcid, NumberFormat *wnf, UBool currency, TestLog *log)
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int n = 0; n < LOOP_COUNT; n += 1) {
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString u3Buffer, u6Buffer, udBuffer;
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UnicodeString w3Buffer, w6Buffer, wdBuffer;
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        double d    = randomDouble();
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t i32 = randomInt32();
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int64_t i64 = randomInt64();
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getWindowsFormat(lcid, currency, wdBuffer, L"%.16f", d);
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getWindowsFormat(lcid, currency, w3Buffer, L"%I32d", i32);
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        getWindowsFormat(lcid, currency, w6Buffer, L"%I64d", i64);
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        wnf->format(d,   udBuffer);
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (udBuffer.compare(wdBuffer) != 0) {
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UnicodeString locale(localeID);
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            log->errln("Double format error for locale " + locale +
24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    ": got " + udBuffer + " expected " + wdBuffer);
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        wnf->format(i32, u3Buffer);
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (u3Buffer.compare(w3Buffer) != 0) {
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UnicodeString locale(localeID);
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            log->errln("int32_t format error for locale " + locale +
25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    ": got " + u3Buffer + " expected " + w3Buffer);
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        wnf->format(i64, u6Buffer);
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (u6Buffer.compare(w6Buffer) != 0) {
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UnicodeString locale(localeID);
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            log->errln("int64_t format error for locale " + locale +
26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                                    ": got " + u6Buffer + " expected " + w6Buffer);
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Win32NumberTest::testLocales(TestLog *log)
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t lcidCount = 0;
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount);
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(int i = 0; i < lcidCount; i += 1) {
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char localeID[128];
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        // NULL localeID means ICU didn't recognize the lcid
28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        if (lcidRecords[i].localeID == NULL) {
28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            continue;
28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        }
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        strcpy(localeID, lcidRecords[i].localeID);
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (strchr(localeID, '@') > 0) {
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            strcat(localeID, ";");
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            strcat(localeID, "@");
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        strcat(localeID, "compat=host");
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        Locale ulocale(localeID);
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        NumberFormat *wnf = NumberFormat::createInstance(ulocale, status);
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        NumberFormat *wcf = NumberFormat::createCurrencyInstance(ulocale, status);
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wnf, FALSE, log);
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wcf, TRUE,  log);
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        char *old_locale = strdup(setlocale(LC_ALL, NULL));
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setlocale(LC_ALL, "German");
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wnf, FALSE, log);
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        testLocale(lcidRecords[i].localeID, lcidRecords[i].lcid, wcf, TRUE,  log);
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setlocale(LC_ALL, old_locale);
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        free(old_locale);
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete wcf;
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete wnf;
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Win32Utilities::freeLocales(lcidRecords);
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
32383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#endif /* U_PLATFORM_USES_ONLY_WIN32_API */
324