nl_langinfo.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /* nl_langinfo() replacement: query locale dependent information.
  2. Copyright (C) 2007-2013 Free Software Foundation, Inc.
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #include <config.h>
  14. /* Specification. */
  15. #include <langinfo.h>
  16. #if REPLACE_NL_LANGINFO
  17. /* Override nl_langinfo with support for added nl_item values. */
  18. # include <locale.h>
  19. # include <string.h>
  20. # undef nl_langinfo
  21. char *
  22. rpl_nl_langinfo (nl_item item)
  23. {
  24. switch (item)
  25. {
  26. # if GNULIB_defined_CODESET
  27. case CODESET:
  28. {
  29. const char *locale;
  30. static char buf[2 + 10 + 1];
  31. locale = setlocale (LC_CTYPE, NULL);
  32. if (locale != NULL && locale[0] != '\0')
  33. {
  34. /* If the locale name contains an encoding after the dot, return
  35. it. */
  36. const char *dot = strchr (locale, '.');
  37. if (dot != NULL)
  38. {
  39. const char *modifier;
  40. dot++;
  41. /* Look for the possible @... trailer and remove it, if any. */
  42. modifier = strchr (dot, '@');
  43. if (modifier == NULL)
  44. return dot;
  45. if (modifier - dot < sizeof (buf))
  46. {
  47. memcpy (buf, dot, modifier - dot);
  48. buf [modifier - dot] = '\0';
  49. return buf;
  50. }
  51. }
  52. }
  53. return "";
  54. }
  55. # endif
  56. # if GNULIB_defined_T_FMT_AMPM
  57. case T_FMT_AMPM:
  58. return "%I:%M:%S %p";
  59. # endif
  60. # if GNULIB_defined_ERA
  61. case ERA:
  62. /* The format is not standardized. In glibc it is a sequence of strings
  63. of the form "direction:offset:start_date:end_date:era_name:era_format"
  64. with an empty string at the end. */
  65. return "";
  66. case ERA_D_FMT:
  67. /* The %Ex conversion in strftime behaves like %x if the locale does not
  68. have an alternative time format. */
  69. item = D_FMT;
  70. break;
  71. case ERA_D_T_FMT:
  72. /* The %Ec conversion in strftime behaves like %c if the locale does not
  73. have an alternative time format. */
  74. item = D_T_FMT;
  75. break;
  76. case ERA_T_FMT:
  77. /* The %EX conversion in strftime behaves like %X if the locale does not
  78. have an alternative time format. */
  79. item = T_FMT;
  80. break;
  81. case ALT_DIGITS:
  82. /* The format is not standardized. In glibc it is a sequence of 10
  83. strings, appended in memory. */
  84. return "\0\0\0\0\0\0\0\0\0\0";
  85. # endif
  86. # if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS
  87. case YESEXPR:
  88. return "^[yY]";
  89. case NOEXPR:
  90. return "^[nN]";
  91. # endif
  92. default:
  93. break;
  94. }
  95. return nl_langinfo (item);
  96. }
  97. #else
  98. /* Provide nl_langinfo from scratch. */
  99. # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  100. /* Native Windows platforms. */
  101. # define WIN32_LEAN_AND_MEAN /* avoid including junk */
  102. # include <windows.h>
  103. # include <stdio.h>
  104. # else
  105. /* An old Unix platform without locales, such as Linux libc5 or BeOS. */
  106. # endif
  107. # include <locale.h>
  108. char *
  109. nl_langinfo (nl_item item)
  110. {
  111. switch (item)
  112. {
  113. /* nl_langinfo items of the LC_CTYPE category */
  114. case CODESET:
  115. # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
  116. {
  117. static char buf[2 + 10 + 1];
  118. /* The Windows API has a function returning the locale's codepage as
  119. a number. */
  120. sprintf (buf, "CP%u", GetACP ());
  121. return buf;
  122. }
  123. # elif defined __BEOS__
  124. return "UTF-8";
  125. # else
  126. return "ISO-8859-1";
  127. # endif
  128. /* nl_langinfo items of the LC_NUMERIC category */
  129. case RADIXCHAR:
  130. return localeconv () ->decimal_point;
  131. case THOUSEP:
  132. return localeconv () ->thousands_sep;
  133. /* nl_langinfo items of the LC_TIME category.
  134. TODO: Really use the locale. */
  135. case D_T_FMT:
  136. case ERA_D_T_FMT:
  137. return "%a %b %e %H:%M:%S %Y";
  138. case D_FMT:
  139. case ERA_D_FMT:
  140. return "%m/%d/%y";
  141. case T_FMT:
  142. case ERA_T_FMT:
  143. return "%H:%M:%S";
  144. case T_FMT_AMPM:
  145. return "%I:%M:%S %p";
  146. case AM_STR:
  147. return "AM";
  148. case PM_STR:
  149. return "PM";
  150. case DAY_1:
  151. return "Sunday";
  152. case DAY_2:
  153. return "Monday";
  154. case DAY_3:
  155. return "Tuesday";
  156. case DAY_4:
  157. return "Wednesday";
  158. case DAY_5:
  159. return "Thursday";
  160. case DAY_6:
  161. return "Friday";
  162. case DAY_7:
  163. return "Saturday";
  164. case ABDAY_1:
  165. return "Sun";
  166. case ABDAY_2:
  167. return "Mon";
  168. case ABDAY_3:
  169. return "Tue";
  170. case ABDAY_4:
  171. return "Wed";
  172. case ABDAY_5:
  173. return "Thu";
  174. case ABDAY_6:
  175. return "Fri";
  176. case ABDAY_7:
  177. return "Sat";
  178. case MON_1:
  179. return "January";
  180. case MON_2:
  181. return "February";
  182. case MON_3:
  183. return "March";
  184. case MON_4:
  185. return "April";
  186. case MON_5:
  187. return "May";
  188. case MON_6:
  189. return "June";
  190. case MON_7:
  191. return "July";
  192. case MON_8:
  193. return "August";
  194. case MON_9:
  195. return "September";
  196. case MON_10:
  197. return "October";
  198. case MON_11:
  199. return "November";
  200. case MON_12:
  201. return "December";
  202. case ABMON_1:
  203. return "Jan";
  204. case ABMON_2:
  205. return "Feb";
  206. case ABMON_3:
  207. return "Mar";
  208. case ABMON_4:
  209. return "Apr";
  210. case ABMON_5:
  211. return "May";
  212. case ABMON_6:
  213. return "Jun";
  214. case ABMON_7:
  215. return "Jul";
  216. case ABMON_8:
  217. return "Aug";
  218. case ABMON_9:
  219. return "Sep";
  220. case ABMON_10:
  221. return "Oct";
  222. case ABMON_11:
  223. return "Nov";
  224. case ABMON_12:
  225. return "Dec";
  226. case ERA:
  227. return "";
  228. case ALT_DIGITS:
  229. return "\0\0\0\0\0\0\0\0\0\0";
  230. /* nl_langinfo items of the LC_MONETARY category
  231. TODO: Really use the locale. */
  232. case CRNCYSTR:
  233. return "-";
  234. /* nl_langinfo items of the LC_MESSAGES category
  235. TODO: Really use the locale. */
  236. case YESEXPR:
  237. return "^[yY]";
  238. case NOEXPR:
  239. return "^[nN]";
  240. default:
  241. return "";
  242. }
  243. }
  244. #endif