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