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