]> git.ipfire.org Git - thirdparty/glibc.git/blame - misc/tst-efgcvt-template.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / misc / tst-efgcvt-template.c
CommitLineData
04277e02 1/* Copyright (C) 1998-2019 Free Software Foundation, Inc.
07b51ba5
UD
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
07b51ba5
UD
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
07b51ba5 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
07b51ba5 17
bd51ff5e
GG
18/* This template provides testing for the *cvt family of functions,
19 which deal with double or long double types. In order to use the
20 template, the following macros must be defined before inclusion of
21 this template:
22
23 FLOAT: The floating-point type, i.e. double or long double.
24
25 ECVT: Appropriate *ecvt function for FLOAT, i.e. ecvt or qecvt.
26 FCVT: Likewise for *fcvt, i.e. fcvt or qfcvt.
27 ECVT_R: Likewise for *ecvt_r, i.e. ecvt_r or qecvt_r.
28 FCVT_R: Likewise for *fcvt_r, i.e. fcvt_r or qfcvt_r.
29
30 PRINTF_CONVERSION: The appropriate printf conversion specifier with
31 length modifier for FLOAT, i.e. "%f" or "%Lf".
32
33 EXTRA_ECVT_TESTS: Additional tests for the ecvt or qecvt function
34 that are only relevant to a particular floating-point type and
35 cannot be represented generically. */
36
da2d1bc5
UD
37#ifndef _GNU_SOURCE
38# define _GNU_SOURCE 1
39#endif
40
41#include <math.h>
07b51ba5
UD
42#include <stdio.h>
43#include <stdlib.h>
3e1f480e 44#include <string.h>
07b51ba5 45
968ed530 46#include <support/check.h>
da2d1bc5 47
bd51ff5e
GG
48#define NAME(x) NAMEX(x)
49#define NAMEX(x) #x
50
a7f804d8 51typedef struct
da2d1bc5 52{
bd51ff5e 53 FLOAT value;
da2d1bc5
UD
54 int ndigit;
55 int decpt;
56 char result[30];
57} testcase;
58
bd51ff5e 59typedef char * ((*efcvt_func) (FLOAT, int, int *, int *));
da2d1bc5 60
bd51ff5e 61typedef int ((*efcvt_r_func) (FLOAT, int, int *, int *, char *, size_t));
c9e17a9c 62
da2d1bc5
UD
63
64static testcase ecvt_tests[] =
65{
66 { 0.0, 0, 1, "" },
67 { 10.0, 0, 2, "" },
68 { 10.0, 1, 2, "1" },
69 { 10.0, 5, 2, "10000" },
70 { -12.0, 5, 2, "12000" },
71 { 0.2, 4, 0, "2000" },
72 { 0.02, 4, -1, "2000" },
73 { 5.5, 1, 1, "6" },
74 { 1.0, -1, 1, "" },
75 { 0.01, 2, -1, "10" },
1eb687d0
UD
76 { 100.0, -2, 3, "" },
77 { 100.0, -5, 3, "" },
78 { 100.0, -4, 3, "" },
79 { 100.01, -4, 3, "" },
80 { 123.01, -4, 3, "" },
81 { 126.71, -4, 3, "" },
a7f804d8 82 { 0.0, 4, 1, "0000" },
bd51ff5e 83 EXTRA_ECVT_TESTS
da2d1bc5
UD
84 /* -1.0 is end marker. */
85 { -1.0, 0, 0, "" }
86};
87
88static testcase fcvt_tests[] =
89{
90 { 0.0, 0, 1, "0" },
91 { 10.0, 0, 2, "10" },
92 { 10.0, 1, 2, "100" },
93 { 10.0, 4, 2, "100000" },
94 { -12.0, 5, 2, "1200000" },
95 { 0.2, 4, 0, "2000" },
96 { 0.02, 4, -1, "200" },
97 { 5.5, 1, 1, "55" },
98 { 5.5, 0, 1, "6" },
99 { 0.01, 2, -1, "1" },
1eb687d0
UD
100 { 100.0, -2, 3, "100" },
101 { 100.0, -5, 3, "100" },
102 { 100.0, -4, 3, "100" },
103 { 100.01, -4, 3, "100" },
104 { 123.01, -4, 3, "100" },
105 { 126.71, -4, 3, "100" },
887e7ab6 106 { 322.5, 16, 3, "3225000000000000000" },
da2d1bc5
UD
107 /* -1.0 is end marker. */
108 { -1.0, 0, 0, "" }
109};
110
de149cdb 111static void
bd51ff5e 112output_error (const char *name, FLOAT value, int ndigit,
da2d1bc5
UD
113 const char *exp_p, int exp_decpt, int exp_sign,
114 char *res_p, int res_decpt, int res_sign)
115{
bd51ff5e
GG
116 printf ("%s returned wrong result for value: " PRINTF_CONVERSION
117 ", ndigits: %d\n",
da2d1bc5
UD
118 name, value, ndigit);
119 printf ("Result was p: \"%s\", decpt: %d, sign: %d\n",
120 res_p, res_decpt, res_sign);
121 printf ("Should be p: \"%s\", decpt: %d, sign: %d\n",
122 exp_p, exp_decpt, exp_sign);
968ed530 123 support_record_failure ();
da2d1bc5
UD
124}
125
c9e17a9c 126
de149cdb 127static void
bd51ff5e 128output_r_error (const char *name, FLOAT value, int ndigit,
c9e17a9c
UD
129 const char *exp_p, int exp_decpt, int exp_sign, int exp_return,
130 char *res_p, int res_decpt, int res_sign, int res_return)
131{
bd51ff5e
GG
132 printf ("%s returned wrong result for value: " PRINTF_CONVERSION
133 ", ndigits: %d\n",
c9e17a9c
UD
134 name, value, ndigit);
135 printf ("Result was buf: \"%s\", decpt: %d, sign: %d return value: %d\n",
136 res_p, res_decpt, res_sign, res_return);
137 printf ("Should be buf: \"%s\", decpt: %d, sign: %d\n",
1fc6f813 138 exp_p, exp_decpt, exp_sign);
968ed530 139 support_record_failure ();
c9e17a9c
UD
140}
141
de149cdb 142static void
da2d1bc5
UD
143test (testcase tests[], efcvt_func efcvt, const char *name)
144{
145 int no = 0;
146 int decpt, sign;
147 char *p;
148
149 while (tests[no].value != -1.0)
150 {
151 p = efcvt (tests[no].value, tests[no].ndigit, &decpt, &sign);
152 if (decpt != tests[no].decpt
153 || sign != (tests[no].value < 0)
154 || strcmp (p, tests[no].result) != 0)
155 output_error (name, tests[no].value, tests[no].ndigit,
156 tests[no].result, tests[no].decpt,
157 (tests[no].value < 0),
158 p, decpt, sign);
159 ++no;
160 }
161}
162
de149cdb 163static void
c9e17a9c
UD
164test_r (testcase tests[], efcvt_r_func efcvt_r, const char *name)
165{
166 int no = 0;
167 int decpt, sign, res;
168 char buf [1024];
1fc6f813 169
c9e17a9c
UD
170
171 while (tests[no].value != -1.0)
172 {
173 res = efcvt_r (tests[no].value, tests[no].ndigit, &decpt, &sign,
174 buf, sizeof (buf));
175 if (res != 0
176 || decpt != tests[no].decpt
177 || sign != (tests[no].value < 0)
178 || strcmp (buf, tests[no].result) != 0)
179 output_r_error (name, tests[no].value, tests[no].ndigit,
180 tests[no].result, tests[no].decpt, 0,
181 (tests[no].value < 0),
182 buf, decpt, sign, res);
183 ++no;
184 }
185}
186
de149cdb 187static void
da2d1bc5 188special (void)
07b51ba5 189{
b9d3d9f7 190 int decpt, sign, res;
07b51ba5 191 char *p;
b9d3d9f7 192 char buf [1024];
1fc6f813 193
bd51ff5e 194 p = ECVT (NAN, 10, &decpt, &sign);
da2d1bc5 195 if (sign != 0 || strcmp (p, "nan") != 0)
bd51ff5e 196 output_error (NAME (ECVT), NAN, 10, "nan", 0, 0, p, decpt, sign);
07b51ba5 197
bd51ff5e 198 p = ECVT (INFINITY, 10, &decpt, &sign);
da2d1bc5 199 if (sign != 0 || strcmp (p, "inf") != 0)
bd51ff5e 200 output_error (NAME (ECVT), INFINITY, 10, "inf", 0, 0, p, decpt, sign);
da2d1bc5 201
67994d6f 202 /* Simply make sure these calls with large NDIGITs don't crash. */
bd51ff5e
GG
203 (void) ECVT (123.456, 10000, &decpt, &sign);
204 (void) FCVT (123.456, 10000, &decpt, &sign);
67994d6f 205
ded5b9b7 206 /* Some tests for the reentrant functions. */
b9d3d9f7 207 /* Use a too small buffer. */
bd51ff5e 208 res = ECVT_R (123.456, 10, &decpt, &sign, buf, 1);
b9d3d9f7
UD
209 if (res == 0)
210 {
bd51ff5e 211 printf (NAME (ECVT_R) " with a too small buffer was succesful.\n");
968ed530 212 support_record_failure ();
b9d3d9f7 213 }
bd51ff5e 214 res = FCVT_R (123.456, 10, &decpt, &sign, buf, 1);
b9d3d9f7
UD
215 if (res == 0)
216 {
bd51ff5e 217 printf (NAME (FCVT_R) " with a too small buffer was succesful.\n");
968ed530 218 support_record_failure ();
b9d3d9f7 219 }
da2d1bc5
UD
220}
221
a7f804d8 222
29955b5d
AS
223static int
224do_test (void)
da2d1bc5 225{
bd51ff5e
GG
226 test (ecvt_tests, ECVT, NAME (ECVT));
227 test (fcvt_tests, FCVT, NAME (FCVT));
228 test_r (ecvt_tests, ECVT_R, NAME (ECVT_R));
229 test_r (fcvt_tests, FCVT_R, NAME (FCVT_R));
da2d1bc5 230 special ();
a7f804d8 231
968ed530 232 return 0;
07b51ba5 233}
29955b5d 234
968ed530 235#include <support/test-driver.c>