scanfloat_test.c revision 116969
1/*- 2 * Copyright (C) 2003 David Schultz <das@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * Test for scanf() floating point formats. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: head/tools/regression/lib/libc/stdio/test-scanfloat.c 116969 2003-06-28 09:03:44Z das $"); 33 34#include <assert.h> 35#include <float.h> 36#include <locale.h> 37#include <math.h> 38#include <stdio.h> 39#include <string.h> 40 41#define eq(type, a, b) _eq(type##_EPSILON, (a), (b)) 42static int _eq(long double epsilon, long double a, long double b); 43 44extern int __scanfdebug; 45 46int 47main(int argc, char *argv[]) 48{ 49 char buf[128]; 50 long double ld = 0.0; 51 double d = 0.0; 52 float f = 0.0; 53 54 buf[0] = '\0'; 55 assert(setlocale(LC_NUMERIC, "")); 56 57 __scanfdebug = 1; 58 59 sscanf("3.141592", "%e", &f); 60 assert(eq(FLT, f, 3.141592)); 61 62 sscanf("3.141592653589793", "%lf", &d); 63 assert(eq(DBL, d, 3.141592653589793)); 64 65 sscanf("3.14159265358979323846", "%Lg", &ld); 66 assert(eq(LDBL, ld, 3.14159265358979323846L)); 67 68 sscanf("1.234568e+06", "%E", &f); 69 assert(eq(FLT, f, 1.234568e+06)); 70 71 sscanf("-1.234568e6", "%lF", &d); 72 assert(eq(DBL, d, -1.234568e6)); 73 74 sscanf("+1.234568e-52", "%LG", &ld); 75 assert(eq(LDBL, ld, 1.234568e-52L)); 76 77 sscanf("0.1", "%la", &d); 78 assert(eq(DBL, d, 0.1)); 79 80 sscanf("00.2", "%lA", &d); 81 assert(eq(DBL, d, 0.2)); 82 83 sscanf("123456", "%5le%s", &d, buf); 84 assert(eq(DBL, d, 12345.)); 85 assert(strcmp(buf, "6") == 0); 86 87 sscanf("1.0Q", "%*5le%s", buf); 88 assert(strcmp(buf, "Q") == 0); 89 90 sscanf("-1.23e", "%e%s", &f, buf); 91 assert(eq(FLT, f, -1.23)); 92 assert(strcmp(buf, "e") == 0); 93 94 sscanf("1.25e+", "%le%s", &d, buf); 95 assert(eq(DBL, d, 1.25)); 96 assert(strcmp(buf, "e+") == 0); 97 98 sscanf("1.23E4E5", "%le%s", &d, buf); 99 assert(eq(DBL, d, 1.23e4)); 100 assert(strcmp(buf, "E5") == 0); 101 102 sscanf("12e6", "%le", &d); 103 assert(eq(DBL, d, 12e6)); 104 105 sscanf("1.a", "%le%s", &d, buf); 106 assert(eq(DBL, d, 1.0)); 107 assert(strcmp(buf, "a") == 0); 108 109 sscanf(".0p4", "%le%s", &d, buf); 110 assert(eq(DBL, d, 0.0)); 111 assert(strcmp(buf, "p4") == 0); 112 113 d = 0.25; 114 assert(sscanf(".", "%le", &d) == 0); 115 assert(d == 0.25); 116 117 sscanf("0x08", "%le", &d); 118 assert(d == 0x8p0); 119 120 sscanf("0x90a.bcdefP+09a", "%le%s", &d, buf); 121 assert(d == 0x90a.bcdefp+09); 122 assert(strcmp(buf, "a") == 0); 123 124#if LDBL_MANT_DIG > DBL_MANT_DIG 125 sscanf(" 0X.0123456789abcdefffp-3g", "%Le%s", &ld, buf); 126 assert(ld == 0x.0123456789abcdefffp-3L); 127 assert(strcmp(buf, "g") == 0); 128#endif 129 130 sscanf("0xg", "%le%s", &d, buf); 131 assert(d == 0.0); 132 assert(strcmp(buf, "xg") == 0); 133 134 assert(setlocale(LC_NUMERIC, "ru_RU.ISO8859-5")); /* decimalpoint==, */ 135 136 sscanf("1.23", "%le%s", &d, buf); 137 assert(d == 1.0); 138 assert(strcmp(buf, ".23") == 0); 139 140 sscanf("1,23", "%le", &d); 141 assert(d == 1.23); 142 143 assert(setlocale(LC_NUMERIC, "")); 144 145 sscanf("-Inf", "%le", &d); 146 assert(d < 0.0 && isinf(d)); 147 148 sscanf("iNfInItY and beyond", "%le%s", &d, buf); 149 assert(d > 0.0 && isinf(d)); 150 assert(strcmp(buf, " and beyond")); 151 152 sscanf("NaN", "%le", &d); 153 assert(isnan(d)); 154 155 sscanf("NAN(123Y", "%le%s", &d, buf); 156 assert(isnan(d)); 157 assert(strcmp(buf, "(123Y") == 0); 158 159 sscanf("nan(f00f)plugh", "%le%s", &d, buf); 160 assert(isnan(d)); 161 assert(strcmp(buf, "plugh") == 0); 162 163 sscanf("-nan", "%le", &d); 164 assert(isnan(d)); 165 166 printf("PASS scanfloat\n"); 167 168 return (0); 169} 170 171static int 172_eq(long double epsilon, long double a, long double b) 173{ 174 long double delta; 175 176 delta = a - b; 177 if (delta < 0) /* XXX no fabsl() */ 178 delta = -delta; 179 return (delta <= epsilon); 180} 181