ReactOS 0.4.16-dev-2279-gc890759
lcformatansi.c
Go to the documentation of this file.
1/*
2 * Locale-dependent format handling
3 *
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1998 David Lee Lambert
6 * Copyright 2000 Julio Cesar Gazquez
7 * Copyright 2003 Jon Griffiths
8 * Copyright 2005 Dmitry Timoshkov
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <k32.h>
26
27#define NDEBUG
28#include <debug.h>
30
31#include "lcformat_private.h"
32
33#ifndef CAL_SABBREVERASTRING
34#define CAL_SABBREVERASTRING 0x00000039
35#endif
36
37/**************************************************************************
38 * GetNumberFormatA (KERNEL32.@)
39 *
40 * Format a number string for a given locale.
41 *
42 * PARAMS
43 * lcid [I] Locale to format for
44 * dwFlags [I] LOCALE_ flags from "winnls.h"
45 * lpszValue [I] String to format
46 * lpFormat [I] Formatting overrides
47 * lpNumberStr [O] Destination for formatted string
48 * cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size
49 *
50 * NOTES
51 * - lpszValue can contain only '0' - '9', '-' and '.'.
52 * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
53 * be formatted according to the format details returned by GetLocaleInfoA().
54 * - This function rounds the number string if the number of decimals exceeds the
55 * locales normal number of decimal places.
56 * - If cchOut is 0, this function does not write to lpNumberStr.
57 * - The Ascii version of this function fails if lcid is Unicode only.
58 *
59 * RETURNS
60 * Success: The number of character written to lpNumberStr, or that would
61 * have been written, if cchOut is 0.
62 * Failure: 0. Use GetLastError() to determine the cause.
63 */
64
65/**************************************************************************
66 * GetNumberFormatA (KERNEL32.@)
67 */
69 LPCSTR lpszValue, const NUMBERFMTA *lpFormat,
70 LPSTR lpNumberStr, int cchOut)
71{
72 DWORD cp = CP_ACP;
73 WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
75 const NUMBERFMTW *pfmt = NULL;
76 INT iRet;
77
78 TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
79 lpFormat, lpNumberStr, cchOut);
80
82 {
84 return 0;
85 }
86
88 {
90 if (!cp)
91 {
93 return 0;
94 }
95 }
96
97 if (lpFormat)
98 {
99 memcpy(&fmt, lpFormat, sizeof(fmt));
100 pfmt = &fmt;
101 if (lpFormat->lpDecimalSep)
102 {
103 MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
104 fmt.lpDecimalSep = szDec;
105 }
106 if (lpFormat->lpThousandSep)
107 {
108 MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
109 fmt.lpThousandSep = szGrp;
110 }
111 }
112
113 if (lpszValue)
114 MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
115
116 if (cchOut > (int) ARRAY_SIZE(szOut))
117 cchOut = ARRAY_SIZE(szOut);
118
119 szOut[0] = '\0';
120
121 iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
122 lpNumberStr ? szOut : NULL, cchOut);
123
124 if (szOut[0] && lpNumberStr)
125 WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
126 return iRet;
127}
128
129/**************************************************************************
130 * GetCurrencyFormatA (KERNEL32.@)
131 *
132 * Format a currency string for a given locale.
133 *
134 * PARAMS
135 * lcid [I] Locale to format for
136 * dwFlags [I] LOCALE_ flags from "winnls.h"
137 * lpszValue [I] String to format
138 * lpFormat [I] Formatting overrides
139 * lpCurrencyStr [O] Destination for formatted string
140 * cchOut [I] Size of lpCurrencyStr, or 0 to calculate the resulting size
141 *
142 * NOTES
143 * - lpszValue can contain only '0' - '9', '-' and '.'.
144 * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
145 * be formatted according to the format details returned by GetLocaleInfoA().
146 * - This function rounds the currency if the number of decimals exceeds the
147 * locales number of currency decimal places.
148 * - If cchOut is 0, this function does not write to lpCurrencyStr.
149 * - The Ascii version of this function fails if lcid is Unicode only.
150 *
151 * RETURNS
152 * Success: The number of character written to lpNumberStr, or that would
153 * have been written, if cchOut is 0.
154 * Failure: 0. Use GetLastError() to determine the cause.
155 */
156
157/**************************************************************************
158 * GetCurrencyFormatA (KERNEL32.@)
159 */
161 LPCSTR lpszValue, const CURRENCYFMTA *lpFormat,
162 LPSTR lpCurrencyStr, int cchOut)
163{
164 DWORD cp = CP_ACP;
165 WCHAR szDec[8], szGrp[8], szCy[8], szIn[128], szOut[128];
167 const CURRENCYFMTW *pfmt = NULL;
168 INT iRet;
169
170 TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
171 lpFormat, lpCurrencyStr, cchOut);
172
174 {
176 return 0;
177 }
178
179 if (!(dwFlags & LOCALE_USE_CP_ACP))
180 {
182 if (!cp)
183 {
185 return 0;
186 }
187 }
188
189 if (lpFormat)
190 {
191 memcpy(&fmt, lpFormat, sizeof(fmt));
192 pfmt = &fmt;
193 if (lpFormat->lpDecimalSep)
194 {
195 MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
196 fmt.lpDecimalSep = szDec;
197 }
198 if (lpFormat->lpThousandSep)
199 {
200 MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
201 fmt.lpThousandSep = szGrp;
202 }
203 if (lpFormat->lpCurrencySymbol)
204 {
205 MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy));
206 fmt.lpCurrencySymbol = szCy;
207 }
208 }
209
210 if (lpszValue)
211 MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
212
213 if (cchOut > (int) ARRAY_SIZE(szOut))
214 cchOut = ARRAY_SIZE(szOut);
215
216 szOut[0] = '\0';
217
218 iRet = GetCurrencyFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
219 lpCurrencyStr ? szOut : NULL, cchOut);
220
221 if (szOut[0] && lpCurrencyStr)
222 WideCharToMultiByte(cp, 0, szOut, -1, lpCurrencyStr, cchOut, 0, 0);
223 return iRet;
224}
225
226/**************************************************************************
227 * EnumDateFormatsA (KERNEL32.@)
228 *
229 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
230 * LOCALE_NOUSEROVERRIDE here as well?
231 */
233{
234 struct enumdateformats_context ctxt;
235
236 ctxt.type = CALLBACK_ENUMPROC;
238 ctxt.lcid = lcid;
239 ctxt.flags = flags;
240 ctxt.unicode = FALSE;
241
242 return NLS_EnumDateFormats(&ctxt);
243}
244
245/**************************************************************************
246 * EnumTimeFormatsA (KERNEL32.@)
247 *
248 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
249 * LOCALE_NOUSEROVERRIDE here as well?
250 */
252{
253 struct enumtimeformats_context ctxt;
254
255 /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */
257 {
259 return FALSE;
260 }
261
262 ctxt.type = CALLBACK_ENUMPROC;
264 ctxt.lcid = lcid;
265 ctxt.flags = flags;
266 ctxt.unicode = FALSE;
267
268 return NLS_EnumTimeFormats(&ctxt);
269}
270
271/******************************************************************************
272 * EnumCalendarInfoA [KERNEL32.@]
273 */
274
276 CALID calendar, CALTYPE caltype)
277{
278 struct enumcalendar_context ctxt;
279
280 TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
281
282 ctxt.type = CALLBACK_ENUMPROC;
283 ctxt.u.callback = (CALINFO_ENUMPROCW)calinfoproc;
284 ctxt.lcid = locale;
285 ctxt.calendar = calendar;
286 ctxt.caltype = caltype;
287 ctxt.lParam = 0;
288 ctxt.unicode = FALSE;
289 return NLS_EnumCalendarInfo(&ctxt);
290}
291
292/**************************************************************************
293 * EnumCalendarInfoExA [KERNEL32.@]
294 */
297{
298 struct enumcalendar_context ctxt;
299
300 TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
301
303 ctxt.u.callbackex = (CALINFO_ENUMPROCEXW)calinfoproc;
304 ctxt.lcid = locale;
305 ctxt.calendar = calendar;
306 ctxt.caltype = caltype;
307 ctxt.lParam = 0;
308 ctxt.unicode = FALSE;
309 return NLS_EnumCalendarInfo(&ctxt);
310}
311
312/*********************************************************************
313 * GetCalendarInfoA (KERNEL32.@)
314 */
316 LPSTR lpCalData, int cchData, LPDWORD lpValue)
317{
318 int ret, cchDataW = cchData;
319 LPWSTR lpCalDataW = NULL;
320#ifdef __REACTOS__
321 DWORD cp = CP_ACP;
322 if (!(CalType & CAL_USE_CP_ACP))
323 {
324 DWORD dwFlags = ((CalType & CAL_NOUSEROVERRIDE) ? LOCALE_NOUSEROVERRIDE : 0);
326 if (!cp)
327 {
329 return 0;
330 }
331 }
332 if ((CalType & 0xFFFF) == CAL_SABBREVERASTRING)
333 {
334 /* NOTE: CAL_SABBREVERASTRING is not supported in GetCalendarInfoA */
336 return 0;
337 }
338#endif
339
341 {
343 return 0;
344 }
345
346 if (!cchData && !(CalType & CAL_RETURN_NUMBER))
347 cchDataW = GetCalendarInfoW(lcid, Calendar, CalType, NULL, 0, NULL);
348 if (!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchDataW*sizeof(WCHAR))))
349 return 0;
350
351 ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchDataW, lpValue);
352 if(ret && lpCalDataW && lpCalData)
353#ifdef __REACTOS__
354 ret = WideCharToMultiByte(cp, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
355#else
356 ret = WideCharToMultiByte(CP_ACP, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
357#endif
358 else if (CalType & CAL_RETURN_NUMBER)
359 ret *= sizeof(WCHAR);
360 HeapFree(GetProcessHeap(), 0, lpCalDataW);
361
362 return ret;
363}
364
365/*********************************************************************
366 * SetCalendarInfoA (KERNEL32.@)
367 */
368int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
369{
370 FIXME("(%08x,%08x,%08x,%s): stub\n",
371 Locale, Calendar, CalType, debugstr_a(lpCalData));
372 return 0;
373}
374
375/* EOF */
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
Definition: _locale.h:75
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
LCID lcid
Definition: locale.c:5656
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
#define debugstr_a
Definition: kernel32.h:31
#define nls
Definition: kernel32.h:13
BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt)
Definition: lcformat.c:1720
BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
Definition: lcformat.c:1852
BOOL NLS_IsUnicodeOnlyLcid(LCID lcid)
Definition: lcformat.c:372
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1130
DWORD NLS_GetAnsiCodePage(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:361
INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat, LPWSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1401
BOOL NLS_EnumCalendarInfo(const struct enumcalendar_context *ctxt)
Definition: lcformat.c:1959
int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPWSTR lpCalData, int cchData, LPDWORD lpValue)
Definition: lcformat.c:2144
@ CALLBACK_ENUMPROCEX
@ CALLBACK_ENUMPROC
#define CAL_SABBREVERASTRING
Definition: lcformatansi.c:34
BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
Definition: lcformatansi.c:251
BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformatansi.c:275
int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType, LPSTR lpCalData, int cchData, LPDWORD lpValue)
Definition: lcformatansi.c:315
INT WINAPI GetCurrencyFormatA(LCID lcid, DWORD dwFlags, LPCSTR lpszValue, const CURRENCYFMTA *lpFormat, LPSTR lpCurrencyStr, int cchOut)
Definition: lcformatansi.c:160
BOOL WINAPI EnumCalendarInfoExA(CALINFO_ENUMPROCEXA calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformatansi.c:295
INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags, LPCSTR lpszValue, const NUMBERFMTA *lpFormat, LPSTR lpNumberStr, int cchOut)
Definition: lcformatansi.c:68
int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
Definition: lcformatansi.c:368
BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
Definition: lcformatansi.c:232
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
static HANDLE proc()
Definition: pdb.c:34
DWORD LCID
Definition: nls.h:13
#define TRACE(s)
Definition: solgame.cpp:4
enum enum_callback_type type
CALINFO_ENUMPROCEXW callbackex
union enumcalendar_context::@453 u
CALINFO_ENUMPROCW callback
union enumdateformats_context::@451 u
DATEFMT_ENUMPROCW callback
enum enum_callback_type type
TIMEFMT_ENUMPROCW callback
union enumtimeformats_context::@452 u
enum enum_callback_type type
Definition: dsound.c:943
LPCWSTR lpFormat
Definition: trayclock.cpp:32
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_FLAGS
Definition: winerror.h:907
#define LOCALE_USE_CP_ACP
Definition: winnls.h:20
DWORD CALID
Definition: winnls.h:583
BOOL(CALLBACK * CALINFO_ENUMPROCW)(LPWSTR)
Definition: winnls.h:592
BOOL(CALLBACK * DATEFMT_ENUMPROCW)(LPWSTR)
Definition: winnls.h:607
DWORD CALTYPE
Definition: winnls.h:582
BOOL(CALLBACK * CALINFO_ENUMPROCA)(LPSTR)
Definition: winnls.h:591
BOOL(CALLBACK * TIMEFMT_ENUMPROCA)(LPSTR)
Definition: winnls.h:610
BOOL(CALLBACK * CALINFO_ENUMPROCEXA)(LPSTR, CALID)
Definition: winnls.h:593
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
BOOL(CALLBACK * TIMEFMT_ENUMPROCW)(LPWSTR)
Definition: winnls.h:611
BOOL(CALLBACK * DATEFMT_ENUMPROCA)(LPSTR)
Definition: winnls.h:606
BOOL(CALLBACK * CALINFO_ENUMPROCEXW)(LPWSTR, CALID)
Definition: winnls.h:594
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182