ReactOS 0.4.15-dev-7788-g1ad9096
lcformat.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 César Gázquez
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#ifdef __REACTOS__
26
27#include <k32.h>
28#include "japanese.h" /* Japanese eras */
29
30#define NDEBUG
31#include <debug.h>
33
34#undef _WIN32_WINNT
35#undef WINVER
36#define _WIN32_WINNT DLL_EXPORT_VERSION
37#define WINVER DLL_EXPORT_VERSION
38
39LCID WINAPI LocaleNameToLCID(_In_ LPCWSTR, _In_ DWORD);
40#define LOCALE_SSHORTESTDAYNAME1 96
41#define LOCALE_SSHORTESTDAYNAME2 97
42#define LOCALE_SSHORTESTDAYNAME3 98
43#define LOCALE_SSHORTESTDAYNAME4 99
44#define LOCALE_SSHORTESTDAYNAME5 100
45#define LOCALE_SSHORTESTDAYNAME6 101
46#define LOCALE_SSHORTESTDAYNAME7 102
47
48#define CRITICAL_SECTION RTL_CRITICAL_SECTION
49#define CRITICAL_SECTION_DEBUG RTL_CRITICAL_SECTION_DEBUG
50#define CALINFO_MAX_YEAR 2029
51
52#define IS_LCID_JAPANESE(lcid) PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_JAPANESE
53
54#ifndef CAL_SABBREVERASTRING
55 #define CAL_SABBREVERASTRING 0x00000039
56#endif
57
58#else /* __REACTOS__ */
59
60#include "config.h"
61#include "wine/port.h"
62
63#include <string.h>
64#include <stdarg.h>
65#include <stdio.h>
66#include <stdlib.h>
67
68#include "windef.h"
69#include "winbase.h"
70#include "wine/unicode.h"
71#include "wine/debug.h"
72#include "winternl.h"
73
74#include "kernel_private.h"
75
77
78#endif /* __REACTOS__ */
79
80#define DATE_DATEVARSONLY 0x0100 /* only date stuff: yMdg */
81#define TIME_TIMEVARSONLY 0x0200 /* only time stuff: hHmst */
82
83/* Since calculating the formatting data for each locale is time-consuming,
84 * we get the format data for each locale only once and cache it in memory.
85 * We cache both the system default and user overridden data, after converting
86 * them into the formats that the functions here expect. Since these functions
87 * will typically be called with only a small number of the total locales
88 * installed, the memory overhead is minimal while the speedup is significant.
89 *
90 * Our cache takes the form of a singly linked list, whose node is below:
91 */
92#define NLS_NUM_CACHED_STRINGS 57
93
94typedef struct _NLS_FORMAT_NODE
95{
96 LCID lcid; /* Locale Id */
97 DWORD dwFlags; /* 0 or LOCALE_NOUSEROVERRIDE */
98 DWORD dwCodePage; /* Default code page (if LOCALE_USE_ANSI_CP not given) */
99 NUMBERFMTW fmt; /* Default format for numbers */
100 CURRENCYFMTW cyfmt; /* Default format for currencies */
101 LPWSTR lppszStrings[NLS_NUM_CACHED_STRINGS]; /* Default formats,day/month names */
102 WCHAR szShortAM[2]; /* Short 'AM' marker */
103 WCHAR szShortPM[2]; /* Short 'PM' marker */
106
107/* Macros to get particular data strings from a format node */
108#define GetNegative(fmt) fmt->lppszStrings[0]
109#define GetLongDate(fmt) fmt->lppszStrings[1]
110#define GetShortDate(fmt) fmt->lppszStrings[2]
111#define GetTime(fmt) fmt->lppszStrings[3]
112#define GetAM(fmt) fmt->lppszStrings[54]
113#define GetPM(fmt) fmt->lppszStrings[55]
114#define GetYearMonth(fmt) fmt->lppszStrings[56]
115
116#define GetLongDay(fmt,day) fmt->lppszStrings[4 + day]
117#define GetShortDay(fmt,day) fmt->lppszStrings[11 + day]
118#define GetLongMonth(fmt,mth) fmt->lppszStrings[18 + mth]
119#define GetGenitiveMonth(fmt,mth) fmt->lppszStrings[30 + mth]
120#define GetShortMonth(fmt,mth) fmt->lppszStrings[42 + mth]
121
122/* Write access to the cache is protected by this critical section */
125{
126 0, 0, &NLS_FormatsCS,
129#ifdef __REACTOS__
130 0, 0, 0
131#else
132 0, 0, { (DWORD_PTR)(__FILE__ ": NLS_Formats") }
133#endif
134};
135static CRITICAL_SECTION NLS_FormatsCS = { &NLS_FormatsCS_debug, -1, 0, 0, 0, 0 };
136
137/**************************************************************************
138 * NLS_GetLocaleNumber <internal>
139 *
140 * Get a numeric locale format value.
141 */
143{
144 WCHAR szBuff[80];
145 DWORD dwVal = 0;
146
147 szBuff[0] = '\0';
148 GetLocaleInfoW(lcid, dwFlags, szBuff, ARRAY_SIZE(szBuff));
149
150 if (szBuff[0] && szBuff[1] == ';' && szBuff[2] != '0')
151 dwVal = (szBuff[0] - '0') * 10 + (szBuff[2] - '0');
152 else
153 {
154 const WCHAR* iter = szBuff;
155 dwVal = 0;
156 while(*iter >= '0' && *iter <= '9')
157 dwVal = dwVal * 10 + (*iter++ - '0');
158 }
159 return dwVal;
160}
161
162/**************************************************************************
163 * NLS_GetLocaleString <internal>
164 *
165 * Get a string locale format value.
166 */
168{
169 WCHAR szBuff[80], *str;
170 DWORD dwLen;
171
172 szBuff[0] = '\0';
173 GetLocaleInfoW(lcid, dwFlags, szBuff, ARRAY_SIZE(szBuff));
174 dwLen = strlenW(szBuff) + 1;
175 str = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(WCHAR));
176 if (str)
177 memcpy(str, szBuff, dwLen * sizeof(WCHAR));
178 return str;
179}
180
181#define GET_LOCALE_NUMBER(num, type) num = NLS_GetLocaleNumber(lcid, type|dwFlags); \
182 TRACE( #type ": %d (%08x)\n", (DWORD)num, (DWORD)num)
183
184#define GET_LOCALE_STRING(str, type) str = NLS_GetLocaleString(lcid, type|dwFlags); \
185 TRACE( #type ": %s\n", debugstr_w(str))
186
187/**************************************************************************
188 * NLS_GetFormats <internal>
189 *
190 * Calculate (and cache) the number formats for a locale.
191 */
193{
194 /* GetLocaleInfo() identifiers for cached formatting strings */
195 static const LCTYPE NLS_LocaleIndices[] = {
225 LOCALE_SYEARMONTH
226 };
227 static NLS_FORMAT_NODE *NLS_CachedFormats = NULL;
228 NLS_FORMAT_NODE *node = NLS_CachedFormats;
229
231
232 TRACE("(0x%04x,0x%08x)\n", lcid, dwFlags);
233
234 /* See if we have already cached the locales number format */
235 while (node && (node->lcid != lcid || node->dwFlags != dwFlags) && node->next)
236 node = node->next;
237
238 if (!node || node->lcid != lcid || node->dwFlags != dwFlags)
239 {
240 NLS_FORMAT_NODE *new_node;
241 DWORD i;
242
243 TRACE("Creating new cache entry\n");
244
245 if (!(new_node = HeapAlloc(GetProcessHeap(), 0, sizeof(NLS_FORMAT_NODE))))
246 return NULL;
247
249
250 /* Number Format */
251 new_node->lcid = lcid;
252 new_node->dwFlags = dwFlags;
253 new_node->next = NULL;
254
258
260 if (new_node->fmt.Grouping > 9 && new_node->fmt.Grouping != 32)
261 {
262 WARN("LOCALE_SGROUPING (%d) unhandled, please report!\n",
263 new_node->fmt.Grouping);
264 new_node->fmt.Grouping = 0;
265 }
266
269
270 /* Currency Format */
271 new_node->cyfmt.NumDigits = new_node->fmt.NumDigits;
272 new_node->cyfmt.LeadingZero = new_node->fmt.LeadingZero;
273
275
276 if (new_node->cyfmt.Grouping > 9)
277 {
278 WARN("LOCALE_SMONGROUPING (%d) unhandled, please report!\n",
279 new_node->cyfmt.Grouping);
280 new_node->cyfmt.Grouping = 0;
281 }
282
284 if (new_node->cyfmt.NegativeOrder > 15)
285 {
286 WARN("LOCALE_INEGCURR (%d) unhandled, please report!\n",
287 new_node->cyfmt.NegativeOrder);
288 new_node->cyfmt.NegativeOrder = 0;
289 }
291 if (new_node->cyfmt.PositiveOrder > 3)
292 {
293 WARN("LOCALE_IPOSCURR (%d) unhandled,please report!\n",
294 new_node->cyfmt.PositiveOrder);
295 new_node->cyfmt.PositiveOrder = 0;
296 }
300
301 /* Date/Time Format info, negative character, etc */
302 for (i = 0; i < ARRAY_SIZE(NLS_LocaleIndices); i++)
303 {
304 GET_LOCALE_STRING(new_node->lppszStrings[i], NLS_LocaleIndices[i]);
305 }
306 /* Save some memory if month genitive name is the same or not present */
307 for (i = 0; i < 12; i++)
308 {
309 if (strcmpW(GetLongMonth(new_node, i), GetGenitiveMonth(new_node, i)) == 0)
310 {
311 HeapFree(GetProcessHeap(), 0, GetGenitiveMonth(new_node, i));
312 GetGenitiveMonth(new_node, i) = NULL;
313 }
314 }
315
316 new_node->szShortAM[0] = GetAM(new_node)[0]; new_node->szShortAM[1] = '\0';
317 new_node->szShortPM[0] = GetPM(new_node)[0]; new_node->szShortPM[1] = '\0';
318
319 /* Now add the computed format to the cache */
321
322 /* Search again: We may have raced to add the node */
323 node = NLS_CachedFormats;
324 while (node && (node->lcid != lcid || node->dwFlags != dwFlags) && node->next)
325 node = node->next;
326
327 if (!node)
328 {
329 node = NLS_CachedFormats = new_node; /* Empty list */
330 new_node = NULL;
331 }
332 else if (node->lcid != lcid || node->dwFlags != dwFlags)
333 {
334 node->next = new_node; /* Not in the list, add to end */
335 node = new_node;
336 new_node = NULL;
337 }
338
340
341 if (new_node)
342 {
343 /* We raced and lost: The node was already added by another thread.
344 * node points to the currently cached node, so free new_node.
345 */
346 for (i = 0; i < ARRAY_SIZE(NLS_LocaleIndices); i++)
347 HeapFree(GetProcessHeap(), 0, new_node->lppszStrings[i]);
348 HeapFree(GetProcessHeap(), 0, new_node->fmt.lpDecimalSep);
349 HeapFree(GetProcessHeap(), 0, new_node->fmt.lpThousandSep);
350 HeapFree(GetProcessHeap(), 0, new_node->cyfmt.lpDecimalSep);
353 HeapFree(GetProcessHeap(), 0, new_node);
354 }
355 }
356 return node;
357}
358
359/**************************************************************************
360 * NLS_IsUnicodeOnlyLcid <internal>
361 *
362 * Determine if a locale is Unicode only, and thus invalid in ASCII calls.
363 */
365{
367
368 switch (PRIMARYLANGID(lcid))
369 {
370 case LANG_ARMENIAN:
371 case LANG_DIVEHI:
372 case LANG_GEORGIAN:
373 case LANG_GUJARATI:
374 case LANG_HINDI:
375 case LANG_KANNADA:
376 case LANG_KONKANI:
377 case LANG_MARATHI:
378 case LANG_PUNJABI:
379 case LANG_SANSKRIT:
380 TRACE("lcid 0x%08x: langid 0x%4x is Unicode Only\n", lcid, PRIMARYLANGID(lcid));
381 return TRUE;
382 default:
383 return FALSE;
384 }
385}
386
387/*
388 * Formatting of dates, times, numbers and currencies.
389 */
390
391#define IsLiteralMarker(p) (p == '\'')
392#define IsDateFmtChar(p) (p == 'd'||p == 'M'||p == 'y'||p == 'g')
393#define IsTimeFmtChar(p) (p == 'H'||p == 'h'||p == 'm'||p == 's'||p == 't')
394
395/* Only the following flags can be given if a date/time format is specified */
396#ifdef __REACTOS__
397#define DATE_FORMAT_FLAGS (DATE_DATEVARSONLY | DATE_USE_ALT_CALENDAR)
398#else
399#define DATE_FORMAT_FLAGS (DATE_DATEVARSONLY)
400#endif
401#define TIME_FORMAT_FLAGS (TIME_TIMEVARSONLY|TIME_FORCE24HOURFORMAT| \
402 TIME_NOMINUTESORSECONDS|TIME_NOSECONDS| \
403 TIME_NOTIMEMARKER)
404
405/******************************************************************************
406 * NLS_GetDateTimeFormatW <internal>
407 *
408 * Performs the formatting for GetDateFormatW/GetTimeFormatW.
409 *
410 * FIXME
411 * DATE_USE_ALT_CALENDAR - Requires GetCalendarInfo to work first.
412 * DATE_LTRREADING/DATE_RTLREADING - Not yet implemented.
413 */
415 const SYSTEMTIME* lpTime, LPCWSTR lpFormat,
416 LPWSTR lpStr, INT cchOut)
417{
418 const NLS_FORMAT_NODE *node;
419 SYSTEMTIME st;
420 INT cchWritten = 0;
421 INT lastFormatPos = 0;
422 BOOL bSkipping = FALSE; /* Skipping text around marker? */
423 BOOL d_dd_formatted = FALSE; /* previous formatted part was for d or dd */
424
425 /* Verify our arguments */
426 if ((cchOut && !lpStr) || !(node = NLS_GetFormats(lcid, dwFlags)))
427 goto invalid_parameter;
428
430 {
431 if (lpFormat &&
434 {
435 goto invalid_flags;
436 }
437
439 {
440 if ((dwFlags & (DATE_LTRREADING|DATE_RTLREADING)) == (DATE_LTRREADING|DATE_RTLREADING))
441 goto invalid_flags;
442 else if (dwFlags & (DATE_LTRREADING|DATE_RTLREADING))
443 FIXME("Unsupported flags: DATE_LTRREADING/DATE_RTLREADING\n");
444
445 switch (dwFlags & (DATE_SHORTDATE|DATE_LONGDATE|DATE_YEARMONTH))
446 {
447 case 0:
448 break;
449 case DATE_SHORTDATE:
450 case DATE_LONGDATE:
451 case DATE_YEARMONTH:
452 if (lpFormat)
453 goto invalid_flags;
454 break;
455 default:
456 goto invalid_flags;
457 }
458 }
459 }
460
461 if (!lpFormat)
462 {
463 /* Use the appropriate default format */
465 {
466 if (dwFlags & DATE_YEARMONTH)
468 else if (dwFlags & DATE_LONGDATE)
470 else
472 }
473 else
475 }
476
477 if (!lpTime)
478 {
479 GetLocalTime(&st); /* Default to current time */
480 lpTime = &st;
481 }
482 else
483 {
485 {
486 FILETIME ftTmp;
487
488 /* Verify the date and correct the D.O.W. if needed */
489 memset(&st, 0, sizeof(st));
490 st.wYear = lpTime->wYear;
491 st.wMonth = lpTime->wMonth;
492 st.wDay = lpTime->wDay;
493
494 if (st.wDay > 31 || st.wMonth > 12 || !SystemTimeToFileTime(&st, &ftTmp))
495 goto invalid_parameter;
496
497 FileTimeToSystemTime(&ftTmp, &st);
498 lpTime = &st;
499 }
500
502 {
503 /* Verify the time */
504 if (lpTime->wHour > 24 || lpTime->wMinute > 59 || lpTime->wSecond > 59)
505 goto invalid_parameter;
506 }
507 }
508
509 /* Format the output */
510 while (*lpFormat)
511 {
513 {
514 /* Start of a literal string */
515 lpFormat++;
516
517 /* Loop until the end of the literal marker or end of the string */
518 while (*lpFormat)
519 {
521 {
522 lpFormat++;
524 break; /* Terminating literal marker */
525 }
526
527 if (!cchOut)
528 cchWritten++; /* Count size only */
529 else if (cchWritten >= cchOut)
530 goto overrun;
531 else if (!bSkipping)
532 {
533 lpStr[cchWritten] = *lpFormat;
534 cchWritten++;
535 }
536 lpFormat++;
537 }
538 }
541 {
542 WCHAR buff[32], fmtChar;
543 LPCWSTR szAdd = NULL;
544 DWORD dwVal = 0;
545 int count = 0, dwLen;
546
547 bSkipping = FALSE;
548
549 fmtChar = *lpFormat;
550 while (*lpFormat == fmtChar)
551 {
552 count++;
553 lpFormat++;
554 }
555 buff[0] = '\0';
556
557 if (fmtChar != 'M') d_dd_formatted = FALSE;
558 switch(fmtChar)
559 {
560 case 'd':
561 if (count >= 4)
562 szAdd = GetLongDay(node, (lpTime->wDayOfWeek + 6) % 7);
563 else if (count == 3)
564 szAdd = GetShortDay(node, (lpTime->wDayOfWeek + 6) % 7);
565 else
566 {
567 dwVal = lpTime->wDay;
568 szAdd = buff;
569 d_dd_formatted = TRUE;
570 }
571 break;
572
573 case 'M':
574 if (count >= 4)
575 {
576 LPCWSTR genitive = GetGenitiveMonth(node, lpTime->wMonth - 1);
577 if (genitive)
578 {
579 if (d_dd_formatted)
580 {
581 szAdd = genitive;
582 break;
583 }
584 else
585 {
587 /* Look forward now, if next format pattern is for day genitive
588 name should be used */
589 while (*format)
590 {
591 /* Skip parts within markers */
593 {
594 ++format;
595 while (*format)
596 {
598 {
599 ++format;
600 if (!IsLiteralMarker(*format)) break;
601 }
602 }
603 }
604 if (*format != ' ') break;
605 ++format;
606 }
607 /* Only numeric day form matters */
608 if (*format == 'd')
609 {
610 INT dcount = 1;
611 while (*++format == 'd') dcount++;
612 if (dcount < 3)
613 {
614 szAdd = genitive;
615 break;
616 }
617 }
618 }
619 }
620 szAdd = GetLongMonth(node, lpTime->wMonth - 1);
621 }
622 else if (count == 3)
623 szAdd = GetShortMonth(node, lpTime->wMonth - 1);
624 else
625 {
626 dwVal = lpTime->wMonth;
627 szAdd = buff;
628 }
629 break;
630
631 case 'y':
632#ifdef __REACTOS__
633 if (IS_LCID_JAPANESE(lcid) && (dwFlags & DATE_USE_ALT_CALENDAR))
634 {
635 PCJAPANESE_ERA pEra = JapaneseEra_Find(lpTime);
636 if (pEra)
637 {
638 if (count >= 2)
639 {
640 count = 2;
641 }
642
643 dwVal = lpTime->wYear - pEra->wYear + 1;
644
645 if (dwVal == 1 && JapaneseEra_IsFirstYearGannen())
646 {
647 // Gan of 'Gannen'
648 buff[0] = 0x5143;
649 buff[1] = 0;
650 }
651 szAdd = buff;
652 break;
653 }
655 return 0;
656 }
657#endif
658 if (count >= 4)
659 {
660 count = 4;
661 dwVal = lpTime->wYear;
662 }
663 else
664 {
665 count = count > 2 ? 2 : count;
666 dwVal = lpTime->wYear % 100;
667 }
668 szAdd = buff;
669 break;
670
671 case 'g':
672#ifdef __REACTOS__
673 if (IS_LCID_JAPANESE(lcid))
674 {
676 {
677 PCJAPANESE_ERA pEra = JapaneseEra_Find(lpTime);
678 if (pEra)
679 {
680 RtlStringCbCopyW(buff, sizeof(buff), pEra->szEraName);
681 szAdd = buff;
682 break;
683 }
685 return 0;
686 }
687 else
688 {
689 /* Seireki */
690 buff[0] = 0x897F;
691 buff[1] = 0x66A6;
692 buff[2] = 0;
693 szAdd = buff;
694 break;
695 }
696 }
697#endif
698 if (count == 2)
699 {
700 /* FIXME: Our GetCalendarInfo() does not yet support CAL_SERASTRING.
701 * When it is fixed, this string should be cached in 'node'.
702 */
703 FIXME("Should be using GetCalendarInfo(CAL_SERASTRING), defaulting to 'AD'\n");
704 buff[0] = 'A'; buff[1] = 'D'; buff[2] = '\0';
705 }
706 else
707 {
708 buff[0] = 'g'; buff[1] = '\0'; /* Add a literal 'g' */
709 }
710 szAdd = buff;
711 break;
712
713 case 'h':
715 {
716 count = count > 2 ? 2 : count;
717 dwVal = lpTime->wHour == 0 ? 12 : (lpTime->wHour - 1) % 12 + 1;
718 szAdd = buff;
719 break;
720 }
721 /* .. fall through if we are forced to output in 24 hour format */
722
723 case 'H':
724 count = count > 2 ? 2 : count;
725 dwVal = lpTime->wHour;
726 szAdd = buff;
727 break;
728
729 case 'm':
731 {
732 cchWritten = lastFormatPos; /* Skip */
733 bSkipping = TRUE;
734 }
735 else
736 {
737 count = count > 2 ? 2 : count;
738 dwVal = lpTime->wMinute;
739 szAdd = buff;
740 }
741 break;
742
743 case 's':
745 {
746 cchWritten = lastFormatPos; /* Skip */
747 bSkipping = TRUE;
748 }
749 else
750 {
751 count = count > 2 ? 2 : count;
752 dwVal = lpTime->wSecond;
753 szAdd = buff;
754 }
755 break;
756
757 case 't':
759 {
760 cchWritten = lastFormatPos; /* Skip */
761 bSkipping = TRUE;
762 }
763 else
764 {
765 if (count == 1)
766 szAdd = lpTime->wHour < 12 ? node->szShortAM : node->szShortPM;
767 else
768 szAdd = lpTime->wHour < 12 ? GetAM(node) : GetPM(node);
769 }
770 break;
771 }
772
773 if (szAdd == buff && buff[0] == '\0')
774 {
775 static const WCHAR fmtW[] = {'%','.','*','d',0};
776 /* We have a numeric value to add */
777 snprintfW(buff, ARRAY_SIZE(buff), fmtW, count, dwVal);
778 }
779
780 dwLen = szAdd ? strlenW(szAdd) : 0;
781
782 if (cchOut && dwLen)
783 {
784 if (cchWritten + dwLen < cchOut)
785 memcpy(lpStr + cchWritten, szAdd, dwLen * sizeof(WCHAR));
786 else
787 {
788 memcpy(lpStr + cchWritten, szAdd, (cchOut - cchWritten) * sizeof(WCHAR));
789 goto overrun;
790 }
791 }
792 cchWritten += dwLen;
793 lastFormatPos = cchWritten; /* Save position of last output format text */
794 }
795 else
796 {
797 /* Literal character */
798 if (!cchOut)
799 cchWritten++; /* Count size only */
800 else if (cchWritten >= cchOut)
801 goto overrun;
802 else if (!bSkipping || *lpFormat == ' ')
803 {
804 lpStr[cchWritten] = *lpFormat;
805 cchWritten++;
806 }
807 lpFormat++;
808 }
809 }
810
811 /* Final string terminator and sanity check */
812 if (cchOut)
813 {
814 if (cchWritten >= cchOut)
815 goto overrun;
816 else
817 lpStr[cchWritten] = '\0';
818 }
819 cchWritten++; /* Include terminating NUL */
820
821 TRACE("returning length=%d, output=%s\n", cchWritten, debugstr_w(lpStr));
822 return cchWritten;
823
824overrun:
825 TRACE("returning 0, (ERROR_INSUFFICIENT_BUFFER)\n");
827 return 0;
828
829invalid_parameter:
831 return 0;
832
833invalid_flags:
835 return 0;
836}
837
838/******************************************************************************
839 * NLS_GetDateTimeFormatA <internal>
840 *
841 * ASCII wrapper for GetDateFormatA/GetTimeFormatA.
842 */
844 const SYSTEMTIME* lpTime,
845 LPCSTR lpFormat, LPSTR lpStr, INT cchOut)
846{
847 DWORD cp = CP_ACP;
848 WCHAR szFormat[128], szOut[128];
849 INT iRet;
850
851 TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n", lcid, dwFlags, lpTime,
852 debugstr_a(lpFormat), lpStr, cchOut);
853
855 {
857 return 0;
858 }
859
860 if (!(dwFlags & LOCALE_USE_CP_ACP))
861 {
863 if (!node)
864 {
866 return 0;
867 }
868
869 cp = node->dwCodePage;
870 }
871
872 if (lpFormat)
873 MultiByteToWideChar(cp, 0, lpFormat, -1, szFormat, ARRAY_SIZE(szFormat));
874
875 if (cchOut > (int) ARRAY_SIZE(szOut))
876 cchOut = ARRAY_SIZE(szOut);
877
878 szOut[0] = '\0';
879
880 iRet = NLS_GetDateTimeFormatW(lcid, dwFlags, lpTime, lpFormat ? szFormat : NULL,
881 lpStr ? szOut : NULL, cchOut);
882
883 if (lpStr)
884 {
885 if (szOut[0])
886 WideCharToMultiByte(cp, 0, szOut, iRet ? -1 : cchOut, lpStr, cchOut, 0, 0);
887 else if (cchOut && iRet)
888 *lpStr = '\0';
889 }
890 return iRet;
891}
892
893/******************************************************************************
894 * GetDateFormatA [KERNEL32.@]
895 *
896 * Format a date for a given locale.
897 *
898 * PARAMS
899 * lcid [I] Locale to format for
900 * dwFlags [I] LOCALE_ and DATE_ flags from "winnls.h"
901 * lpTime [I] Date to format
902 * lpFormat [I] Format string, or NULL to use the system defaults
903 * lpDateStr [O] Destination for formatted string
904 * cchOut [I] Size of lpDateStr, or 0 to calculate the resulting size
905 *
906 * NOTES
907 * - If lpFormat is NULL, lpDateStr will be formatted according to the format
908 * details returned by GetLocaleInfoA() and modified by dwFlags.
909 * - lpFormat is a string of characters and formatting tokens. Any characters
910 * in the string are copied verbatim to lpDateStr, with tokens being replaced
911 * by the date values they represent.
912 * - The following tokens have special meanings in a date format string:
913 *| Token Meaning
914 *| ----- -------
915 *| d Single digit day of the month (no leading 0)
916 *| dd Double digit day of the month
917 *| ddd Short name for the day of the week
918 *| dddd Long name for the day of the week
919 *| M Single digit month of the year (no leading 0)
920 *| MM Double digit month of the year
921 *| MMM Short name for the month of the year
922 *| MMMM Long name for the month of the year
923 *| y Double digit year number (no leading 0)
924 *| yy Double digit year number
925 *| yyyy Four digit year number
926 *| gg Era string, for example 'AD'.
927 * - To output any literal character that could be misidentified as a token,
928 * enclose it in single quotes.
929 * - The Ascii version of this function fails if lcid is Unicode only.
930 *
931 * RETURNS
932 * Success: The number of character written to lpDateStr, or that would
933 * have been written, if cchOut is 0.
934 * Failure: 0. Use GetLastError() to determine the cause.
935 */
937 LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
938{
939 TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
940 debugstr_a(lpFormat), lpDateStr, cchOut);
941
943 lpFormat, lpDateStr, cchOut);
944}
945
946#if _WIN32_WINNT >= 0x600
947/******************************************************************************
948 * GetDateFormatEx [KERNEL32.@]
949 *
950 * Format a date for a given locale.
951 *
952 * PARAMS
953 * localename [I] Locale to format for
954 * flags [I] LOCALE_ and DATE_ flags from "winnls.h"
955 * date [I] Date to format
956 * format [I] Format string, or NULL to use the locale defaults
957 * outbuf [O] Destination for formatted string
958 * bufsize [I] Size of outbuf, or 0 to calculate the resulting size
959 * calendar [I] Reserved, must be NULL
960 *
961 * See GetDateFormatA for notes.
962 *
963 * RETURNS
964 * Success: The number of characters written to outbuf, or that would have
965 * been written if bufsize is 0.
966 * Failure: 0. Use GetLastError() to determine the cause.
967 */
970 LPWSTR outbuf, INT bufsize, LPCWSTR calendar)
971{
972 TRACE("(%s,0x%08x,%p,%s,%p,%d,%s)\n", debugstr_w(localename), flags,
973 date, debugstr_w(format), outbuf, bufsize, debugstr_w(calendar));
974
975 /* Parameter is currently reserved and Windows errors if set */
976 if (calendar != NULL)
977 {
979 return 0;
980 }
981
982 return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
984 outbuf, bufsize);
985}
986#endif /* _WIN32_WINNT >= 0x600 */
987
988/******************************************************************************
989 * GetDateFormatW [KERNEL32.@]
990 *
991 * See GetDateFormatA.
992 */
994 LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
995{
996 TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n", lcid, dwFlags, lpTime,
997 debugstr_w(lpFormat), lpDateStr, cchOut);
998
1000 lpFormat, lpDateStr, cchOut);
1001}
1002
1003/******************************************************************************
1004 * GetTimeFormatA [KERNEL32.@]
1005 *
1006 * Format a time for a given locale.
1007 *
1008 * PARAMS
1009 * lcid [I] Locale to format for
1010 * dwFlags [I] LOCALE_ and TIME_ flags from "winnls.h"
1011 * lpTime [I] Time to format
1012 * lpFormat [I] Formatting overrides
1013 * lpTimeStr [O] Destination for formatted string
1014 * cchOut [I] Size of lpTimeStr, or 0 to calculate the resulting size
1015 *
1016 * NOTES
1017 * - If lpFormat is NULL, lpszValue will be formatted according to the format
1018 * details returned by GetLocaleInfoA() and modified by dwFlags.
1019 * - lpFormat is a string of characters and formatting tokens. Any characters
1020 * in the string are copied verbatim to lpTimeStr, with tokens being replaced
1021 * by the time values they represent.
1022 * - The following tokens have special meanings in a time format string:
1023 *| Token Meaning
1024 *| ----- -------
1025 *| h Hours with no leading zero (12-hour clock)
1026 *| hh Hours with full two digits (12-hour clock)
1027 *| H Hours with no leading zero (24-hour clock)
1028 *| HH Hours with full two digits (24-hour clock)
1029 *| m Minutes with no leading zero
1030 *| mm Minutes with full two digits
1031 *| s Seconds with no leading zero
1032 *| ss Seconds with full two digits
1033 *| t Short time marker (e.g. "A" or "P")
1034 *| tt Long time marker (e.g. "AM", "PM")
1035 * - To output any literal character that could be misidentified as a token,
1036 * enclose it in single quotes.
1037 * - The Ascii version of this function fails if lcid is Unicode only.
1038 *
1039 * RETURNS
1040 * Success: The number of character written to lpTimeStr, or that would
1041 * have been written, if cchOut is 0.
1042 * Failure: 0. Use GetLastError() to determine the cause.
1043 */
1045 LPCSTR lpFormat, LPSTR lpTimeStr, INT cchOut)
1046{
1047 TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
1048 debugstr_a(lpFormat), lpTimeStr, cchOut);
1049
1051 lpFormat, lpTimeStr, cchOut);
1052}
1053
1054#if _WIN32_WINNT >= 0x600
1055/******************************************************************************
1056 * GetTimeFormatEx [KERNEL32.@]
1057 *
1058 * Format a date for a given locale.
1059 *
1060 * PARAMS
1061 * localename [I] Locale to format for
1062 * flags [I] LOCALE_ and TIME_ flags from "winnls.h"
1063 * time [I] Time to format
1064 * format [I] Formatting overrides
1065 * outbuf [O] Destination for formatted string
1066 * bufsize [I] Size of outbuf, or 0 to calculate the resulting size
1067 *
1068 * See GetTimeFormatA for notes.
1069 *
1070 * RETURNS
1071 * Success: The number of characters written to outbuf, or that would have
1072 * have been written if bufsize is 0.
1073 * Failure: 0. Use GetLastError() to determine the cause.
1074 */
1076 const SYSTEMTIME* time, LPCWSTR format,
1077 LPWSTR outbuf, INT bufsize)
1078{
1079 TRACE("(%s,0x%08x,%p,%s,%p,%d)\n", debugstr_w(localename), flags, time,
1080 debugstr_w(format), outbuf, bufsize);
1081
1082 return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
1084 outbuf, bufsize);
1085}
1086#endif /* _WIN32_WINNT >= 0x600 */
1087
1088/******************************************************************************
1089 * GetTimeFormatW [KERNEL32.@]
1090 *
1091 * See GetTimeFormatA.
1092 */
1094 LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
1095{
1096 TRACE("(0x%04x,0x%08x,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
1097 debugstr_w(lpFormat), lpTimeStr, cchOut);
1098
1100 lpFormat, lpTimeStr, cchOut);
1101}
1102
1103/**************************************************************************
1104 * GetNumberFormatA (KERNEL32.@)
1105 *
1106 * Format a number string for a given locale.
1107 *
1108 * PARAMS
1109 * lcid [I] Locale to format for
1110 * dwFlags [I] LOCALE_ flags from "winnls.h"
1111 * lpszValue [I] String to format
1112 * lpFormat [I] Formatting overrides
1113 * lpNumberStr [O] Destination for formatted string
1114 * cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size
1115 *
1116 * NOTES
1117 * - lpszValue can contain only '0' - '9', '-' and '.'.
1118 * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
1119 * be formatted according to the format details returned by GetLocaleInfoA().
1120 * - This function rounds the number string if the number of decimals exceeds the
1121 * locales normal number of decimal places.
1122 * - If cchOut is 0, this function does not write to lpNumberStr.
1123 * - The Ascii version of this function fails if lcid is Unicode only.
1124 *
1125 * RETURNS
1126 * Success: The number of character written to lpNumberStr, or that would
1127 * have been written, if cchOut is 0.
1128 * Failure: 0. Use GetLastError() to determine the cause.
1129 */
1131 LPCSTR lpszValue, const NUMBERFMTA *lpFormat,
1132 LPSTR lpNumberStr, int cchOut)
1133{
1134 DWORD cp = CP_ACP;
1135 WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
1137 const NUMBERFMTW *pfmt = NULL;
1138 INT iRet;
1139
1140 TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
1141 lpFormat, lpNumberStr, cchOut);
1142
1144 {
1146 return 0;
1147 }
1148
1149 if (!(dwFlags & LOCALE_USE_CP_ACP))
1150 {
1152 if (!node)
1153 {
1155 return 0;
1156 }
1157
1158 cp = node->dwCodePage;
1159 }
1160
1161 if (lpFormat)
1162 {
1163 memcpy(&fmt, lpFormat, sizeof(fmt));
1164 pfmt = &fmt;
1165 if (lpFormat->lpDecimalSep)
1166 {
1167 MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
1168 fmt.lpDecimalSep = szDec;
1169 }
1170 if (lpFormat->lpThousandSep)
1171 {
1172 MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
1173 fmt.lpThousandSep = szGrp;
1174 }
1175 }
1176
1177 if (lpszValue)
1178 MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
1179
1180 if (cchOut > (int) ARRAY_SIZE(szOut))
1181 cchOut = ARRAY_SIZE(szOut);
1182
1183 szOut[0] = '\0';
1184
1185 iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
1186 lpNumberStr ? szOut : NULL, cchOut);
1187
1188 if (szOut[0] && lpNumberStr)
1189 WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
1190 return iRet;
1191}
1192
1193/* Number parsing state flags */
1194#define NF_ISNEGATIVE 0x1 /* '-' found */
1195#define NF_ISREAL 0x2 /* '.' found */
1196#define NF_DIGITS 0x4 /* '0'-'9' found */
1197#define NF_DIGITS_OUT 0x8 /* Digits before the '.' found */
1198#define NF_ROUND 0x10 /* Number needs to be rounded */
1199
1200/* Formatting options for Numbers */
1201#define NLS_NEG_PARENS 0 /* "(1.1)" */
1202#define NLS_NEG_LEFT 1 /* "-1.1" */
1203#define NLS_NEG_LEFT_SPACE 2 /* "- 1.1" */
1204#define NLS_NEG_RIGHT 3 /* "1.1-" */
1205#define NLS_NEG_RIGHT_SPACE 4 /* "1.1 -" */
1206
1207/**************************************************************************
1208 * GetNumberFormatW (KERNEL32.@)
1209 *
1210 * See GetNumberFormatA.
1211 */
1213 LPCWSTR lpszValue, const NUMBERFMTW *lpFormat,
1214 LPWSTR lpNumberStr, int cchOut)
1215{
1216 WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
1217 WCHAR szNegBuff[8];
1218 const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc;
1219 DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0;
1220 INT iRet;
1221
1222 TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_w(lpszValue),
1223 lpFormat, lpNumberStr, cchOut);
1224
1225 if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpNumberStr) ||
1226 !IsValidLocale(lcid, 0) ||
1227 (lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep)))
1228 {
1229 goto error;
1230 }
1231
1232 if (!lpFormat)
1233 {
1235
1236 if (!node)
1237 goto error;
1238 lpFormat = &node->fmt;
1239 lpszNegStart = lpszNeg = GetNegative(node);
1240 }
1241 else
1242 {
1244 szNegBuff, ARRAY_SIZE(szNegBuff));
1245 lpszNegStart = lpszNeg = szNegBuff;
1246 }
1247 lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
1248
1250
1251 /* Format the number backwards into a temporary buffer */
1252
1253 szSrc = lpszValue;
1254 *szOut-- = '\0';
1255
1256 /* Check the number for validity */
1257 while (*szSrc)
1258 {
1259 if (*szSrc >= '0' && *szSrc <= '9')
1260 {
1261 dwState |= NF_DIGITS;
1262 if (dwState & NF_ISREAL)
1263 dwDecimals++;
1264 }
1265 else if (*szSrc == '-')
1266 {
1267 if (dwState)
1268 goto error; /* '-' not first character */
1269 dwState |= NF_ISNEGATIVE;
1270 }
1271 else if (*szSrc == '.')
1272 {
1273 if (dwState & NF_ISREAL)
1274 goto error; /* More than one '.' */
1275 dwState |= NF_ISREAL;
1276 }
1277 else
1278 goto error; /* Invalid char */
1279 szSrc++;
1280 }
1281 szSrc--; /* Point to last character */
1282
1283 if (!(dwState & NF_DIGITS))
1284 goto error; /* No digits */
1285
1286 /* Add any trailing negative sign */
1287 if (dwState & NF_ISNEGATIVE)
1288 {
1289 switch (lpFormat->NegativeOrder)
1290 {
1291 case NLS_NEG_PARENS:
1292 *szOut-- = ')';
1293 break;
1294 case NLS_NEG_RIGHT:
1296 while (lpszNeg >= lpszNegStart)
1297 *szOut-- = *lpszNeg--;
1298 if (lpFormat->NegativeOrder == NLS_NEG_RIGHT_SPACE)
1299 *szOut-- = ' ';
1300 break;
1301 }
1302 }
1303
1304 /* Copy all digits up to the decimal point */
1305 if (!lpFormat->NumDigits)
1306 {
1307 if (dwState & NF_ISREAL)
1308 {
1309 while (*szSrc != '.') /* Don't write any decimals or a separator */
1310 {
1311 if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1312 dwState |= NF_ROUND;
1313 else
1314 dwState &= ~NF_ROUND;
1315 szSrc--;
1316 }
1317 szSrc--;
1318 }
1319 }
1320 else
1321 {
1322 LPWSTR lpszDec = lpFormat->lpDecimalSep + strlenW(lpFormat->lpDecimalSep) - 1;
1323
1324 if (dwDecimals <= lpFormat->NumDigits)
1325 {
1326 dwDecimals = lpFormat->NumDigits - dwDecimals;
1327 while (dwDecimals--)
1328 *szOut-- = '0'; /* Pad to correct number of dp */
1329 }
1330 else
1331 {
1332 dwDecimals -= lpFormat->NumDigits;
1333 /* Skip excess decimals, and determine if we have to round the number */
1334 while (dwDecimals--)
1335 {
1336 if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1337 dwState |= NF_ROUND;
1338 else
1339 dwState &= ~NF_ROUND;
1340 szSrc--;
1341 }
1342 }
1343
1344 if (dwState & NF_ISREAL)
1345 {
1346 while (*szSrc != '.')
1347 {
1348 if (dwState & NF_ROUND)
1349 {
1350 if (*szSrc == '9')
1351 *szOut-- = '0'; /* continue rounding */
1352 else
1353 {
1354 dwState &= ~NF_ROUND;
1355 *szOut-- = (*szSrc)+1;
1356 }
1357 szSrc--;
1358 }
1359 else
1360 *szOut-- = *szSrc--; /* Write existing decimals */
1361 }
1362 szSrc--; /* Skip '.' */
1363 }
1364
1365 while (lpszDec >= lpFormat->lpDecimalSep)
1366 *szOut-- = *lpszDec--; /* Write decimal separator */
1367 }
1368
1369 dwGroupCount = lpFormat->Grouping == 32 ? 3 : lpFormat->Grouping;
1370
1371 /* Write the remaining whole number digits, including grouping chars */
1372 while (szSrc >= lpszValue && *szSrc >= '0' && *szSrc <= '9')
1373 {
1374 if (dwState & NF_ROUND)
1375 {
1376 if (*szSrc == '9')
1377 *szOut-- = '0'; /* continue rounding */
1378 else
1379 {
1380 dwState &= ~NF_ROUND;
1381 *szOut-- = (*szSrc)+1;
1382 }
1383 szSrc--;
1384 }
1385 else
1386 *szOut-- = *szSrc--;
1387
1388 dwState |= NF_DIGITS_OUT;
1389 dwCurrentGroupCount++;
1390 if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-')
1391 {
1392 LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1;
1393
1394 while (lpszGrp >= lpFormat->lpThousandSep)
1395 *szOut-- = *lpszGrp--; /* Write grouping char */
1396
1397 dwCurrentGroupCount = 0;
1398 if (lpFormat->Grouping == 32)
1399 dwGroupCount = 2; /* Indic grouping: 3 then 2 */
1400 }
1401 }
1402 if (dwState & NF_ROUND)
1403 {
1404 *szOut-- = '1'; /* e.g. .6 > 1.0 */
1405 }
1406 else if (!(dwState & NF_DIGITS_OUT) && lpFormat->LeadingZero)
1407 *szOut-- = '0'; /* Add leading 0 if we have no digits before the decimal point */
1408
1409 /* Add any leading negative sign */
1410 if (dwState & NF_ISNEGATIVE)
1411 {
1412 switch (lpFormat->NegativeOrder)
1413 {
1414 case NLS_NEG_PARENS:
1415 *szOut-- = '(';
1416 break;
1417 case NLS_NEG_LEFT_SPACE:
1418 *szOut-- = ' ';
1419 /* Fall through */
1420 case NLS_NEG_LEFT:
1421 while (lpszNeg >= lpszNegStart)
1422 *szOut-- = *lpszNeg--;
1423 break;
1424 }
1425 }
1426 szOut++;
1427
1428 iRet = strlenW(szOut) + 1;
1429 if (cchOut)
1430 {
1431 if (iRet <= cchOut)
1432 memcpy(lpNumberStr, szOut, iRet * sizeof(WCHAR));
1433 else
1434 {
1435 memcpy(lpNumberStr, szOut, cchOut * sizeof(WCHAR));
1436 lpNumberStr[cchOut - 1] = '\0';
1438 iRet = 0;
1439 }
1440 }
1441 return iRet;
1442
1443error:
1445 return 0;
1446}
1447
1448#if _WIN32_WINNT >= 0x600
1449/**************************************************************************
1450 * GetNumberFormatEx (KERNEL32.@)
1451 */
1452INT WINAPI GetNumberFormatEx(LPCWSTR name, DWORD flags,
1454 LPWSTR number, int numout)
1455{
1456 LCID lcid;
1457
1458 TRACE("(%s,0x%08x,%s,%p,%p,%d)\n", debugstr_w(name), flags,
1459 debugstr_w(value), format, number, numout);
1460
1461 lcid = LocaleNameToLCID(name, 0);
1462 if (!lcid)
1463 return 0;
1464
1465 return GetNumberFormatW(lcid, flags, value, format, number, numout);
1466}
1467#endif /* _WIN32_WINNT >= 0x600 */
1468
1469/**************************************************************************
1470 * GetCurrencyFormatA (KERNEL32.@)
1471 *
1472 * Format a currency string for a given locale.
1473 *
1474 * PARAMS
1475 * lcid [I] Locale to format for
1476 * dwFlags [I] LOCALE_ flags from "winnls.h"
1477 * lpszValue [I] String to format
1478 * lpFormat [I] Formatting overrides
1479 * lpCurrencyStr [O] Destination for formatted string
1480 * cchOut [I] Size of lpCurrencyStr, or 0 to calculate the resulting size
1481 *
1482 * NOTES
1483 * - lpszValue can contain only '0' - '9', '-' and '.'.
1484 * - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
1485 * be formatted according to the format details returned by GetLocaleInfoA().
1486 * - This function rounds the currency if the number of decimals exceeds the
1487 * locales number of currency decimal places.
1488 * - If cchOut is 0, this function does not write to lpCurrencyStr.
1489 * - The Ascii version of this function fails if lcid is Unicode only.
1490 *
1491 * RETURNS
1492 * Success: The number of character written to lpNumberStr, or that would
1493 * have been written, if cchOut is 0.
1494 * Failure: 0. Use GetLastError() to determine the cause.
1495 */
1497 LPCSTR lpszValue, const CURRENCYFMTA *lpFormat,
1498 LPSTR lpCurrencyStr, int cchOut)
1499{
1500 DWORD cp = CP_ACP;
1501 WCHAR szDec[8], szGrp[8], szCy[8], szIn[128], szOut[128];
1503 const CURRENCYFMTW *pfmt = NULL;
1504 INT iRet;
1505
1506 TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
1507 lpFormat, lpCurrencyStr, cchOut);
1508
1510 {
1512 return 0;
1513 }
1514
1515 if (!(dwFlags & LOCALE_USE_CP_ACP))
1516 {
1518 if (!node)
1519 {
1521 return 0;
1522 }
1523
1524 cp = node->dwCodePage;
1525 }
1526
1527 if (lpFormat)
1528 {
1529 memcpy(&fmt, lpFormat, sizeof(fmt));
1530 pfmt = &fmt;
1531 if (lpFormat->lpDecimalSep)
1532 {
1533 MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
1534 fmt.lpDecimalSep = szDec;
1535 }
1536 if (lpFormat->lpThousandSep)
1537 {
1538 MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
1539 fmt.lpThousandSep = szGrp;
1540 }
1541 if (lpFormat->lpCurrencySymbol)
1542 {
1543 MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy));
1544 fmt.lpCurrencySymbol = szCy;
1545 }
1546 }
1547
1548 if (lpszValue)
1549 MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
1550
1551 if (cchOut > (int) ARRAY_SIZE(szOut))
1552 cchOut = ARRAY_SIZE(szOut);
1553
1554 szOut[0] = '\0';
1555
1556 iRet = GetCurrencyFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
1557 lpCurrencyStr ? szOut : NULL, cchOut);
1558
1559 if (szOut[0] && lpCurrencyStr)
1560 WideCharToMultiByte(cp, 0, szOut, -1, lpCurrencyStr, cchOut, 0, 0);
1561 return iRet;
1562}
1563
1564/* Formatting states for Currencies. We use flags to avoid code duplication. */
1565#define CF_PARENS 0x1 /* Parentheses */
1566#define CF_MINUS_LEFT 0x2 /* '-' to the left */
1567#define CF_MINUS_RIGHT 0x4 /* '-' to the right */
1568#define CF_MINUS_BEFORE 0x8 /* '-' before '$' */
1569#define CF_CY_LEFT 0x10 /* '$' to the left */
1570#define CF_CY_RIGHT 0x20 /* '$' to the right */
1571#define CF_CY_SPACE 0x40 /* ' ' by '$' */
1572
1573/**************************************************************************
1574 * GetCurrencyFormatW (KERNEL32.@)
1575 *
1576 * See GetCurrencyFormatA.
1577 */
1579 LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat,
1580 LPWSTR lpCurrencyStr, int cchOut)
1581{
1582 static const BYTE NLS_NegCyFormats[16] =
1583 {
1584 CF_PARENS|CF_CY_LEFT, /* ($1.1) */
1586 CF_MINUS_LEFT|CF_CY_LEFT, /* $-1.1 */
1587 CF_MINUS_RIGHT|CF_CY_LEFT, /* $1.1- */
1588 CF_PARENS|CF_CY_RIGHT, /* (1.1$) */
1589 CF_MINUS_LEFT|CF_CY_RIGHT, /* -1.1$ */
1591 CF_MINUS_RIGHT|CF_CY_RIGHT, /* 1.1$- */
1598 CF_PARENS|CF_CY_LEFT|CF_CY_SPACE, /* ($ 1.1) */
1599 CF_PARENS|CF_CY_RIGHT|CF_CY_SPACE, /* (1.1 $) */
1600 };
1601 static const BYTE NLS_PosCyFormats[4] =
1602 {
1603 CF_CY_LEFT, /* $1.1 */
1604 CF_CY_RIGHT, /* 1.1$ */
1605 CF_CY_LEFT|CF_CY_SPACE, /* $ 1.1 */
1606 CF_CY_RIGHT|CF_CY_SPACE, /* 1.1 $ */
1607 };
1608 WCHAR szBuff[128], *szOut = szBuff + ARRAY_SIZE(szBuff) - 1;
1609 WCHAR szNegBuff[8];
1610 const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc, *lpszCy, *lpszCyStart;
1611 DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0, dwFmt;
1612 INT iRet;
1613
1614 TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_w(lpszValue),
1615 lpFormat, lpCurrencyStr, cchOut);
1616
1617 if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpCurrencyStr) ||
1618 !IsValidLocale(lcid, 0) ||
1619 (lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep ||
1620 !lpFormat->lpCurrencySymbol || lpFormat->NegativeOrder > 15 ||
1621 lpFormat->PositiveOrder > 3)))
1622 {
1623 goto error;
1624 }
1625
1626 if (!lpFormat)
1627 {
1629
1630 if (!node)
1631 goto error;
1632
1633 lpFormat = &node->cyfmt;
1634 lpszNegStart = lpszNeg = GetNegative(node);
1635 }
1636 else
1637 {
1639 szNegBuff, ARRAY_SIZE(szNegBuff));
1640 lpszNegStart = lpszNeg = szNegBuff;
1641 }
1643
1644 lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
1645 lpszCyStart = lpFormat->lpCurrencySymbol;
1646 lpszCy = lpszCyStart + strlenW(lpszCyStart) - 1;
1647
1648 /* Format the currency backwards into a temporary buffer */
1649
1650 szSrc = lpszValue;
1651 *szOut-- = '\0';
1652
1653 /* Check the number for validity */
1654 while (*szSrc)
1655 {
1656 if (*szSrc >= '0' && *szSrc <= '9')
1657 {
1658 dwState |= NF_DIGITS;
1659 if (dwState & NF_ISREAL)
1660 dwDecimals++;
1661 }
1662 else if (*szSrc == '-')
1663 {
1664 if (dwState)
1665 goto error; /* '-' not first character */
1666 dwState |= NF_ISNEGATIVE;
1667 }
1668 else if (*szSrc == '.')
1669 {
1670 if (dwState & NF_ISREAL)
1671 goto error; /* More than one '.' */
1672 dwState |= NF_ISREAL;
1673 }
1674 else
1675 goto error; /* Invalid char */
1676 szSrc++;
1677 }
1678 szSrc--; /* Point to last character */
1679
1680 if (!(dwState & NF_DIGITS))
1681 goto error; /* No digits */
1682
1683 if (dwState & NF_ISNEGATIVE)
1684 dwFmt = NLS_NegCyFormats[lpFormat->NegativeOrder];
1685 else
1686 dwFmt = NLS_PosCyFormats[lpFormat->PositiveOrder];
1687
1688 /* Add any trailing negative or currency signs */
1689 if (dwFmt & CF_PARENS)
1690 *szOut-- = ')';
1691
1692 while (dwFmt & (CF_MINUS_RIGHT|CF_CY_RIGHT))
1693 {
1694 switch (dwFmt & (CF_MINUS_RIGHT|CF_MINUS_BEFORE|CF_CY_RIGHT))
1695 {
1696 case CF_MINUS_RIGHT:
1698 while (lpszNeg >= lpszNegStart)
1699 *szOut-- = *lpszNeg--;
1700 dwFmt &= ~CF_MINUS_RIGHT;
1701 break;
1702
1703 case CF_CY_RIGHT:
1706 while (lpszCy >= lpszCyStart)
1707 *szOut-- = *lpszCy--;
1708 if (dwFmt & CF_CY_SPACE)
1709 *szOut-- = ' ';
1710 dwFmt &= ~(CF_CY_RIGHT|CF_MINUS_BEFORE);
1711 break;
1712 }
1713 }
1714
1715 /* Copy all digits up to the decimal point */
1716 if (!lpFormat->NumDigits)
1717 {
1718 if (dwState & NF_ISREAL)
1719 {
1720 while (*szSrc != '.') /* Don't write any decimals or a separator */
1721 {
1722 if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1723 dwState |= NF_ROUND;
1724 else
1725 dwState &= ~NF_ROUND;
1726 szSrc--;
1727 }
1728 szSrc--;
1729 }
1730 }
1731 else
1732 {
1733 LPWSTR lpszDec = lpFormat->lpDecimalSep + strlenW(lpFormat->lpDecimalSep) - 1;
1734
1735 if (dwDecimals <= lpFormat->NumDigits)
1736 {
1737 dwDecimals = lpFormat->NumDigits - dwDecimals;
1738 while (dwDecimals--)
1739 *szOut-- = '0'; /* Pad to correct number of dp */
1740 }
1741 else
1742 {
1743 dwDecimals -= lpFormat->NumDigits;
1744 /* Skip excess decimals, and determine if we have to round the number */
1745 while (dwDecimals--)
1746 {
1747 if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
1748 dwState |= NF_ROUND;
1749 else
1750 dwState &= ~NF_ROUND;
1751 szSrc--;
1752 }
1753 }
1754
1755 if (dwState & NF_ISREAL)
1756 {
1757 while (*szSrc != '.')
1758 {
1759 if (dwState & NF_ROUND)
1760 {
1761 if (*szSrc == '9')
1762 *szOut-- = '0'; /* continue rounding */
1763 else
1764 {
1765 dwState &= ~NF_ROUND;
1766 *szOut-- = (*szSrc)+1;
1767 }
1768 szSrc--;
1769 }
1770 else
1771 *szOut-- = *szSrc--; /* Write existing decimals */
1772 }
1773 szSrc--; /* Skip '.' */
1774 }
1775 while (lpszDec >= lpFormat->lpDecimalSep)
1776 *szOut-- = *lpszDec--; /* Write decimal separator */
1777 }
1778
1779 dwGroupCount = lpFormat->Grouping == 32 ? 3 : lpFormat->Grouping;
1780
1781 /* Write the remaining whole number digits, including grouping chars */
1782 while (szSrc >= lpszValue && *szSrc >= '0' && *szSrc <= '9')
1783 {
1784 if (dwState & NF_ROUND)
1785 {
1786 if (*szSrc == '9')
1787 *szOut-- = '0'; /* continue rounding */
1788 else
1789 {
1790 dwState &= ~NF_ROUND;
1791 *szOut-- = (*szSrc)+1;
1792 }
1793 szSrc--;
1794 }
1795 else
1796 *szOut-- = *szSrc--;
1797
1798 dwState |= NF_DIGITS_OUT;
1799 dwCurrentGroupCount++;
1800 if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-')
1801 {
1802 LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1;
1803
1804 while (lpszGrp >= lpFormat->lpThousandSep)
1805 *szOut-- = *lpszGrp--; /* Write grouping char */
1806
1807 dwCurrentGroupCount = 0;
1808 if (lpFormat->Grouping == 32)
1809 dwGroupCount = 2; /* Indic grouping: 3 then 2 */
1810 }
1811 }
1812 if (dwState & NF_ROUND)
1813 *szOut-- = '1'; /* e.g. .6 > 1.0 */
1814 else if (!(dwState & NF_DIGITS_OUT) && lpFormat->LeadingZero)
1815 *szOut-- = '0'; /* Add leading 0 if we have no digits before the decimal point */
1816
1817 /* Add any leading negative or currency sign */
1818 while (dwFmt & (CF_MINUS_LEFT|CF_CY_LEFT))
1819 {
1820 switch (dwFmt & (CF_MINUS_LEFT|CF_MINUS_BEFORE|CF_CY_LEFT))
1821 {
1822 case CF_MINUS_LEFT:
1824 while (lpszNeg >= lpszNegStart)
1825 *szOut-- = *lpszNeg--;
1826 dwFmt &= ~CF_MINUS_LEFT;
1827 break;
1828
1829 case CF_CY_LEFT:
1832 if (dwFmt & CF_CY_SPACE)
1833 *szOut-- = ' ';
1834 while (lpszCy >= lpszCyStart)
1835 *szOut-- = *lpszCy--;
1836 dwFmt &= ~(CF_CY_LEFT|CF_MINUS_BEFORE);
1837 break;
1838 }
1839 }
1840 if (dwFmt & CF_PARENS)
1841 *szOut-- = '(';
1842 szOut++;
1843
1844 iRet = strlenW(szOut) + 1;
1845 if (cchOut)
1846 {
1847 if (iRet <= cchOut)
1848 memcpy(lpCurrencyStr, szOut, iRet * sizeof(WCHAR));
1849 else
1850 {
1851 memcpy(lpCurrencyStr, szOut, cchOut * sizeof(WCHAR));
1852 lpCurrencyStr[cchOut - 1] = '\0';
1854 iRet = 0;
1855 }
1856 }
1857 return iRet;
1858
1859error:
1861 return 0;
1862}
1863
1864#if _WIN32_WINNT >= 0x600
1865/***********************************************************************
1866 * GetCurrencyFormatEx (KERNEL32.@)
1867 */
1868int WINAPI GetCurrencyFormatEx(LPCWSTR localename, DWORD flags, LPCWSTR value,
1869 const CURRENCYFMTW *format, LPWSTR str, int len)
1870{
1871 TRACE("(%s,0x%08x,%s,%p,%p,%d)\n", debugstr_w(localename), flags,
1873
1874 return GetCurrencyFormatW( LocaleNameToLCID(localename, 0), flags, value, format, str, len);
1875}
1876#endif
1877
1878
1879/* FIXME: Everything below here needs to move somewhere else along with the
1880 * other EnumXXX functions, when a method for storing resources for
1881 * alternate calendars is determined.
1882 */
1883
1889
1891 enum enum_callback_type type; /* callback kind */
1892 union {
1893 DATEFMT_ENUMPROCW callback; /* user callback pointer */
1896 } u;
1897 LCID lcid; /* locale of interest */
1900 BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
1901};
1902
1903/******************************************************************************
1904 * NLS_EnumDateFormats <internal>
1905 * Enumerates date formats for a specified locale.
1906 *
1907 * PARAMS
1908 * ctxt [I] enumeration context, see 'struct enumdateformats_context'
1909 *
1910 * RETURNS
1911 * Success: TRUE.
1912 * Failure: FALSE. Use GetLastError() to determine the cause.
1913 */
1915{
1916 WCHAR bufW[256];
1917 char bufA[256];
1918 LCTYPE lctype;
1919 CALID cal_id;
1920 INT ret;
1921
1922 if (!ctxt->u.callback)
1923 {
1925 return FALSE;
1926 }
1927
1928 if (!GetLocaleInfoW(ctxt->lcid, LOCALE_ICALENDARTYPE|LOCALE_RETURN_NUMBER, (LPWSTR)&cal_id, sizeof(cal_id)/sizeof(WCHAR)))
1929 return FALSE;
1930
1931 switch (ctxt->flags & ~LOCALE_USE_CP_ACP)
1932 {
1933 case 0:
1934 case DATE_SHORTDATE:
1935 lctype = LOCALE_SSHORTDATE;
1936 break;
1937 case DATE_LONGDATE:
1938 lctype = LOCALE_SLONGDATE;
1939 break;
1940 case DATE_YEARMONTH:
1941 lctype = LOCALE_SYEARMONTH;
1942 break;
1943 default:
1944 FIXME("Unknown date format (0x%08x)\n", ctxt->flags);
1946 return FALSE;
1947 }
1948
1949 lctype |= ctxt->flags & LOCALE_USE_CP_ACP;
1950 if (ctxt->unicode)
1951 ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW));
1952 else
1953 ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA));
1954
1955 if (ret)
1956 {
1957 switch (ctxt->type)
1958 {
1959 case CALLBACK_ENUMPROC:
1960 ctxt->u.callback(ctxt->unicode ? bufW : (WCHAR*)bufA);
1961 break;
1963 ctxt->u.callbackex(ctxt->unicode ? bufW : (WCHAR*)bufA, cal_id);
1964 break;
1966 ctxt->u.callbackexex(bufW, cal_id, ctxt->lParam);
1967 break;
1968 default:
1969 ;
1970 }
1971 }
1972
1973 return TRUE;
1974}
1975
1976/**************************************************************************
1977 * EnumDateFormatsExA (KERNEL32.@)
1978 *
1979 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
1980 * LOCALE_NOUSEROVERRIDE here as well?
1981 */
1983{
1984 struct enumdateformats_context ctxt;
1985
1988 ctxt.lcid = lcid;
1989 ctxt.flags = flags;
1990 ctxt.unicode = FALSE;
1991
1992 return NLS_EnumDateFormats(&ctxt);
1993}
1994
1995/**************************************************************************
1996 * EnumDateFormatsExW (KERNEL32.@)
1997 */
1999{
2000 struct enumdateformats_context ctxt;
2001
2003 ctxt.u.callbackex = proc;
2004 ctxt.lcid = lcid;
2005 ctxt.flags = flags;
2006 ctxt.unicode = TRUE;
2007
2008 return NLS_EnumDateFormats(&ctxt);
2009}
2010
2011/**************************************************************************
2012 * EnumDateFormatsA (KERNEL32.@)
2013 *
2014 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
2015 * LOCALE_NOUSEROVERRIDE here as well?
2016 */
2018{
2019 struct enumdateformats_context ctxt;
2020
2021 ctxt.type = CALLBACK_ENUMPROC;
2023 ctxt.lcid = lcid;
2024 ctxt.flags = flags;
2025 ctxt.unicode = FALSE;
2026
2027 return NLS_EnumDateFormats(&ctxt);
2028}
2029
2030/**************************************************************************
2031 * EnumDateFormatsW (KERNEL32.@)
2032 */
2034{
2035 struct enumdateformats_context ctxt;
2036
2037 ctxt.type = CALLBACK_ENUMPROC;
2038 ctxt.u.callback = proc;
2039 ctxt.lcid = lcid;
2040 ctxt.flags = flags;
2041 ctxt.unicode = TRUE;
2042
2043 return NLS_EnumDateFormats(&ctxt);
2044}
2045
2046#if _WIN32_WINNT >= 0x600
2047/**************************************************************************
2048 * EnumDateFormatsExEx (KERNEL32.@)
2049 */
2050BOOL WINAPI EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale, DWORD flags, LPARAM lParam)
2051{
2052 struct enumdateformats_context ctxt;
2053
2055 ctxt.u.callbackexex = proc;
2056 ctxt.lcid = LocaleNameToLCID(locale, 0);
2057 ctxt.flags = flags;
2058 ctxt.lParam = lParam;
2059 ctxt.unicode = TRUE;
2060
2061 return NLS_EnumDateFormats(&ctxt);
2062}
2063#endif /* _WIN32_WINNT >= 0x600 */
2064
2066 enum enum_callback_type type; /* callback kind */
2067 union {
2068 TIMEFMT_ENUMPROCW callback; /* user callback pointer */
2070 } u;
2071 LCID lcid; /* locale of interest */
2074 BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
2075};
2076
2078{
2079 WCHAR bufW[256];
2080 char bufA[256];
2081 LCTYPE lctype;
2082 INT ret;
2083
2084 if (!ctxt->u.callback)
2085 {
2087 return FALSE;
2088 }
2089
2090 switch (ctxt->flags & ~LOCALE_USE_CP_ACP)
2091 {
2092 case 0:
2093 lctype = LOCALE_STIMEFORMAT;
2094 break;
2095 case TIME_NOSECONDS:
2096 lctype = LOCALE_SSHORTTIME;
2097 break;
2098 default:
2099 FIXME("Unknown time format (%d)\n", ctxt->flags);
2101 return FALSE;
2102 }
2103
2104 lctype |= ctxt->flags & LOCALE_USE_CP_ACP;
2105 if (ctxt->unicode)
2106 ret = GetLocaleInfoW(ctxt->lcid, lctype, bufW, ARRAY_SIZE(bufW));
2107 else
2108 ret = GetLocaleInfoA(ctxt->lcid, lctype, bufA, ARRAY_SIZE(bufA));
2109
2110 if (ret)
2111 {
2112 switch (ctxt->type)
2113 {
2114 case CALLBACK_ENUMPROC:
2115 ctxt->u.callback(ctxt->unicode ? bufW : (WCHAR*)bufA);
2116 break;
2118 ctxt->u.callbackex(bufW, ctxt->lParam);
2119 break;
2120 default:
2121 ;
2122 }
2123 }
2124
2125 return TRUE;
2126}
2127
2128/**************************************************************************
2129 * EnumTimeFormatsA (KERNEL32.@)
2130 *
2131 * FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
2132 * LOCALE_NOUSEROVERRIDE here as well?
2133 */
2135{
2136 struct enumtimeformats_context ctxt;
2137
2138 /* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */
2139 if (flags & ~LOCALE_USE_CP_ACP)
2140 {
2142 return FALSE;
2143 }
2144
2145 ctxt.type = CALLBACK_ENUMPROC;
2147 ctxt.lcid = lcid;
2148 ctxt.flags = flags;
2149 ctxt.unicode = FALSE;
2150
2151 return NLS_EnumTimeFormats(&ctxt);
2152}
2153
2154/**************************************************************************
2155 * EnumTimeFormatsW (KERNEL32.@)
2156 */
2158{
2159 struct enumtimeformats_context ctxt;
2160
2161 ctxt.type = CALLBACK_ENUMPROC;
2162 ctxt.u.callback = proc;
2163 ctxt.lcid = lcid;
2164 ctxt.flags = flags;
2165 ctxt.unicode = TRUE;
2166
2167 return NLS_EnumTimeFormats(&ctxt);
2168}
2169
2170#if _WIN32_WINNT >= 0x600
2171/**************************************************************************
2172 * EnumTimeFormatsEx (KERNEL32.@)
2173 */
2175{
2176 struct enumtimeformats_context ctxt;
2177
2179 ctxt.u.callbackex = proc;
2180 ctxt.lcid = LocaleNameToLCID(locale, 0);
2181 ctxt.flags = flags;
2182 ctxt.lParam = lParam;
2183 ctxt.unicode = TRUE;
2184
2185 return NLS_EnumTimeFormats(&ctxt);
2186}
2187#endif /* _WIN32_WINNT >= 0x600 */
2188
2190 enum enum_callback_type type; /* callback kind */
2191 union {
2192 CALINFO_ENUMPROCW callback; /* user callback pointer */
2195 } u;
2196 LCID lcid; /* locale of interest */
2197 CALID calendar; /* specific calendar or ENUM_ALL_CALENDARS */
2198 CALTYPE caltype; /* calendar information type */
2199 LPARAM lParam; /* user input parameter passed to callback, for ExEx case only */
2200 BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
2201};
2202
2203/******************************************************************************
2204 * NLS_EnumCalendarInfo <internal>
2205 * Enumerates calendar information for a specified locale.
2206 *
2207 * PARAMS
2208 * ctxt [I] enumeration context, see 'struct enumcalendar_context'
2209 *
2210 * RETURNS
2211 * Success: TRUE.
2212 * Failure: FALSE. Use GetLastError() to determine the cause.
2213 *
2214 * NOTES
2215 * When the ANSI version of this function is used with a Unicode-only LCID,
2216 * the call can succeed because the system uses the system code page.
2217 * However, characters that are undefined in the system code page appear
2218 * in the string as a question mark (?).
2219 *
2220 * TODO
2221 * The above note should be respected by GetCalendarInfoA.
2222 */
2224{
2225 WCHAR *buf, *opt = NULL, *iter = NULL;
2226 CALID calendar = ctxt->calendar;
2227 BOOL ret = FALSE;
2228 int bufSz = 200; /* the size of the buffer */
2229
2230 if (ctxt->u.callback == NULL)
2231 {
2233 return FALSE;
2234 }
2235
2236 buf = HeapAlloc(GetProcessHeap(), 0, bufSz);
2237 if (buf == NULL)
2238 {
2240 return FALSE;
2241 }
2242
2243 if (calendar == ENUM_ALL_CALENDARS)
2244 {
2245 int optSz = GetLocaleInfoW(ctxt->lcid, LOCALE_IOPTIONALCALENDAR, NULL, 0);
2246 if (optSz > 1)
2247 {
2248 opt = HeapAlloc(GetProcessHeap(), 0, optSz * sizeof(WCHAR));
2249 if (opt == NULL)
2250 {
2252 goto cleanup;
2253 }
2254 if (GetLocaleInfoW(ctxt->lcid, LOCALE_IOPTIONALCALENDAR, opt, optSz))
2255 iter = opt;
2256 }
2258 }
2259
2260 while (TRUE) /* loop through calendars */
2261 {
2262 do /* loop until there's no error */
2263 {
2264 if (ctxt->caltype & CAL_RETURN_NUMBER)
2265 ret = GetCalendarInfoW(ctxt->lcid, calendar, ctxt->caltype, NULL, bufSz / sizeof(WCHAR), (LPDWORD)buf);
2266 else if (ctxt->unicode)
2267 ret = GetCalendarInfoW(ctxt->lcid, calendar, ctxt->caltype, buf, bufSz / sizeof(WCHAR), NULL);
2268 else ret = GetCalendarInfoA(ctxt->lcid, calendar, ctxt->caltype, (CHAR*)buf, bufSz / sizeof(CHAR), NULL);
2269
2270 if (!ret)
2271 {
2273 { /* so resize it */
2274 int newSz;
2275 if (ctxt->unicode)
2276 newSz = GetCalendarInfoW(ctxt->lcid, calendar, ctxt->caltype, NULL, 0, NULL) * sizeof(WCHAR);
2277 else newSz = GetCalendarInfoA(ctxt->lcid, calendar, ctxt->caltype, NULL, 0, NULL) * sizeof(CHAR);
2278 if (bufSz >= newSz)
2279 {
2280 ERR("Buffer resizing disorder: was %d, requested %d.\n", bufSz, newSz);
2281 goto cleanup;
2282 }
2283 bufSz = newSz;
2284 WARN("Buffer too small; resizing to %d bytes.\n", bufSz);
2285 buf = HeapReAlloc(GetProcessHeap(), 0, buf, bufSz);
2286 if (buf == NULL)
2287 goto cleanup;
2288 } else goto cleanup;
2289 }
2290 } while (!ret);
2291
2292 /* Here we are. We pass the buffer to the correct version of
2293 * the callback. Because it's not the same number of params,
2294 * we must check for Ex, but we don't care about Unicode
2295 * because the buffer is already in the correct format.
2296 */
2297 switch (ctxt->type)
2298 {
2299 case CALLBACK_ENUMPROC:
2300 ret = ctxt->u.callback(buf);
2301 break;
2303 ret = ctxt->u.callbackex(buf, calendar);
2304 break;
2306 ret = ctxt->u.callbackexex(buf, calendar, NULL, ctxt->lParam);
2307 break;
2308 default:
2309 ;
2310 }
2311
2312 if (!ret) { /* the callback told to stop */
2313 ret = TRUE;
2314 break;
2315 }
2316
2317 if ((iter == NULL) || (*iter == 0)) /* no more calendars */
2318 break;
2319
2320 calendar = 0;
2321 while ((*iter >= '0') && (*iter <= '9'))
2322 calendar = calendar * 10 + *iter++ - '0';
2323
2324 if (*iter++ != 0)
2325 {
2327 ret = FALSE;
2328 break;
2329 }
2330 }
2331
2332cleanup:
2333 HeapFree(GetProcessHeap(), 0, opt);
2335 return ret;
2336}
2337
2338/******************************************************************************
2339 * EnumCalendarInfoA [KERNEL32.@]
2340 */
2342 CALID calendar,CALTYPE caltype )
2343{
2344 struct enumcalendar_context ctxt;
2345
2346 TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2347
2348 ctxt.type = CALLBACK_ENUMPROC;
2349 ctxt.u.callback = (CALINFO_ENUMPROCW)calinfoproc;
2350 ctxt.lcid = locale;
2351 ctxt.calendar = calendar;
2352 ctxt.caltype = caltype;
2353 ctxt.lParam = 0;
2354 ctxt.unicode = FALSE;
2355 return NLS_EnumCalendarInfo(&ctxt);
2356}
2357
2358/******************************************************************************
2359 * EnumCalendarInfoW [KERNEL32.@]
2360 */
2363{
2364 struct enumcalendar_context ctxt;
2365
2366 TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2367
2368 ctxt.type = CALLBACK_ENUMPROC;
2369 ctxt.u.callback = calinfoproc;
2370 ctxt.lcid = locale;
2371 ctxt.calendar = calendar;
2372 ctxt.caltype = caltype;
2373 ctxt.lParam = 0;
2374 ctxt.unicode = TRUE;
2375 return NLS_EnumCalendarInfo(&ctxt);
2376}
2377
2378/******************************************************************************
2379 * EnumCalendarInfoExA [KERNEL32.@]
2380 */
2383{
2384 struct enumcalendar_context ctxt;
2385
2386 TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2387
2389 ctxt.u.callbackex = (CALINFO_ENUMPROCEXW)calinfoproc;
2390 ctxt.lcid = locale;
2391 ctxt.calendar = calendar;
2392 ctxt.caltype = caltype;
2393 ctxt.lParam = 0;
2394 ctxt.unicode = FALSE;
2395 return NLS_EnumCalendarInfo(&ctxt);
2396}
2397
2398/******************************************************************************
2399 * EnumCalendarInfoExW [KERNEL32.@]
2400 */
2403{
2404 struct enumcalendar_context ctxt;
2405
2406 TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
2407
2409 ctxt.u.callbackex = calinfoproc;
2410 ctxt.lcid = locale;
2411 ctxt.calendar = calendar;
2412 ctxt.caltype = caltype;
2413 ctxt.lParam = 0;
2414 ctxt.unicode = TRUE;
2415 return NLS_EnumCalendarInfo(&ctxt);
2416}
2417
2418#if _WIN32_WINNT >= 0x600
2419/******************************************************************************
2420 * EnumCalendarInfoExEx [KERNEL32.@]
2421 */
2422BOOL WINAPI EnumCalendarInfoExEx( CALINFO_ENUMPROCEXEX calinfoproc, LPCWSTR locale, CALID calendar,
2424{
2425 struct enumcalendar_context ctxt;
2426
2427 TRACE("(%p,%s,0x%08x,%p,0x%08x,0x%ld)\n", calinfoproc, debugstr_w(locale), calendar, reserved, caltype, lParam);
2428
2429 ctxt.type = CALLBACK_ENUMPROCEXEX;
2430 ctxt.u.callbackexex = calinfoproc;
2431 ctxt.lcid = LocaleNameToLCID(locale, 0);
2432 ctxt.calendar = calendar;
2433 ctxt.caltype = caltype;
2434 ctxt.lParam = lParam;
2435 ctxt.unicode = TRUE;
2436 return NLS_EnumCalendarInfo(&ctxt);
2437}
2438#endif /* _WIN32_WINNT >= 0x600 */
2439
2440/*********************************************************************
2441 * GetCalendarInfoA (KERNEL32.@)
2442 *
2443 */
2445 LPSTR lpCalData, int cchData, LPDWORD lpValue)
2446{
2447 int ret, cchDataW = cchData;
2448 LPWSTR lpCalDataW = NULL;
2449#ifdef __REACTOS__
2450 DWORD cp = CP_ACP;
2451 if (!(CalType & CAL_USE_CP_ACP))
2452 {
2453 DWORD dwFlags = ((CalType & CAL_NOUSEROVERRIDE) ? LOCALE_NOUSEROVERRIDE : 0);
2455 if (!node)
2456 {
2458 return 0;
2459 }
2460 cp = node->dwCodePage;
2461 }
2462 if ((CalType & 0xFFFF) == CAL_SABBREVERASTRING)
2463 {
2464 /* NOTE: CAL_SABBREVERASTRING is not supported in GetCalendarInfoA */
2466 return 0;
2467 }
2468#endif
2469
2471 {
2473 return 0;
2474 }
2475
2476 if (!cchData && !(CalType & CAL_RETURN_NUMBER))
2477 cchDataW = GetCalendarInfoW(lcid, Calendar, CalType, NULL, 0, NULL);
2478 if (!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchDataW*sizeof(WCHAR))))
2479 return 0;
2480
2481 ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchDataW, lpValue);
2482 if(ret && lpCalDataW && lpCalData)
2483#ifdef __REACTOS__
2484 ret = WideCharToMultiByte(cp, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
2485#else
2486 ret = WideCharToMultiByte(CP_ACP, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
2487#endif
2488 else if (CalType & CAL_RETURN_NUMBER)
2489 ret *= sizeof(WCHAR);
2490 HeapFree(GetProcessHeap(), 0, lpCalDataW);
2491
2492 return ret;
2493}
2494
2495/*********************************************************************
2496 * GetCalendarInfoW (KERNEL32.@)
2497 *
2498 */
2499int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType,
2500 LPWSTR lpCalData, int cchData, LPDWORD lpValue)
2501{
2502 static const LCTYPE caltype_lctype_map[] = {
2503 0, /* not used */
2504 0, /* CAL_ICALINTVALUE */
2505 0, /* CAL_SCALNAME */
2506 0, /* CAL_IYEAROFFSETRANGE */
2507 0, /* CAL_SERASTRING */
2550 LOCALE_SYEARMONTH,
2551 0, /* CAL_ITWODIGITYEARMAX */
2552#if (WINVER >= 0x0600) /* ReactOS */
2553 LOCALE_SSHORTESTDAYNAME1,
2554 LOCALE_SSHORTESTDAYNAME2,
2555 LOCALE_SSHORTESTDAYNAME3,
2556 LOCALE_SSHORTESTDAYNAME4,
2557 LOCALE_SSHORTESTDAYNAME5,
2558 LOCALE_SSHORTESTDAYNAME6,
2559 LOCALE_SSHORTESTDAYNAME7,
2560#endif
2562 0, /* CAL_SABBREVERASTRING */
2563 };
2564 DWORD localeflags = 0;
2565 CALTYPE calinfo;
2566
2567 if (CalType & CAL_NOUSEROVERRIDE)
2568 FIXME("flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
2569 if (CalType & CAL_USE_CP_ACP)
2570 FIXME("flag CAL_USE_CP_ACP used, not fully implemented\n");
2571
2572 if (CalType & CAL_RETURN_NUMBER) {
2573 if (!lpValue)
2574 {
2576 return 0;
2577 }
2578 if (lpCalData != NULL)
2579 WARN("lpCalData not NULL (%p) when it should!\n", lpCalData);
2580 if (cchData != 0)
2581 WARN("cchData not 0 (%d) when it should!\n", cchData);
2582 } else {
2583 if (lpValue != NULL)
2584 WARN("lpValue not NULL (%p) when it should!\n", lpValue);
2585 }
2586
2587 /* FIXME: No verification is made yet wrt Locale
2588 * for the CALTYPES not requiring GetLocaleInfoA */
2589
2590 calinfo = CalType & 0xffff;
2591
2592#ifdef __REACTOS__
2593 if (CalType & LOCALE_RETURN_GENITIVE_NAMES)
2594#else
2595 if (CalType & CAL_RETURN_GENITIVE_NAMES)
2596#endif
2597 localeflags |= LOCALE_RETURN_GENITIVE_NAMES;
2598
2599 switch (calinfo) {
2600 case CAL_ICALINTVALUE:
2601#ifdef __REACTOS__
2602 if (IS_LCID_JAPANESE(Locale))
2603 {
2604 if (CalType & CAL_RETURN_NUMBER)
2605 {
2606 *lpValue = CAL_JAPAN;
2607 return sizeof(DWORD) / sizeof(WCHAR);
2608 }
2609 else
2610 {
2611 static const WCHAR fmtW[] = {'%','u',0};
2612 WCHAR buffer[10];
2613 int ret = snprintfW( buffer, 10, fmtW, CAL_JAPAN ) + 1;
2614 if (!lpCalData) return ret;
2615 if (ret <= cchData)
2616 {
2617 strcpyW( lpCalData, buffer );
2618 return ret;
2619 }
2621 return 0;
2622 }
2623 }
2624#endif
2625 if (CalType & CAL_RETURN_NUMBER)
2626 return GetLocaleInfoW(Locale, LOCALE_RETURN_NUMBER | LOCALE_ICALENDARTYPE,
2627 (LPWSTR)lpValue, 2);
2628 return GetLocaleInfoW(Locale, LOCALE_ICALENDARTYPE, lpCalData, cchData);
2629 case CAL_SCALNAME:
2630#ifdef __REACTOS__
2631 if (IS_LCID_JAPANESE(Locale) && Calendar == CAL_JAPAN)
2632 {
2633 // Wareki
2634 lpCalData[0] = 0x548C;
2635 lpCalData[1] = 0x66A6;
2636 lpCalData[2] = 0;
2637 return 3;
2638 }
2639#endif
2640 FIXME("Unimplemented caltype %d\n", calinfo);
2641 if (lpCalData) *lpCalData = 0;
2642 return 1;
2644#ifdef __REACTOS__
2645 if (IS_LCID_JAPANESE(Locale) && Calendar == CAL_JAPAN)
2646 {
2648 if (pEra)
2649 {
2650 if (CalType & CAL_RETURN_NUMBER)
2651 {
2652 *lpValue = pEra->wYear;
2653 return sizeof(DWORD) / sizeof(WCHAR);
2654 }
2655 else
2656 {
2657 static const WCHAR fmtW[] = {'%','u',0};
2658 WCHAR buffer[10];
2659 int ret = snprintfW( buffer, 10, fmtW, pEra->wYear ) + 1;
2660 if (!lpCalData) return ret;
2661 if (ret <= cchData)
2662 {
2663 strcpyW( lpCalData, buffer );
2664 return ret;
2665 }
2667 return 0;
2668 }
2669 }
2670 else
2671 {
2673 return 0;
2674 }
2675 }
2676#endif
2677 FIXME("Unimplemented caltype %d\n", calinfo);
2678 return 0;
2679 case CAL_SERASTRING:
2680#ifdef __REACTOS__
2681 if (IS_LCID_JAPANESE(Locale) && Calendar == CAL_JAPAN)
2682 {
2684 if (pEra)
2685 {
2686 RtlStringCchCopyW(lpCalData, cchData, pEra->szEraName);
2687 return strlenW(lpCalData) + 1;
2688 }
2689 else
2690 {
2692 return 0;
2693 }
2694 }
2695#endif
2696 FIXME("Unimplemented caltype %d\n", calinfo);
2697 return 0;
2698 case CAL_SSHORTDATE:
2699 case CAL_SLONGDATE:
2700 case CAL_SDAYNAME1:
2701 case CAL_SDAYNAME2:
2702 case CAL_SDAYNAME3:
2703 case CAL_SDAYNAME4:
2704 case CAL_SDAYNAME5:
2705 case CAL_SDAYNAME6:
2706 case CAL_SDAYNAME7:
2714 case CAL_SMONTHNAME1:
2715 case CAL_SMONTHNAME2:
2716 case CAL_SMONTHNAME3:
2717 case CAL_SMONTHNAME4:
2718 case CAL_SMONTHNAME5:
2719 case CAL_SMONTHNAME6:
2720 case CAL_SMONTHNAME7:
2721 case CAL_SMONTHNAME8:
2722 case CAL_SMONTHNAME9:
2723 case CAL_SMONTHNAME10:
2724 case CAL_SMONTHNAME11:
2725 case CAL_SMONTHNAME12:
2726 case CAL_SMONTHNAME13:
2740 case CAL_SYEARMONTH:
2741 return GetLocaleInfoW(Locale, caltype_lctype_map[calinfo] | localeflags, lpCalData, cchData);
2742 case CAL_ITWODIGITYEARMAX:
2743#ifdef __REACTOS__
2744 if (IS_LCID_JAPANESE(Locale) && Calendar == CAL_JAPAN)
2745 {
2746 if (CalType & CAL_RETURN_NUMBER)
2747 {
2748 *lpValue = JAPANESE_MAX_TWODIGITYEAR;
2749 return sizeof(DWORD) / sizeof(WCHAR);
2750 }
2751 else
2752 {
2753 static const WCHAR fmtW[] = {'%','u',0};
2754 WCHAR buffer[10];
2755 int ret = snprintfW( buffer, 10, fmtW, JAPANESE_MAX_TWODIGITYEAR ) + 1;
2756 if (!lpCalData) return ret;
2757 if (ret <= cchData)
2758 {
2759 strcpyW( lpCalData, buffer );
2760 return ret;
2761 }
2763 return 0;
2764 }
2765 }
2766#endif
2767 if (CalType & CAL_RETURN_NUMBER)
2768 {
2769 *lpValue = CALINFO_MAX_YEAR;
2770 return sizeof(DWORD) / sizeof(WCHAR);
2771 }
2772 else
2773 {
2774 static const WCHAR fmtW[] = {'%','u',0};
2775 WCHAR buffer[10];
2776 int ret = snprintfW( buffer, 10, fmtW, CALINFO_MAX_YEAR ) + 1;
2777 if (!lpCalData) return ret;
2778 if (ret <= cchData)
2779 {
2780 strcpyW( lpCalData, buffer );
2781 return ret;
2782 }
2784 return 0;
2785 }
2786 break;
2787#ifdef __REACTOS__
2789 if (IS_LCID_JAPANESE(Locale) && Calendar == CAL_JAPAN)
2790 {
2792 if (pEra)
2793 {
2794 RtlStringCchCopyW(lpCalData, cchData, pEra->szEraAbbrev);
2795 return strlenW(lpCalData) + 1;
2796 }
2797 }
2799 return 0;
2800#endif
2801 default:
2802 FIXME("Unknown caltype %d\n", calinfo);
2804 return 0;
2805 }
2806 return 0;
2807}
2808
2809#if _WIN32_WINNT >= 0x600
2810/*********************************************************************
2811 * GetCalendarInfoEx (KERNEL32.@)
2812 */
2813int WINAPI GetCalendarInfoEx(LPCWSTR locale, CALID calendar, LPCWSTR lpReserved, CALTYPE caltype,
2814 LPWSTR data, int len, DWORD *value)
2815{
2816 static int once;
2817
2818 LCID lcid = LocaleNameToLCID(locale, 0);
2819 if (!once++)
2820 FIXME("(%s, %d, %p, 0x%08x, %p, %d, %p): semi-stub\n", debugstr_w(locale), calendar, lpReserved, caltype,
2821 data, len, value);
2823}
2824#endif
2825
2826/*********************************************************************
2827 * SetCalendarInfoA (KERNEL32.@)
2828 *
2829 */
2830int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
2831{
2832 FIXME("(%08x,%08x,%08x,%s): stub\n",
2833 Locale, Calendar, CalType, debugstr_a(lpCalData));
2834 return 0;
2835}
2836
2837/*********************************************************************
2838 * SetCalendarInfoW (KERNEL32.@)
2839 *
2840 *
2841 */
2842int WINAPI SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
2843{
2844 FIXME("(%08x,%08x,%08x,%s): stub\n",
2845 Locale, Calendar, CalType, debugstr_w(lpCalData));
2846 return 0;
2847}
#define CAL_SABBREVERASTRING
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
#define ARRAY_SIZE(A)
Definition: main.h:33
#define CHAR(Char)
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
Definition: _locale.h:75
LPARAM lParam
Definition: combotst.c:139
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#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 HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
r reserved
Definition: btrfs.c:3006
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOL JapaneseEra_IsFirstYearGannen(void)
Definition: japanese.c:63
PCJAPANESE_ERA JapaneseEra_Find(const SYSTEMTIME *pst OPTIONAL)
Definition: japanese.c:236
#define JAPANESE_MAX_TWODIGITYEAR
Definition: japanese.h:7
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define nls
Definition: kernel32.h:13
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: lang.c:1028
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: lang.c:1558
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1108
LCID WINAPI ConvertDefaultLocale(LCID lcid)
Definition: lang.c:1512
#define GetNegative(fmt)
Definition: lcformat.c:108
#define NF_DIGITS_OUT
Definition: lcformat.c:1197
#define TIME_FORMAT_FLAGS
Definition: lcformat.c:401
#define CF_CY_SPACE
Definition: lcformat.c:1571
#define NLS_NEG_RIGHT_SPACE
Definition: lcformat.c:1205
#define GET_LOCALE_NUMBER(num, type)
Definition: lcformat.c:181
#define TIME_TIMEVARSONLY
Definition: lcformat.c:81
#define GetLongMonth(fmt, mth)
Definition: lcformat.c:118
#define NLS_NEG_PARENS
Definition: lcformat.c:1201
#define NF_ISNEGATIVE
Definition: lcformat.c:1194
BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
Definition: lcformat.c:2134
#define GetShortMonth(fmt, mth)
Definition: lcformat.c:120
BOOL WINAPI EnumDateFormatsExA(DATEFMT_ENUMPROCEXA proc, LCID lcid, DWORD flags)
Definition: lcformat.c:1982
#define CF_MINUS_BEFORE
Definition: lcformat.c:1568
static INT NLS_GetDateTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpStr, INT cchOut)
Definition: lcformat.c:843
static DWORD NLS_GetLocaleNumber(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:142
INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1044
#define IsDateFmtChar(p)
Definition: lcformat.c:392
#define GetLongDate(fmt)
Definition: lcformat.c:109
#define GetYearMonth(fmt)
Definition: lcformat.c:114
#define GetTime(fmt)
Definition: lcformat.c:111
static WCHAR * NLS_GetLocaleString(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:167
#define GET_LOCALE_STRING(str, type)
Definition: lcformat.c:184
enum_callback_type
Definition: lcformat.c:1884
@ CALLBACK_ENUMPROCEX
Definition: lcformat.c:1886
@ CALLBACK_ENUMPROCEXEX
Definition: lcformat.c:1887
@ CALLBACK_ENUMPROC
Definition: lcformat.c:1885
BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2341
BOOL NLS_IsUnicodeOnlyLcid(LCID lcid)
Definition: lcformat.c:364
static CRITICAL_SECTION NLS_FormatsCS
Definition: lcformat.c:123
#define GetPM(fmt)
Definition: lcformat.c:113
int WINAPI SetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPCWSTR lpCalData)
Definition: lcformat.c:2842
#define NLS_NUM_CACHED_STRINGS
Definition: lcformat.c:92
int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType, LPSTR lpCalData, int cchData, LPDWORD lpValue)
Definition: lcformat.c:2444
static BOOL NLS_EnumCalendarInfo(const struct enumcalendar_context *ctxt)
Definition: lcformat.c:2223
#define NLS_NEG_RIGHT
Definition: lcformat.c:1204
INT WINAPI GetCurrencyFormatA(LCID lcid, DWORD dwFlags, LPCSTR lpszValue, const CURRENCYFMTA *lpFormat, LPSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1496
#define CF_MINUS_LEFT
Definition: lcformat.c:1566
static const NLS_FORMAT_NODE * NLS_GetFormats(LCID lcid, DWORD dwFlags)
Definition: lcformat.c:192
BOOL WINAPI EnumCalendarInfoExA(CALINFO_ENUMPROCEXA calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2381
#define GetShortDay(fmt, day)
Definition: lcformat.c:117
static INT NLS_GetDateTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpStr, INT cchOut)
Definition: lcformat.c:414
BOOL WINAPI EnumCalendarInfoExW(CALINFO_ENUMPROCEXW calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2401
#define CF_MINUS_RIGHT
Definition: lcformat.c:1567
#define NLS_NEG_LEFT
Definition: lcformat.c:1202
#define NLS_NEG_LEFT_SPACE
Definition: lcformat.c:1203
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const NUMBERFMTW *lpFormat, LPWSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1212
INT WINAPI GetDateFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
Definition: lcformat.c:936
#define NF_DIGITS
Definition: lcformat.c:1196
INT WINAPI GetCurrencyFormatW(LCID lcid, DWORD dwFlags, LPCWSTR lpszValue, const CURRENCYFMTW *lpFormat, LPWSTR lpCurrencyStr, int cchOut)
Definition: lcformat.c:1578
INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags, LPCSTR lpszValue, const NUMBERFMTA *lpFormat, LPSTR lpNumberStr, int cchOut)
Definition: lcformat.c:1130
#define GetAM(fmt)
Definition: lcformat.c:112
INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1093
static CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug
Definition: lcformat.c:124
BOOL WINAPI EnumDateFormatsExW(DATEFMT_ENUMPROCEXW proc, LCID lcid, DWORD flags)
Definition: lcformat.c:1998
BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags)
Definition: lcformat.c:2033
#define DATE_FORMAT_FLAGS
Definition: lcformat.c:399
#define IsTimeFmtChar(p)
Definition: lcformat.c:393
#define GetLongDay(fmt, day)
Definition: lcformat.c:116
#define CF_CY_RIGHT
Definition: lcformat.c:1570
static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
Definition: lcformat.c:2077
#define IsLiteralMarker(p)
Definition: lcformat.c:391
BOOL WINAPI EnumCalendarInfoW(CALINFO_ENUMPROCW calinfoproc, LCID locale, CALID calendar, CALTYPE caltype)
Definition: lcformat.c:2361
#define DATE_DATEVARSONLY
Definition: lcformat.c:80
#define NF_ROUND
Definition: lcformat.c:1198
struct _NLS_FORMAT_NODE NLS_FORMAT_NODE
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
Definition: lcformat.c:993
BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW proc, LCID lcid, DWORD flags)
Definition: lcformat.c:2157
#define NF_ISREAL
Definition: lcformat.c:1195
#define GetGenitiveMonth(fmt, mth)
Definition: lcformat.c:119
static BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt)
Definition: lcformat.c:1914
int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
Definition: lcformat.c:2830
int WINAPI GetCalendarInfoW(LCID Locale, CALID Calendar, CALTYPE CalType, LPWSTR lpCalData, int cchData, LPDWORD lpValue)
Definition: lcformat.c:2499
#define GetShortDate(fmt)
Definition: lcformat.c:110
#define CF_CY_LEFT
Definition: lcformat.c:1569
BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
Definition: lcformat.c:2017
#define CF_PARENS
Definition: lcformat.c:1565
POINT cp
Definition: magnifier.c:59
__u16 date
Definition: mkdosfs.c:8
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static unsigned int number
Definition: dsound.c:1479
#define _In_
Definition: ms_sal.h:308
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define DWORD
Definition: nt_native.h:44
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
static HANDLE proc()
Definition: pdb.c:34
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strlenW(s)
Definition: unicode.h:28
#define snprintfW
Definition: unicode.h:60
#define strcpyW(d, s)
Definition: unicode.h:29
const WCHAR * str
#define LANG_KONKANI
Definition: nls.h:83
#define LANG_HINDI
Definition: nls.h:68
#define LANG_SANSKRIT
Definition: nls.h:115
#define LANG_KANNADA
Definition: nls.h:77
#define LANG_GEORGIAN
Definition: nls.h:61
#define LANG_PUNJABI
Definition: nls.h:109
DWORD LCID
Definition: nls.h:13
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_DIVEHI
Definition: nls.h:50
#define LANG_GUJARATI
Definition: nls.h:65
#define LANG_MARATHI
Definition: nls.h:98
#define LANG_ARMENIAN
Definition: nls.h:30
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR szEraAbbrev[5]
Definition: japanese.h:15
WORD wYear
Definition: japanese.h:11
WCHAR szEraName[16]
Definition: japanese.h:14
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883
DWORD dwCodePage
Definition: lcformat.c:98
struct _NLS_FORMAT_NODE * next
Definition: lcformat.c:104
CURRENCYFMTW cyfmt
Definition: lcformat.c:100
WCHAR szShortAM[2]
Definition: lcformat.c:102
NUMBERFMTW fmt
Definition: lcformat.c:99
LPWSTR lppszStrings[NLS_NUM_CACHED_STRINGS]
Definition: lcformat.c:101
WCHAR szShortPM[2]
Definition: lcformat.c:103
WORD wYear
Definition: winbase.h:905
WORD wMonth
Definition: winbase.h:906
WORD wHour
Definition: winbase.h:909
WORD wSecond
Definition: winbase.h:911
WORD wMinute
Definition: winbase.h:910
WORD wDay
Definition: winbase.h:908
WORD wDayOfWeek
Definition: winbase.h:907
UINT LeadingZero
Definition: winnls.h:613
LPWSTR lpDecimalSep
Definition: winnls.h:615
UINT NumDigits
Definition: winnls.h:612
LPWSTR lpCurrencySymbol
Definition: winnls.h:619
UINT PositiveOrder
Definition: winnls.h:618
UINT Grouping
Definition: winnls.h:614
UINT NegativeOrder
Definition: winnls.h:617
LPWSTR lpThousandSep
Definition: winnls.h:616
UINT NumDigits
Definition: winnls.h:642
LPWSTR lpDecimalSep
Definition: winnls.h:645
UINT Grouping
Definition: winnls.h:644
UINT NegativeOrder
Definition: winnls.h:647
LPWSTR lpThousandSep
Definition: winnls.h:646
UINT LeadingZero
Definition: winnls.h:643
union enumcalendar_context::@466 u
enum enum_callback_type type
Definition: lcformat.c:2190
CALINFO_ENUMPROCEXW callbackex
Definition: lcformat.c:2193
CALINFO_ENUMPROCW callback
Definition: lcformat.c:2192
CALINFO_ENUMPROCEXEX callbackexex
Definition: lcformat.c:2194
union enumdateformats_context::@464 u
DATEFMT_ENUMPROCEXW callbackex
Definition: lcformat.c:1894
DATEFMT_ENUMPROCW callback
Definition: lcformat.c:1893
DATEFMT_ENUMPROCEXEX callbackexex
Definition: lcformat.c:1895
enum enum_callback_type type
Definition: lcformat.c:1891
union enumtimeformats_context::@465 u
TIMEFMT_ENUMPROCW callback
Definition: lcformat.c:2068
TIMEFMT_ENUMPROCEX callbackex
Definition: lcformat.c:2069
enum enum_callback_type type
Definition: lcformat.c:2066
Definition: dsound.c:943
Definition: name.c:39
LPCWSTR lpFormat
Definition: trayclock.cpp:32
#define DWORD_PTR
Definition: treelist.c:76
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
Definition: dlist.c:348
void * next
Definition: dlist.c:360
Definition: pdh_main.c:94
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
LONG_PTR LPARAM
Definition: windef.h:208
#define WINAPI
Definition: msvc.h:6
#define ERROR_BADDB
Definition: winerror.h:588
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define LOCALE_USE_CP_ACP
Definition: winnls.h:20
#define LOCALE_SABBREVMONTHNAME10
Definition: winnls.h:113
#define LOCALE_SMONTHNAME12
Definition: winnls.h:102
#define CAL_SMONTHNAME9
Definition: winnls.h:425
#define LOCALE_SMONTHNAME5
Definition: winnls.h:95
#define CAL_SDAYNAME5
Definition: winnls.h:407
#define CAL_SABBREVMONTHNAME8
Definition: winnls.h:437
#define LOCALE_SDAYNAME5
Definition: winnls.h:81
#define CAL_SABBREVMONTHNAME6
Definition: winnls.h:435
#define CAL_SABBREVMONTHNAME12
Definition: winnls.h:441
#define LOCALE_SABBREVMONTHNAME9
Definition: winnls.h:112
#define LOCALE_SABBREVMONTHNAME11
Definition: winnls.h:114
DWORD CALID
Definition: winnls.h:519
#define LOCALE_SABBREVDAYNAME5
Definition: winnls.h:88
#define LOCALE_SABBREVDAYNAME2
Definition: winnls.h:85
#define LOCALE_SABBREVMONTHNAME2
Definition: winnls.h:105
#define CAL_SMONTHNAME6
Definition: winnls.h:422
#define CAL_SCALNAME
Definition: winnls.h:398
BOOL(CALLBACK * CALINFO_ENUMPROCW)(LPWSTR)
Definition: winnls.h:528
#define LOCALE_SMONTHNAME13
Definition: winnls.h:103
#define CAL_SERASTRING
Definition: winnls.h:400
#define CAL_SABBREVMONTHNAME9
Definition: winnls.h:438
#define LOCALE_SGROUPING
Definition: winnls.h:44
#define CAL_SABBREVMONTHNAME10
Definition: winnls.h:439
#define LOCALE_SMONTHNAME3
Definition: winnls.h:93
#define LOCALE_SSHORTTIME
Definition: winnls.h:163
#define LOCALE_SDECIMAL
Definition: winnls.h:42
#define LOCALE_SMONTHNAME11
Definition: winnls.h:101
#define LOCALE_SMONTHNAME8
Definition: winnls.h:98
#define CAL_SABBREVMONTHNAME7
Definition: winnls.h:436
#define LOCALE_SMONTHNAME4
Definition: winnls.h:94
BOOL(CALLBACK * TIMEFMT_ENUMPROCEX)(LPWSTR, LPARAM)
Definition: winnls.h:526
#define CAL_SABBREVDAYNAME7
Definition: winnls.h:416
#define LOCALE_SABBREVMONTHNAME13
Definition: winnls.h:116
#define CAL_SABBREVDAYNAME5
Definition: winnls.h:414
#define LOCALE_SDAYNAME1
Definition: winnls.h:77
#define CAL_SABBREVMONTHNAME11
Definition: winnls.h:440
#define CAL_SMONTHNAME4
Definition: winnls.h:420
BOOL(CALLBACK * DATEFMT_ENUMPROCW)(LPWSTR)
Definition: winnls.h:543
#define LOCALE_SLONGDATE
Definition: winnls.h:61
#define CAL_SABBREVMONTHNAME1
Definition: winnls.h:430
#define LOCALE_SMONTHNAME7
Definition: winnls.h:97
#define CAL_SMONTHNAME8
Definition: winnls.h:424
#define CAL_ICALINTVALUE
Definition: winnls.h:397
BOOL(CALLBACK * DATEFMT_ENUMPROCEXEX)(LPWSTR, CALID, LPARAM)
Definition: winnls.h:525
DWORD CALTYPE
Definition: winnls.h:518
#define CAL_SDAYNAME3
Definition: winnls.h:405
#define LOCALE_S1159
Definition: winnls.h:71
#define CAL_SABBREVMONTHNAME3
Definition: winnls.h:432
int WINAPI GetDateFormatEx(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, int, LPCWSTR)
#define LOCALE_SSHORTDATE
Definition: winnls.h:60
BOOL(CALLBACK * CALINFO_ENUMPROCA)(LPSTR)
Definition: winnls.h:527
#define CAL_SMONTHNAME12
Definition: winnls.h:428
#define TIME_NOTIMEMARKER
Definition: winnls.h:279
BOOL(CALLBACK * TIMEFMT_ENUMPROCA)(LPSTR)
Definition: winnls.h:546
#define TIME_NOMINUTESORSECONDS
Definition: winnls.h:277
#define CAL_SDAYNAME4
Definition: winnls.h:406
#define LOCALE_SABBREVMONTHNAME4
Definition: winnls.h:107
#define CAL_SABBREVMONTHNAME5
Definition: winnls.h:434
#define LOCALE_SABBREVDAYNAME4
Definition: winnls.h:87
#define CAL_JAPAN
Definition: winnls.h:445
#define CAL_SDAYNAME1
Definition: winnls.h:403
#define LOCALE_SMONDECIMALSEP
Definition: winnls.h:51
BOOL(CALLBACK * CALINFO_ENUMPROCEXA)(LPSTR, CALID)
Definition: winnls.h:529
#define CAL_SMONTHNAME7
Definition: winnls.h:423
#define CAL_SSHORTDATE
Definition: winnls.h:401
#define LOCALE_ICURRENCY
Definition: winnls.h:56
#define LOCALE_SMONTHNAME1
Definition: winnls.h:91
#define LOCALE_SABBREVMONTHNAME3
Definition: winnls.h:106
#define CAL_SMONTHNAME11
Definition: winnls.h:427
#define CAL_SMONTHNAME2
Definition: winnls.h:418
#define LOCALE_SMONTHOUSANDSEP
Definition: winnls.h:52
#define LOCALE_SDAYNAME7
Definition: winnls.h:83
#define LOCALE_SDAYNAME2
Definition: winnls.h:78
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:104
#define LOCALE_NOUSEROVERRIDE
Definition: winnls.h:19
#define LOCALE_IOPTIONALCALENDAR
Definition: winnls.h:74
#define CAL_SDAYNAME7
Definition: winnls.h:409
#define LOCALE_IDIGITS
Definition: winnls.h:45
#define CAL_SABBREVDAYNAME6
Definition: winnls.h:415
#define CAL_SLONGDATE
Definition: winnls.h:402
#define CAL_SABBREVDAYNAME4
Definition: winnls.h:413
#define LOCALE_STHOUSAND
Definition: winnls.h:43
#define CAL_SMONTHNAME10
Definition: winnls.h:426
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
#define CAL_SDAYNAME6
Definition: winnls.h:408
#define LOCALE_SABBREVDAYNAME6
Definition: winnls.h:89
#define LOCALE_SMONTHNAME2
Definition: winnls.h:92
#define LOCALE_STIMEFORMAT
Definition: winnls.h:62
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:84
#define LOCALE_SMONTHDAY
Definition: winnls.h:162
#define ENUM_ALL_CALENDARS
Definition: winnls.h:195
#define LOCALE_SABBREVMONTHNAME6
Definition: winnls.h:109
#define LOCALE_SMONTHNAME6
Definition: winnls.h:96
int WINAPI GetTimeFormatEx(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, int)
BOOL(CALLBACK * DATEFMT_ENUMPROCEXW)(LPWSTR, CALID)
Definition: winnls.h:545
#define LOCALE_INEGNUMBER
Definition: winnls.h:47
#define LOCALE_SNEGATIVESIGN
Definition: winnls.h:118
BOOL(CALLBACK * TIMEFMT_ENUMPROCW)(LPWSTR)
Definition: winnls.h:547
DWORD LCTYPE
Definition: winnls.h:517
#define TIME_FORCE24HOURFORMAT
Definition: winnls.h:280
#define LOCALE_SDAYNAME3
Definition: winnls.h:79
#define LOCALE_S2359
Definition: winnls.h:72
#define LOCALE_SABBREVDAYNAME3
Definition: winnls.h:86
#define DATE_USE_ALT_CALENDAR
Definition: winnls.h:198
#define CAL_SMONTHNAME3
Definition: winnls.h:419
#define CAL_SMONTHNAME13
Definition: winnls.h:429
#define LOCALE_ILZERO
Definition: winnls.h:46
#define CAL_IYEAROFFSETRANGE
Definition: winnls.h:399
BOOL(CALLBACK * CALINFO_ENUMPROCEXEX)(LPWSTR, CALID, LPWSTR, LPARAM)
Definition: winnls.h:524
#define LOCALE_SABBREVMONTHNAME5
Definition: winnls.h:108
#define CAL_SABBREVMONTHNAME2
Definition: winnls.h:431
BOOL(CALLBACK * DATEFMT_ENUMPROCA)(LPSTR)
Definition: winnls.h:542
#define LOCALE_SABBREVMONTHNAME7
Definition: winnls.h:110
#define LOCALE_ICALENDARTYPE
Definition: winnls.h:73
BOOL(CALLBACK * DATEFMT_ENUMPROCEXA)(LPSTR, CALID)
Definition: winnls.h:544
#define LOCALE_SABBREVMONTHNAME8
Definition: winnls.h:111
#define CAL_SABBREVDAYNAME2
Definition: winnls.h:411
#define LOCALE_SDAYNAME4
Definition: winnls.h:80
#define TIME_NOSECONDS
Definition: winnls.h:278
#define LOCALE_SCURRENCY
Definition: winnls.h:49
#define LOCALE_SMONTHNAME10
Definition: winnls.h:100
#define LOCALE_INEGCURR
Definition: winnls.h:57
#define LOCALE_SMONTHNAME9
Definition: winnls.h:99
BOOL(CALLBACK * CALINFO_ENUMPROCEXW)(LPWSTR, CALID)
Definition: winnls.h:530
#define CAL_SMONTHNAME1
Definition: winnls.h:417
#define DATE_LONGDATE
Definition: winnls.h:197
#define CAL_SABBREVMONTHNAME13
Definition: winnls.h:442
#define CAL_SMONTHNAME5
Definition: winnls.h:421
#define LOCALE_SABBREVMONTHNAME12
Definition: winnls.h:115
#define LOCALE_SDAYNAME6
Definition: winnls.h:82
#define CAL_SABBREVMONTHNAME4
Definition: winnls.h:433
#define CAL_SABBREVDAYNAME3
Definition: winnls.h:412
#define CAL_SABBREVDAYNAME1
Definition: winnls.h:410
#define LOCALE_RETURN_GENITIVE_NAMES
Definition: winnls.h:24
#define CAL_SDAYNAME2
Definition: winnls.h:404
#define DATE_SHORTDATE
Definition: winnls.h:196
#define LOCALE_SABBREVDAYNAME7
Definition: winnls.h:90
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193