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