1 /* Tests for strfromf, strfromd, strfroml functions. 2 Copyright (C) 2016-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <float.h> 23 #include <math.h> 24 #include <locale.h> 25 26 #include "tst-strtod.h" 27 28 #define _CONCAT(a, b) a ## b 29 #define CONCAT(a, b) _CONCAT (a, b) 30 31 /* Generator to create an FTYPE member variabled named FSUF 32 * used to populate struct member variables. */ 33 #define FTYPE_MEMBER(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ 34 FTYPE FSUF; 35 36 #define STRUCT_FOREACH_FLOAT_FTYPE GEN_TEST_STRTOD_FOREACH (FTYPE_MEMBER) 37 38 #define ENTRY(FSUF, FTYPE, FTOSTR, LSUF, CSUF, ...) \ 39 CONCAT (__VA_ARGS__, LSUF), 40 /* This is hacky way around the seemingly unavoidable macro 41 * expansion of the INFINITY or HUGE_VAL like macros in the 42 * above. It is assumed the compiler will implicitly convert 43 * the infinity correctly. */ 44 #define INF INFINITY + 0.0 45 #define NAN_ NAN + 0.0 46 47 struct test_input 48 { 49 STRUCT_FOREACH_FLOAT_FTYPE 50 }; 51 struct test { 52 const char *s; 53 const char *fmt; 54 int size; 55 int rc; 56 struct test_input t; 57 }; 58 #define TEST(s, fmt, size, rc, val) \ 59 { \ 60 s, fmt, size, rc, { GEN_TEST_STRTOD_FOREACH (ENTRY, val) } \ 61 } 62 /* Hexadecimal tests. */ 63 struct htests 64 { 65 const char *fmt; 66 const char *exp[4]; 67 struct test_input t; 68 }; 69 #define HTEST(fmt, exp1, exp2, exp3, exp4, val) \ 70 { \ 71 fmt, exp1, exp2, exp3, exp4, { GEN_TEST_STRTOD_FOREACH (ENTRY, val) } \ 72 } 73 74 #define TEST_STRFROM(FSUF, FTYPE, FTOSTR, LSUF, CSUF) \ 75 static int \ 76 test_ ## FSUF (void) \ 77 { \ 78 char buf[50], sbuf[5]; \ 79 int status = 0; \ 80 int i, rc = 0, rc1 = 0; \ 81 for (i = 0; i < sizeof (stest) / sizeof (stest[0]); i++) \ 82 { \ 83 rc = FTOSTR (sbuf, stest[i].size, stest[i].fmt, stest[i].t.FSUF); \ 84 rc1 = (strcmp (sbuf, stest[i].s) != 0) || (rc != stest[i].rc); \ 85 if (rc1) \ 86 { \ 87 printf (#FTOSTR ": got %s (%d), expected %s (%d)\n", \ 88 sbuf, rc, stest[i].s, stest[i].rc); \ 89 status++; \ 90 } \ 91 } \ 92 for (i = 0; i < sizeof (tests) / sizeof (tests[0]); i++) \ 93 { \ 94 rc = FTOSTR (buf, tests[i].size, tests[i].fmt, tests[i].t.FSUF); \ 95 rc1 = (strcmp (buf, tests[i].s) != 0) || (rc != tests[i].rc); \ 96 if (rc1) \ 97 { \ 98 printf (#FTOSTR ": got %s (%d), expected %s (%d)\n", \ 99 buf, rc, tests[i].s, tests[i].rc); \ 100 status++; \ 101 } \ 102 } \ 103 for (i = 0; i < sizeof (htest) / sizeof (htest[0]); i++) \ 104 { \ 105 rc = FTOSTR (buf, 50, htest[i].fmt, htest[i].t.FSUF); \ 106 if (strcmp (buf, htest[i].exp[0]) == 0 \ 107 || strcmp (buf, htest[i].exp[1]) == 0 \ 108 || strcmp (buf, htest[i].exp[2]) == 0 \ 109 || strcmp (buf, htest[i].exp[3]) == 0) \ 110 continue; \ 111 else \ 112 { \ 113 printf (#FTOSTR ": got %s (%d), expected %s or %s or %s " \ 114 "or %s\n", buf, rc, htest[i].exp[0], htest[i].exp[1], \ 115 htest[i].exp[2], htest[i].exp[3]); \ 116 status++; \ 117 } \ 118 } \ 119 return status; \ 120 } 121