1/* Test locale support, or attempt to do so. 2 3Copyright 2001, 2002 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along 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#ifdef __MINGW32__ 45int 46main (void) 47{ 48 exit (0); 49} 50#else 51 52char *decimal_point; 53 54/* Replace the libc localeconv with one we can manipulate. */ 55#if HAVE_LOCALECONV 56struct lconv * 57localeconv (void) 58{ 59 static struct lconv l; 60 l.decimal_point = 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 67char * 68nl_langinfo (nl_item n) 69{ 70#if defined (DECIMAL_POINT) 71 if (n == DECIMAL_POINT) 72 return decimal_point; 73#endif 74#if defined (RADIXCHAR) 75 if (n == RADIXCHAR) 76 return decimal_point; 77#endif 78 return ""; 79} 80#endif 81 82void 83check_input (void) 84{ 85 static 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 = 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 172int 173main (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