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