tst-strfmon_l.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /* Test locale dependence of strfmon_l.
  2. Copyright (C) 2016-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <stdbool.h>
  16. #include <stdio.h>
  17. #include <monetary.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <locale.h>
  21. static const char *const en_us_name = "en_US.ISO-8859-1";
  22. /* Locale value to be used by tests. */
  23. static locale_t loc;
  24. static const char *loc_name;
  25. /* Set the global locale to GLOBAL_NAME, and the locale referenced by
  26. the loc variable above to LOCAL_NAME. */
  27. static void
  28. init_loc (const char *global_name, const char *local_name)
  29. {
  30. loc = newlocale (LC_ALL_MASK, local_name, 0);
  31. if (loc == 0)
  32. {
  33. printf ("error: newlocale (%s): %m\n", local_name);
  34. abort ();
  35. }
  36. loc_name = local_name;
  37. if (setlocale (LC_ALL, global_name) == NULL)
  38. {
  39. printf ("error: setlocale (%s): %m\n", global_name);
  40. abort ();
  41. }
  42. }
  43. /* Expected strings for a positive or negative value. */
  44. struct testcase
  45. {
  46. const char *i; /* %i */
  47. const char *n; /* %n */
  48. const char *i_ungrouped; /* %^i */
  49. const char *n_ungrouped; /* %^n */
  50. };
  51. /* Collected expected strings for both positive and negative
  52. values. */
  53. struct testcase_pair
  54. {
  55. struct testcase positive; /* 1234567.89 */
  56. struct testcase negative; /* -1234567.89 */
  57. };
  58. static bool errors;
  59. /* Test one value using the locale loc. */
  60. static void
  61. test_one (const char *format, double value, const char *ldformat,
  62. long double ldvalue, const char *expected)
  63. {
  64. static char actual[64], actualld[64];
  65. int result = strfmon_l (actual, sizeof (actual), loc, format, value);
  66. int res_ld = strfmon_l (actualld, sizeof (actualld), loc, ldformat, ldvalue);
  67. if (result < 0)
  68. {
  69. printf ("error: locale %s, format \"%s\", value %g: strfmon_l: %m\n",
  70. loc_name, format, value);
  71. errors = true;
  72. }
  73. else if (res_ld < 0)
  74. {
  75. printf ("error: locale %s, format \"%s\", value %Lg: strfmon_l: %m\n",
  76. loc_name, ldformat, ldvalue);
  77. errors = true;
  78. }
  79. else if (strcmp (actual, expected) != 0)
  80. {
  81. printf ("error: locale %s, format \"%s\", value %g: mismatch\n",
  82. loc_name, format, value);
  83. printf ("error: expected: \"%s\"\n", expected);
  84. printf ("error: actual: \"%s\"\n", actual);
  85. errors = true;
  86. }
  87. else if (strcmp (actualld, expected) != 0)
  88. {
  89. printf ("error: locale %s, format \"%s\", value %Lg: mismatch\n",
  90. loc_name, ldformat, ldvalue);
  91. printf ("error: expected: \"%s\"\n", expected);
  92. printf ("error: actual: \"%s\"\n", actualld);
  93. errors = true;
  94. }
  95. }
  96. static void
  97. test_pair (const struct testcase_pair *pair)
  98. {
  99. double positive = 1234567.89;
  100. long double pos = 1234567.89L;
  101. test_one ("%i", positive, "%Li", pos, pair->positive.i);
  102. test_one ("%n", positive, "%Ln", pos, pair->positive.n);
  103. test_one ("%^i", positive, "%^Li", pos, pair->positive.i_ungrouped);
  104. test_one ("%^n", positive, "%^Ln", pos, pair->positive.n_ungrouped);
  105. double negative = -1234567.89;
  106. long double neg = -1234567.89L;
  107. test_one ("%i", negative, "%Li", neg, pair->negative.i);
  108. test_one ("%n", negative, "%Ln", neg, pair->negative.n);
  109. test_one ("%^i", negative, "%^Li", neg, pair->negative.i_ungrouped);
  110. test_one ("%^n", negative, "%^Ln", neg, pair->negative.n_ungrouped);
  111. }
  112. static const struct testcase_pair en_us =
  113. {
  114. {
  115. "USD 1,234,567.89", "$1,234,567.89",
  116. "USD 1234567.89", "$1234567.89"
  117. },
  118. {
  119. "-USD 1,234,567.89", "-$1,234,567.89",
  120. "-USD 1234567.89", "-$1234567.89"
  121. }
  122. };
  123. static void
  124. test_en_us (const char *other_name)
  125. {
  126. init_loc (other_name, en_us_name);
  127. test_pair (&en_us);
  128. freelocale (loc);
  129. }
  130. struct locale_pair
  131. {
  132. const char *locale_name;
  133. struct testcase_pair pair;
  134. };
  135. static const struct locale_pair tests[] =
  136. {
  137. {
  138. "de_DE.UTF-8",
  139. {
  140. {
  141. "1.234.567,89 EUR", "1.234.567,89 \u20ac",
  142. "1234567,89 EUR", "1234567,89 \u20ac"
  143. },
  144. {
  145. "-1.234.567,89 EUR", "-1.234.567,89 \u20ac",
  146. "-1234567,89 EUR", "-1234567,89 \u20ac"
  147. }
  148. },
  149. },
  150. {
  151. "tg_TJ.UTF-8",
  152. {
  153. {
  154. "1\u202f234\u202f567.89 TJS", "1\u202f234\u202f567.89 \u0440\u0443\u0431",
  155. "1234567.89 TJS", "1234567.89 \u0440\u0443\u0431"
  156. },
  157. {
  158. "-1\u202f234\u202f567.89 TJS", "-1\u202f234\u202f567.89 \u0440\u0443\u0431",
  159. "-1234567.89 TJS", "-1234567.89 \u0440\u0443\u0431"
  160. }
  161. }
  162. },
  163. {
  164. "hr_HR.UTF-8",
  165. {
  166. {
  167. "HRK 1.234.567,89", "1.234.567,89 kn",
  168. "HRK 1234567,89", "1234567,89 kn"
  169. },
  170. {
  171. "-HRK 1.234.567,89", "-1.234.567,89 kn",
  172. "-HRK 1234567,89", "-1234567,89 kn"
  173. }
  174. }
  175. },
  176. {
  177. "hi_IN.UTF-8",
  178. {
  179. {
  180. "INR12,34,567.89", "\u20b912,34,567.89",
  181. "INR1234567.89", "\u20b91234567.89"
  182. },
  183. {
  184. "-INR12,34,567.89", "-\u20b912,34,567.89",
  185. "-INR1234567.89", "-\u20b91234567.89"
  186. }
  187. }
  188. },
  189. {
  190. "el_GR.UTF-8",
  191. {
  192. {
  193. "1.234.567,89EUR", "1.234.567,89\u20ac",
  194. "1234567,89EUR", "1234567,89\u20ac"
  195. },
  196. {
  197. "-1.234.567,89EUR", "-1.234.567,89\u20ac",
  198. "-1234567,89EUR", "-1234567,89\u20ac",
  199. }
  200. }
  201. },
  202. {}
  203. };
  204. static int
  205. do_test (void)
  206. {
  207. for (const struct locale_pair *test = tests;
  208. test->locale_name != NULL; ++test)
  209. {
  210. init_loc (en_us_name, test->locale_name);
  211. test_pair (&test->pair);
  212. freelocale (loc);
  213. test_en_us (test->locale_name);
  214. }
  215. return errors;
  216. }
  217. #define TEST_FUNCTION do_test ()
  218. #include "../test-skeleton.c"