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