xref: /netbsd-src/external/lgpl3/gmp/dist/tests/misc/t-locale.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /* Test locale support, or attempt to do so.
2 
3 Copyright 2001, 2002, 2011 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 http://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 #ifdef __MINGW32__
45 int
46 main (void)
47 {
48   exit (0);
49 }
50 #else
51 
52 const char *decimal_point;
53 
54 /* Replace the libc localeconv with one we can manipulate. */
55 #if HAVE_LOCALECONV
56 struct lconv *
57 localeconv (void)
58 {
59   static struct lconv  l;
60   l.decimal_point = (char *) decimal_point;
61   return &l;
62 }
63 #endif
64 
65 /* Replace the libc nl_langinfo with one we can manipulate. */
66 #if HAVE_NL_LANGINFO
67 char *
68 nl_langinfo (nl_item n)
69 {
70 #if defined (DECIMAL_POINT)
71   if (n == DECIMAL_POINT)
72     return (char *) decimal_point;
73 #endif
74 #if defined (RADIXCHAR)
75   if (n == RADIXCHAR)
76     return (char *) decimal_point;
77 #endif
78   return (char *) "";
79 }
80 #endif
81 
82 void
83 check_input (void)
84 {
85   static const char *point[] = {
86     ".", ",", "WU", "STR", "ZTV***"
87   };
88 
89   static const struct {
90     const char  *str;
91     double      d;
92   } data[] = {
93 
94     { "1%s",   1.0 },
95     { "1%s0",  1.0 },
96     { "1%s00", 1.0 },
97 
98     { "%s5",    0.5 },
99     { "0%s5",   0.5 },
100     { "00%s5",  0.5 },
101     { "00%s50", 0.5 },
102 
103     { "1%s5",    1.5 },
104     { "1%s5e1", 15.0 },
105   };
106 
107   int     i, j, neg, ret;
108   char    str[128];
109   mpf_t   f;
110   double  d;
111 
112   mpf_init (f);
113 
114   for (i = 0; i < numberof (point); i++)
115     {
116       decimal_point = (const char *) point[i];
117 
118       for (neg = 0; neg <= 1; neg++)
119         {
120           for (j = 0; j < numberof (data); j++)
121             {
122               strcpy (str, neg ? "-" : "");
123               sprintf (str+strlen(str), data[j].str, decimal_point);
124 
125               d = data[j].d;
126               if (neg)
127                 d = -d;
128 
129               mpf_set_d (f, 123.0);
130               if (mpf_set_str (f, str, 10) != 0)
131                 {
132                   printf ("mpf_set_str error\n");
133                   printf ("  point  %s\n", decimal_point);
134                   printf ("  str    %s\n", str);
135                   abort ();
136                 }
137               if (mpf_cmp_d (f, d) != 0)
138                 {
139                   printf    ("mpf_set_str wrong result\n");
140                   printf    ("  point  %s\n", decimal_point);
141                   printf    ("  str    %s\n", str);
142                   mpf_trace ("  f", f);
143                   printf    ("  d=%g\n", d);
144                   abort ();
145                 }
146 
147               mpf_set_d (f, 123.0);
148               ret = gmp_sscanf (str, "%Ff", f);
149               if (ret != 1)
150                 {
151                   printf ("gmp_sscanf wrong return value\n");
152                   printf ("  point  %s\n", decimal_point);
153                   printf ("  str    %s\n", str);
154                   printf ("  ret    %d\n", ret);
155                   abort ();
156                 }
157               if (mpf_cmp_d (f, d) != 0)
158                 {
159                   printf    ("gmp_sscanf wrong result\n");
160                   printf    ("  point  %s\n", decimal_point);
161                   printf    ("  str    %s\n", str);
162                   mpf_trace ("  f", f);
163                   printf    ("  d=%g\n", d);
164                   abort ();
165                 }
166             }
167         }
168     }
169   mpf_clear (f);
170 }
171 
172 int
173 main (void)
174 {
175   /* The localeconv replacement breaks printf "%lu" on SunOS 4, so we can't
176      print the seed in tests_rand_start().  Nothing random is used in this
177      program though, so just use the memory tests alone.  */
178   tests_memory_start ();
179 
180   {
181     mpf_t  f;
182     char   buf[128];
183     mpf_init (f);
184     decimal_point = ",";
185     mpf_set_d (f, 1.5);
186     gmp_snprintf (buf, sizeof(buf), "%.1Ff", f);
187     mpf_clear (f);
188     if (strcmp (buf, "1,5") != 0)
189       {
190         printf ("Test skipped, replacing localeconv/nl_langinfo doesn't work\n");
191         goto done;
192       }
193   }
194 
195   check_input ();
196 
197  done:
198   tests_memory_end ();
199   exit (0);
200 }
201 #endif
202