Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
5.5 KiB

  1. /***
  2. *inithelp.c - Contains the __getlocaleinfo helper routine
  3. *
  4. * Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Contains the __getlocaleinfo helper routine.
  8. *
  9. *Revision History:
  10. * 12-28-92 CFW Module created, _getlocaleinfo ported to Cuda tree.
  11. * 12-29-92 CFW Update for new GetLocaleInfoW, add LC_*_TYPE handling.
  12. * 01-25-93 KRS Change category argument to LCID.
  13. * 02-02-93 CFW Optimized INT case, bug fix in STR case.
  14. * 02-08-93 CFW Optimized GetQualifiedLocale call, cast to remove warnings.
  15. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  16. * 04-20-93 CFW JonM's GetLocaleInfoW fixup, cast to avoid trashing memory.
  17. * 05-24-93 CFW Clean up file (brief is evil).
  18. * 09-15-93 CFW Use ANSI conformant "__" names.
  19. * 09-22-93 CFW Use __crtxxx internal NLS API wrapper.
  20. * 09-22-93 CFW NT merge.
  21. * 11-09-93 CFW Add code page for __crtxxx().
  22. * 03-31-94 CFW Include awint.h.
  23. * 04-15-94 GJF Made definition of wcbuffer conditional on
  24. * DLL_FOR_WIN32S
  25. * 09-06-94 CFW Remove _INTL switch.
  26. * 01-10-95 CFW Debug CRT allocs.
  27. * 02-02-95 BWT Update POSIX support.
  28. * 05-13-99 PML Remove Win32s
  29. *
  30. *******************************************************************************/
  31. #include <stdlib.h>
  32. #include <cruntime.h>
  33. #include <locale.h>
  34. #include <setlocal.h>
  35. #include <awint.h>
  36. #include <dbgint.h>
  37. /***
  38. *__getlocaleinfo - return locale data
  39. *
  40. *Purpose:
  41. * Return locale data appropriate for the setlocale init functions.
  42. * In particular, wide locale strings are converted to char strings
  43. * or numeric depending on the value of the first parameter.
  44. *
  45. * Memory is allocated for the char version of the data, and the
  46. * calling function's pointer is set to it. This pointer should later
  47. * be used to free the data. The wide-char data is fetched using
  48. * GetLocaleInfo and converted to multibyte using WideCharToMultiByte.
  49. *
  50. * *** For internal use by the __init_* functions only ***
  51. *
  52. * *** Future optimization ***
  53. * When converting a large number of wide-strings to multibyte, do
  54. * not query the size of the result, but convert them one after
  55. * another into a large character buffer. The entire buffer can
  56. * also be freed with one pointer.
  57. *
  58. *Entry:
  59. * int lc_type - LC_STR_TYPE for string data, LC_INT_TYPE for numeric data
  60. * LCID localehandle - LCID based on category and lang or ctry of __lc_id
  61. * LCTYPE fieldtype - int or string value
  62. * void *address - cast to either char * or char**
  63. *
  64. *Exit:
  65. * 0 success
  66. * -1 failure
  67. *
  68. *Exceptions:
  69. *
  70. *******************************************************************************/
  71. #if NO_ERROR == -1 /*IFSTRIP=IGN*/
  72. #error Need to use another error return code in __getlocaleinfo
  73. #endif
  74. #define STR_CHAR_CNT 128
  75. #define INT_CHAR_CNT 4
  76. int __cdecl __getlocaleinfo (
  77. int lc_type,
  78. LCID localehandle,
  79. LCTYPE fieldtype,
  80. void *address
  81. )
  82. {
  83. #if !defined(_POSIX_)
  84. if (lc_type == LC_STR_TYPE)
  85. {
  86. char **straddress = (char **)address;
  87. unsigned char cbuffer[STR_CHAR_CNT];
  88. unsigned char *pcbuffer = cbuffer;
  89. int bufferused = 0; /* 1 indicates buffer points to malloc'ed memory */
  90. int buffersize = STR_CHAR_CNT;
  91. int outsize;
  92. if ((outsize = __crtGetLocaleInfoA(localehandle, fieldtype, pcbuffer, buffersize, 0))
  93. == 0)
  94. {
  95. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
  96. goto error;
  97. /* buffersize too small, get required size and malloc new buffer */
  98. if ((buffersize = __crtGetLocaleInfoA (localehandle, fieldtype, NULL, 0, 0))
  99. == 0)
  100. goto error;
  101. if ((pcbuffer = (unsigned char *) _malloc_crt (buffersize * sizeof(unsigned char)))
  102. == NULL)
  103. goto error;
  104. bufferused = 1;
  105. if ((outsize = __crtGetLocaleInfoA (localehandle, fieldtype, pcbuffer, buffersize, 0))
  106. == 0)
  107. goto error;
  108. }
  109. if ((*straddress = (char *) _malloc_crt (outsize * sizeof(char))) == NULL)
  110. goto error;
  111. strncpy(*straddress, pcbuffer, outsize);
  112. if (bufferused)
  113. _free_crt (pcbuffer);
  114. return 0;
  115. error:
  116. if (bufferused)
  117. _free_crt (pcbuffer);
  118. return -1;
  119. } else if (lc_type == LC_INT_TYPE)
  120. {
  121. int i;
  122. char c;
  123. static wchar_t wcbuffer[INT_CHAR_CNT];
  124. const int buffersize = INT_CHAR_CNT;
  125. char *charaddress = (char *)address;
  126. if (__crtGetLocaleInfoW (localehandle, fieldtype, (LPWSTR)&wcbuffer, buffersize, 0) == 0)
  127. return -1;
  128. *(char *)charaddress = 0;
  129. /* assume GetLocaleInfoW returns valid ASCII integer in wcstr format */
  130. for (i = 0; i < INT_CHAR_CNT; i++)
  131. {
  132. if (isdigit(((unsigned char)c = (unsigned char)wcbuffer[i])))
  133. *(unsigned char *)charaddress = (unsigned char)(10 * (int)(*charaddress) + (c - '0'));
  134. else
  135. break;
  136. }
  137. return 0;
  138. }
  139. #endif /* _POSIX_ */
  140. return -1;
  141. }