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