t-locale.c revision 1.1.1.5 1 1.1 mrg /* Test locale support, or attempt to do so.
2 1.1 mrg
3 1.1.1.5 mrg Copyright 2001, 2002, 2011, 2014, 2020 Free Software Foundation, Inc.
4 1.1 mrg
5 1.1.1.2 mrg This file is part of the GNU MP Library test suite.
6 1.1 mrg
7 1.1.1.2 mrg The GNU MP Library test suite is free software; you can redistribute it
8 1.1.1.2 mrg and/or modify it under the terms of the GNU General Public License as
9 1.1.1.2 mrg published by the Free Software Foundation; either version 3 of the License,
10 1.1.1.2 mrg or (at your option) any later version.
11 1.1.1.2 mrg
12 1.1.1.2 mrg The GNU MP Library test suite is distributed in the hope that it will be
13 1.1.1.2 mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1.1.2 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 1.1.1.2 mrg Public License for more details.
16 1.1 mrg
17 1.1.1.2 mrg You should have received a copy of the GNU General Public License along with
18 1.1.1.3 mrg the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19 1.1 mrg
20 1.1 mrg #define _GNU_SOURCE /* for DECIMAL_POINT in glibc langinfo.h */
21 1.1 mrg
22 1.1 mrg #include "config.h"
23 1.1 mrg
24 1.1 mrg #include <stdio.h>
25 1.1 mrg #include <stdlib.h>
26 1.1 mrg #include <string.h>
27 1.1 mrg
28 1.1 mrg #if HAVE_NL_TYPES_H
29 1.1 mrg #include <nl_types.h> /* for nl_item (on netbsd 1.4.1 at least) */
30 1.1 mrg #endif
31 1.1 mrg
32 1.1 mrg #if HAVE_LANGINFO_H
33 1.1 mrg #include <langinfo.h> /* for nl_langinfo */
34 1.1 mrg #endif
35 1.1 mrg
36 1.1 mrg #if HAVE_LOCALE_H
37 1.1 mrg #include <locale.h> /* for lconv */
38 1.1 mrg #endif
39 1.1 mrg
40 1.1 mrg #include "gmp-impl.h"
41 1.1 mrg #include "tests.h"
42 1.1 mrg
43 1.1.1.2 mrg const char *decimal_point;
44 1.1 mrg
45 1.1 mrg /* Replace the libc localeconv with one we can manipulate. */
46 1.1.1.3 mrg #if HAVE_LOCALECONV && ! defined __MINGW32__
47 1.1 mrg struct lconv *
48 1.1 mrg localeconv (void)
49 1.1.1.3 mrg #if defined __cplusplus && defined __GLIBC__
50 1.1.1.3 mrg throw()
51 1.1.1.3 mrg #endif
52 1.1 mrg {
53 1.1 mrg static struct lconv l;
54 1.1.1.2 mrg l.decimal_point = (char *) decimal_point;
55 1.1 mrg return &l;
56 1.1 mrg }
57 1.1 mrg #endif
58 1.1 mrg
59 1.1 mrg /* Replace the libc nl_langinfo with one we can manipulate. */
60 1.1.1.5 mrg #if HAVE_NL_LANGINFO && ! defined __TERMUX__
61 1.1 mrg char *
62 1.1 mrg nl_langinfo (nl_item n)
63 1.1.1.3 mrg #if defined __cplusplus && defined __GLIBC__
64 1.1.1.3 mrg throw()
65 1.1.1.3 mrg #endif
66 1.1 mrg {
67 1.1 mrg #if defined (DECIMAL_POINT)
68 1.1 mrg if (n == DECIMAL_POINT)
69 1.1.1.2 mrg return (char *) decimal_point;
70 1.1 mrg #endif
71 1.1 mrg #if defined (RADIXCHAR)
72 1.1 mrg if (n == RADIXCHAR)
73 1.1.1.2 mrg return (char *) decimal_point;
74 1.1 mrg #endif
75 1.1.1.2 mrg return (char *) "";
76 1.1 mrg }
77 1.1 mrg #endif
78 1.1 mrg
79 1.1 mrg void
80 1.1 mrg check_input (void)
81 1.1 mrg {
82 1.1.1.2 mrg static const char *point[] = {
83 1.1 mrg ".", ",", "WU", "STR", "ZTV***"
84 1.1 mrg };
85 1.1 mrg
86 1.1 mrg static const struct {
87 1.1 mrg const char *str;
88 1.1 mrg double d;
89 1.1 mrg } data[] = {
90 1.1 mrg
91 1.1 mrg { "1%s", 1.0 },
92 1.1 mrg { "1%s0", 1.0 },
93 1.1 mrg { "1%s00", 1.0 },
94 1.1 mrg
95 1.1 mrg { "%s5", 0.5 },
96 1.1 mrg { "0%s5", 0.5 },
97 1.1 mrg { "00%s5", 0.5 },
98 1.1 mrg { "00%s50", 0.5 },
99 1.1 mrg
100 1.1 mrg { "1%s5", 1.5 },
101 1.1 mrg { "1%s5e1", 15.0 },
102 1.1 mrg };
103 1.1 mrg
104 1.1 mrg int i, j, neg, ret;
105 1.1 mrg char str[128];
106 1.1 mrg mpf_t f;
107 1.1 mrg double d;
108 1.1 mrg
109 1.1 mrg mpf_init (f);
110 1.1 mrg
111 1.1 mrg for (i = 0; i < numberof (point); i++)
112 1.1 mrg {
113 1.1.1.2 mrg decimal_point = (const char *) point[i];
114 1.1 mrg
115 1.1 mrg for (neg = 0; neg <= 1; neg++)
116 1.1 mrg {
117 1.1 mrg for (j = 0; j < numberof (data); j++)
118 1.1 mrg {
119 1.1 mrg strcpy (str, neg ? "-" : "");
120 1.1 mrg sprintf (str+strlen(str), data[j].str, decimal_point);
121 1.1 mrg
122 1.1 mrg d = data[j].d;
123 1.1 mrg if (neg)
124 1.1 mrg d = -d;
125 1.1 mrg
126 1.1 mrg mpf_set_d (f, 123.0);
127 1.1 mrg if (mpf_set_str (f, str, 10) != 0)
128 1.1 mrg {
129 1.1 mrg printf ("mpf_set_str error\n");
130 1.1 mrg printf (" point %s\n", decimal_point);
131 1.1 mrg printf (" str %s\n", str);
132 1.1 mrg abort ();
133 1.1 mrg }
134 1.1 mrg if (mpf_cmp_d (f, d) != 0)
135 1.1 mrg {
136 1.1 mrg printf ("mpf_set_str wrong result\n");
137 1.1 mrg printf (" point %s\n", decimal_point);
138 1.1 mrg printf (" str %s\n", str);
139 1.1 mrg mpf_trace (" f", f);
140 1.1 mrg printf (" d=%g\n", d);
141 1.1 mrg abort ();
142 1.1 mrg }
143 1.1 mrg
144 1.1 mrg mpf_set_d (f, 123.0);
145 1.1 mrg ret = gmp_sscanf (str, "%Ff", f);
146 1.1 mrg if (ret != 1)
147 1.1 mrg {
148 1.1 mrg printf ("gmp_sscanf wrong return value\n");
149 1.1 mrg printf (" point %s\n", decimal_point);
150 1.1 mrg printf (" str %s\n", str);
151 1.1 mrg printf (" ret %d\n", ret);
152 1.1 mrg abort ();
153 1.1 mrg }
154 1.1 mrg if (mpf_cmp_d (f, d) != 0)
155 1.1 mrg {
156 1.1 mrg printf ("gmp_sscanf wrong result\n");
157 1.1 mrg printf (" point %s\n", decimal_point);
158 1.1 mrg printf (" str %s\n", str);
159 1.1 mrg mpf_trace (" f", f);
160 1.1 mrg printf (" d=%g\n", d);
161 1.1 mrg abort ();
162 1.1 mrg }
163 1.1 mrg }
164 1.1 mrg }
165 1.1 mrg }
166 1.1 mrg mpf_clear (f);
167 1.1 mrg }
168 1.1 mrg
169 1.1 mrg int
170 1.1 mrg main (void)
171 1.1 mrg {
172 1.1 mrg /* The localeconv replacement breaks printf "%lu" on SunOS 4, so we can't
173 1.1 mrg print the seed in tests_rand_start(). Nothing random is used in this
174 1.1 mrg program though, so just use the memory tests alone. */
175 1.1 mrg tests_memory_start ();
176 1.1 mrg
177 1.1 mrg {
178 1.1 mrg mpf_t f;
179 1.1 mrg char buf[128];
180 1.1 mrg mpf_init (f);
181 1.1 mrg decimal_point = ",";
182 1.1 mrg mpf_set_d (f, 1.5);
183 1.1 mrg gmp_snprintf (buf, sizeof(buf), "%.1Ff", f);
184 1.1 mrg mpf_clear (f);
185 1.1 mrg if (strcmp (buf, "1,5") != 0)
186 1.1 mrg {
187 1.1 mrg printf ("Test skipped, replacing localeconv/nl_langinfo doesn't work\n");
188 1.1 mrg goto done;
189 1.1 mrg }
190 1.1 mrg }
191 1.1 mrg
192 1.1 mrg check_input ();
193 1.1 mrg
194 1.1 mrg done:
195 1.1 mrg tests_memory_end ();
196 1.1 mrg exit (0);
197 1.1 mrg }
198