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