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