summaryrefslogtreecommitdiff
path: root/src/regress/lib/libc/printf
diff options
context:
space:
mode:
authorcvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
committercvs2svn <admin@example.com>2025-04-14 17:32:06 +0000
commiteb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch)
treeedb6da6af7e865d488dc1a29309f1e1ec226e603 /src/regress/lib/libc/printf
parent247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff)
downloadopenbsd-tb_20250414.tar.gz
openbsd-tb_20250414.tar.bz2
openbsd-tb_20250414.zip
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/regress/lib/libc/printf')
-rw-r--r--src/regress/lib/libc/printf/Makefile13
-rw-r--r--src/regress/lib/libc/printf/fp.c225
-rw-r--r--src/regress/lib/libc/printf/int.c376
-rw-r--r--src/regress/lib/libc/printf/string.c435
4 files changed, 0 insertions, 1049 deletions
diff --git a/src/regress/lib/libc/printf/Makefile b/src/regress/lib/libc/printf/Makefile
deleted file mode 100644
index 5125fc64da..0000000000
--- a/src/regress/lib/libc/printf/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
1# $OpenBSD: Makefile,v 1.3 2020/07/09 01:49:15 schwarze Exp $
2
3PROGS = fp int string
4
5REGRESS_TARGETS = ${PROGS:S/^/run-regress-/}
6
7.for p in ${PROGS}
8run-regress-${p}: ${p}
9 ./${p}
10.PHONY: run-regress-${p}
11.endfor
12
13.include <bsd.regress.mk>
diff --git a/src/regress/lib/libc/printf/fp.c b/src/regress/lib/libc/printf/fp.c
deleted file mode 100644
index 299d05f55d..0000000000
--- a/src/regress/lib/libc/printf/fp.c
+++ /dev/null
@@ -1,225 +0,0 @@
1/* $OpenBSD: fp.c,v 1.2 2020/05/31 12:27:19 mortimer Exp $ */
2/*-
3 * Copyright (c) 2002, 2005 David Schultz <das@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28/*
29 * Test for printf() floating point formats.
30 */
31
32#include <assert.h>
33#include <err.h>
34#include <float.h>
35#include <math.h>
36#include <stdio.h>
37#include <stdarg.h>
38#include <stdint.h>
39#include <stdlib.h>
40#include <string.h>
41
42#define testfmt(result, fmt, ...) \
43 _testfmt((result), __LINE__, #__VA_ARGS__, fmt, __VA_ARGS__)
44void _testfmt(const char *, int, const char *, const char *, ...);
45void smash_stack(void);
46
47int
48main(int argc, char *argv[])
49{
50 /*
51 * Basic tests of decimal output functionality.
52 */
53 testfmt(" 1.000000E+00", "%13E", 1.0);
54 testfmt(" 1.000000", "%13f", 1.0);
55 testfmt(" 1", "%13G", 1.0);
56 testfmt(" 1.000000E+00", "%13LE", 1.0L);
57 testfmt(" 1.000000", "%13Lf", 1.0L);
58 testfmt(" 1", "%13LG", 1.0L);
59
60 testfmt("2.718282", "%.*f", -2, 2.7182818);
61
62 testfmt("1.234568e+06", "%e", 1234567.8);
63 testfmt("1234567.800000", "%f", 1234567.8);
64 testfmt("1.23457E+06", "%G", 1234567.8);
65 testfmt("1.234568e+06", "%Le", 1234567.8L);
66 testfmt("1234567.800000", "%Lf", 1234567.8L);
67 testfmt("1.23457E+06", "%LG", 1234567.8L);
68
69#if (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__)
70 testfmt("123456789.864210", "%Lf", 123456789.8642097531L);
71 testfmt("-1.23457E+08", "%LG", -123456789.8642097531L);
72 testfmt("123456789.8642097531", "%.10Lf", 123456789.8642097531L);
73 testfmt(" 3.141592653589793238e-4000", "%L27.18Le",
74 3.14159265358979323846e-4000L);
75#endif /* (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) */
76
77 /*
78 * Infinities and NaNs
79 */
80#ifdef NAN
81 testfmt("nan", "%e", NAN);
82 testfmt("NAN", "%F", NAN);
83 testfmt("nan", "%g", NAN);
84 testfmt("NAN", "%LE", (long double)NAN);
85 testfmt(" nan", "%05e", NAN);
86#endif /* NAN */
87
88 testfmt("INF", "%E", HUGE_VAL);
89 testfmt("-inf", "%f", -HUGE_VAL);
90 testfmt("+inf", "%+g", HUGE_VAL);
91 testfmt(" inf", "%4.2Le", HUGE_VALL);
92 testfmt("-inf", "%Lf", -HUGE_VALL);
93 testfmt(" inf", "%05e", HUGE_VAL);
94 testfmt(" -inf", "%05e", -HUGE_VAL);
95
96 /*
97 * Padding
98 */
99 testfmt("0.000000e+00", "%e", 0.0);
100 testfmt("0.000000", "%F", (double)0.0);
101 testfmt("0", "%G", 0.0);
102 testfmt(" 0", "%3.0Lg", 0.0L);
103 testfmt(" 0", "%5.0f", 0.001);
104
105 /*
106 * Precision specifiers
107 */
108 testfmt("1.0123e+00", "%.4e", 1.0123456789);
109 testfmt("1.0123", "%.4f", 1.0123456789);
110 testfmt("1.012", "%.4g", 1.0123456789);
111 testfmt("1.2346e-02", "%.4e", 0.0123456789);
112 testfmt("0.0123", "%.4f", 0.0123456789);
113 testfmt("0.01235", "%.4g", 0.0123456789);
114
115 /*
116 * Signed conversions
117 */
118 testfmt("+2.500000e-01", "%+e", 0.25);
119 testfmt("+0.000000", "%+F", 0.0);
120 testfmt("-1", "%+g", -1.0);
121
122 testfmt("-1.000000e+00", "% e", -1.0);
123 testfmt("+1.000000", "% +f", 1.0);
124 testfmt(" 1", "% g", 1.0);
125 testfmt(" 0", "% g", 0.0);
126
127 /*
128 * ``Alternate form''
129 */
130 testfmt("1.250e+00", "%#.3e", 1.25);
131 testfmt("123.000000", "%#f", 123.0);
132 testfmt(" 12345.", "%#7.5g", 12345.0);
133 testfmt(" 1.00000", "%#8g", 1.0);
134 testfmt("0.0", "%#.2g", 0.0);
135
136 /*
137 * Padding and decimal point placement
138 */
139 testfmt("03.2E+00", "%08.1E", 3.25);
140 testfmt("003.25", "%06.2F", 3.25);
141 testfmt("0003.25", "%07.4G", 3.25);
142
143 testfmt("3.14159e-05", "%g", 3.14159e-5);
144 testfmt("0.000314159", "%g", 3.14159e-4);
145 testfmt("3.14159e+06", "%g", 3.14159e6);
146 testfmt("314159", "%g", 3.14159e5);
147 testfmt("314159.", "%#g", 3.14159e5);
148
149 testfmt(" 9.000000e+03", "%13e", 9000.0);
150 testfmt(" 9000.000000", "%12f", 9000.0);
151 testfmt(" 9000", "%5g", 9000.0);
152 testfmt(" 900000.", "%#8g", 900000.0);
153 testfmt(" 9e+06", "%6g", 9000000.0);
154 testfmt(" 9.000000e-04", "%13e", 0.0009);
155 testfmt(" 0.000900", "%9f", 0.0009);
156 testfmt(" 0.0009", "%7g", 0.0009);
157 testfmt(" 9e-05", "%6g", 0.00009);
158 testfmt(" 9.00000e-05", "%#12g", 0.00009);
159 testfmt(" 9.e-05", "%#7.1g", 0.00009);
160
161 testfmt(" 0.0", "%4.1f", 0.0);
162 testfmt("90.0", "%4.1f", 90.0);
163 testfmt(" 100", "%4.0f", 100.0);
164 testfmt("9.0e+01", "%4.1e", 90.0);
165 testfmt("1e+02", "%4.0e", 100.0);
166
167 /*
168 * Hexadecimal floating point (%a, %A) tests. Some of these
169 * are only valid if the implementation converts to hex digits
170 * on nibble boundaries.
171 */
172 testfmt("0x0p+0", "%a", 0x0.0p0);
173 testfmt("0X0.P+0", "%#LA", 0x0.0p0L);
174#ifdef NAN
175 testfmt("inf", "%La", (long double)INFINITY);
176 testfmt("+INF", "%+A", INFINITY);
177 testfmt("nan", "%La", (long double)NAN);
178 testfmt("NAN", "%A", NAN);
179#endif /* NAN */
180
181 testfmt(" 0x1.23p+0", "%10a", 0x1.23p0);
182 testfmt(" 0x1.23p-500", "%12a", 0x1.23p-500);
183 testfmt(" 0x1.2p+40", "%10.1a", 0x1.23p40);
184 testfmt(" 0X1.230000000000000000000000P-4", "%32.24A", 0x1.23p-4);
185 testfmt("0x1p-1074", "%a", 0x1p-1074);
186 testfmt("0x1.2345p-1024", "%a", 0x1.2345p-1024);
187
188#if LDBL_MANT_DIG == 113
189 testfmt("-0x1.e7d7c7b7a7978777675747372717p-14344", "%La",
190 -0x1.e7d7c7b7a7978777675747372717p-14344L);
191#elif LDBL_MANT_DIG == 64
192 testfmt("-0x8.777675747372717p-16248", "%La",
193 -0x8.777675747372717p-16248L);
194#endif
195
196 return (0);
197}
198
199void
200smash_stack(void)
201{
202 static uint32_t junk = 0xdeadbeef;
203 uint32_t buf[512];
204 int i;
205
206 for (i = 0; i < sizeof(buf) / sizeof(buf[0]); i++)
207 buf[i] = junk;
208}
209
210void
211_testfmt(const char *result, int line, const char *argstr, const char *fmt,...)
212{
213 char s[100];
214 va_list ap;
215
216 va_start(ap, fmt);
217 smash_stack();
218 vsnprintf(s, sizeof(s), fmt, ap);
219 if (strcmp(result, s) != 0) {
220 fprintf(stderr,
221 "%d: printf(\"%s\", %s) ==> [%s], expected [%s]\n",
222 line, fmt, argstr, s, result);
223 abort();
224 }
225}
diff --git a/src/regress/lib/libc/printf/int.c b/src/regress/lib/libc/printf/int.c
deleted file mode 100644
index 5a56c8d50e..0000000000
--- a/src/regress/lib/libc/printf/int.c
+++ /dev/null
@@ -1,376 +0,0 @@
1/* $OpenBSD: int.c,v 1.2 2020/07/14 16:40:04 kettenis Exp $ */
2/*
3 * Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * Test the %c, %lc, %s, and %ls conversion specifiers with all their
18 * modifiers, in particular with the minus flag, width, and maxbytes.
19 * Also verify that other flags do nothing useful.
20 */
21#include <err.h>
22#include <stddef.h>
23#include <stdint.h>
24#include <stdio.h>
25#include <string.h>
26#include <unistd.h>
27
28enum int_size {
29 S_CHAR,
30 S_SHORT,
31 S_INT,
32 S_LONG,
33 S_LL,
34 S_MAX,
35 S_PTR,
36 S_SIZE
37};
38
39void ti(const char *, enum int_size, long long, const char *);
40void tu(const char *, enum int_size, unsigned long long, const char *);
41
42static int badret, badlen, badout; /* Error counters. */
43static int verbose; /* For debugging. */
44
45
46/*
47 * Print the signed integer i with the format fmt,
48 * check that the result matches what we want,
49 * and report and count the error on failure.
50 */
51void
52ti(const char *fmt, enum int_size sz, long long i, const char *want)
53{
54 char buf[32];
55 size_t len;
56 int irc, happy;
57
58 happy = 1;
59 switch (sz) {
60 case S_CHAR:
61 irc = snprintf(buf, sizeof(buf), fmt, (signed char)i);
62 break;
63 case S_SHORT:
64 irc = snprintf(buf, sizeof(buf), fmt, (short)i);
65 break;
66 case S_INT:
67 irc = snprintf(buf, sizeof(buf), fmt, (int)i);
68 break;
69 case S_LONG:
70 irc = snprintf(buf, sizeof(buf), fmt, (long)i);
71 break;
72 case S_LL:
73 irc = snprintf(buf, sizeof(buf), fmt, (long long)i);
74 break;
75 case S_MAX:
76 irc = snprintf(buf, sizeof(buf), fmt, (intmax_t)i);
77 break;
78 case S_PTR:
79 irc = snprintf(buf, sizeof(buf), fmt, (ptrdiff_t)i);
80 break;
81 case S_SIZE:
82 irc = snprintf(buf, sizeof(buf), fmt, (ssize_t)i);
83 break;
84 default:
85 warnx("printf(\"%s\", %lld) unknown size code %d",
86 fmt, i, sz);
87 badret++;
88 return;
89 }
90 len = strlen(want);
91 if (irc < 0) {
92 warn("printf(\"%s\", %lld) returned %d", fmt, i, irc);
93 badret++;
94 return;
95 }
96 if ((unsigned long long)irc != len) {
97 warnx("printf(\"%s\", %lld) returned %d (expected %zu)",
98 fmt, i, irc, len);
99 badlen++;
100 happy = 0;
101 }
102 if (strcmp(buf, want) != 0) {
103 warnx("printf(\"%s\", %lld) wrote \"%s\" (expected \"%s\")",
104 fmt, i, buf, want);
105 badout++;
106 happy = 0;
107 }
108 if (verbose && happy)
109 warnx("printf(\"%s\", %lld) wrote \"%s\" length %d (OK)",
110 fmt, i, buf, irc);
111}
112
113/*
114 * Print the unsigned integer i with the format fmt,
115 * check that the result matches what we want,
116 * and report and count the error on failure.
117 */
118void
119tu(const char *fmt, enum int_size sz, unsigned long long i, const char *want)
120{
121 char buf[32];
122 size_t len;
123 int irc, happy;
124
125 happy = 1;
126 switch (sz) {
127 case S_CHAR:
128 irc = snprintf(buf, sizeof(buf), fmt, (unsigned char)i);
129 break;
130 case S_SHORT:
131 irc = snprintf(buf, sizeof(buf), fmt, (unsigned short)i);
132 break;
133 case S_INT:
134 irc = snprintf(buf, sizeof(buf), fmt, (unsigned int)i);
135 break;
136 case S_LONG:
137 irc = snprintf(buf, sizeof(buf), fmt, (unsigned long)i);
138 break;
139 case S_LL:
140 irc = snprintf(buf, sizeof(buf), fmt, (unsigned long long)i);
141 break;
142 case S_MAX:
143 irc = snprintf(buf, sizeof(buf), fmt, (uintmax_t)i);
144 break;
145 case S_SIZE:
146 irc = snprintf(buf, sizeof(buf), fmt, (size_t)i);
147 break;
148 default:
149 warnx("printf(\"%s\", %llu) unknown size code %d",
150 fmt, i, sz);
151 badret++;
152 return;
153 }
154 len = strlen(want);
155 if (irc < 0) {
156 warn("printf(\"%s\", %llu) returned %d", fmt, i, irc);
157 badret++;
158 return;
159 }
160 if ((unsigned long long)irc != len) {
161 warnx("printf(\"%s\", %llu) returned %d (expected %zu)",
162 fmt, i, irc, len);
163 badlen++;
164 happy = 0;
165 }
166 if (strcmp(buf, want) != 0) {
167 warnx("printf(\"%s\", %llu) wrote \"%s\" (expected \"%s\")",
168 fmt, i, buf, want);
169 badout++;
170 happy = 0;
171 }
172 if (verbose && happy)
173 warnx("printf(\"%s\", %llu) wrote \"%s\" length %d (OK)",
174 fmt, i, buf, irc);
175}
176
177int
178main(int argc, char *argv[])
179{
180 int badarg, picky;
181 int ch;
182
183 badarg = picky = 0;
184 while ((ch = getopt(argc, argv, "pv")) != -1) {
185 switch (ch) {
186 case 'p':
187 picky = 1;
188 break;
189 case 'v':
190 verbose = 1;
191 break;
192 default:
193 badarg = 1;
194 break;
195 }
196 }
197 argc -= optind;
198 argv += optind;
199 if (argc > 0) {
200 warnx("unexpected argument \"%s\"", *argv);
201 badarg = 1;
202 }
203 if (badarg) {
204 fputs("usage: int [-pv]\n", stderr);
205 return 1;
206 }
207
208 /*
209 * Valid use cases of %d.
210 */
211
212 ti("<%d>", S_INT, 0, "<0>");
213 ti("<%d>", S_INT, 1, "<1>");
214 ti("<%d>", S_INT, -1, "<-1>");
215 ti("<%d>", S_INT, 42, "<42>");
216 ti("<%d>", S_INT, INT32_MAX, "<2147483647>");
217 ti("<%d>", S_INT, INT32_MIN, "<-2147483648>");
218 ti("<% d>", S_INT, 42, "< 42>");
219 ti("<% d>", S_INT, -42, "<-42>");
220 ti("<%+d>", S_INT, 42, "<+42>");
221 ti("<%+d>", S_INT, -42, "<-42>");
222 ti("<% +d>", S_INT, 42, "<+42>");
223 ti("<% +d>", S_INT, -42, "<-42>");
224 ti("<%-4d>", S_INT, 42, "<42 >");
225 ti("<% -4d>", S_INT, 42, "< 42 >");
226 ti("<%+-4d>", S_INT, 42, "<+42 >");
227 ti("<%04d>", S_INT, 42, "<0042>");
228 ti("<%-04d>", S_INT, 42, "<42 >");
229 ti("<% 04d>", S_INT, 42, "< 042>");
230 ti("<%+04d>", S_INT, 42, "<+042>");
231 ti("<%4.3d>", S_INT, 42, "< 042>");
232 ti("<% 5.3d>", S_INT, 42, "< 042>");
233 ti("<%+5.3d>", S_INT, 42, "< +042>");
234 ti("<%-4.3d>", S_INT, 42, "<042 >");
235 ti("<%04.3d>", S_INT, 42, "< 042>");
236
237 ti("<%hhd>", S_CHAR, INT8_MIN, "<-128>");
238 ti("<%hhd>", S_CHAR, -1, "<-1>");
239 ti("<%hhd>", S_CHAR, 0, "<0>");
240 ti("<%hhd>", S_CHAR, 1, "<1>");
241 ti("<%hhd>", S_CHAR, INT8_MAX, "<127>");
242 ti("<%+.4hhd>", S_CHAR, 42, "<+0042>");
243 ti("<% 04hhd>", S_CHAR, 42, "< 042>");
244
245 ti("<%hd>", S_SHORT, INT16_MIN, "<-32768>");
246 ti("<%hd>", S_SHORT, -1, "<-1>");
247 ti("<%hd>", S_SHORT, 0, "<0>");
248 ti("<%hd>", S_SHORT, 1, "<1>");
249 ti("<%hd>", S_SHORT, INT16_MAX, "<32767>");
250
251 ti("<%hld>", S_LONG, INT32_MIN, "<-2147483648>");
252 ti("<%hld>", S_LONG, -1, "<-1>");
253 ti("<%hld>", S_LONG, 0, "<0>");
254 ti("<%hld>", S_LONG, 1, "<1>");
255 ti("<%hld>", S_LONG, INT32_MAX, "<2147483647>");
256
257 ti("<%hlld>", S_LL, INT64_MIN, "<-9223372036854775808>");
258 ti("<%hlld>", S_LL, -1, "<-1>");
259 ti("<%hlld>", S_LL, 0, "<0>");
260 ti("<%hlld>", S_LL, 1, "<1>");
261 ti("<%hlld>", S_LL, INT64_MAX, "<9223372036854775807>");
262 ti("<%h-19lld>", S_LL, 123456789123456789LL, "<123456789123456789 >");
263
264 ti("<%hjd>", S_MAX, INT64_MIN, "<-9223372036854775808>");
265 ti("<%hjd>", S_MAX, -1, "<-1>");
266 ti("<%hjd>", S_MAX, 0, "<0>");
267 ti("<%hjd>", S_MAX, 1, "<1>");
268 ti("<%hjd>", S_MAX, INT64_MAX, "<9223372036854775807>");
269
270 ti("<%htd>", S_PTR, INT32_MIN, "<-2147483648>");
271 ti("<%htd>", S_PTR, -1, "<-1>");
272 ti("<%htd>", S_PTR, 0, "<0>");
273 ti("<%htd>", S_PTR, 1, "<1>");
274 ti("<%htd>", S_PTR, INT32_MAX, "<2147483647>");
275
276 ti("<%hzd>", S_SIZE, INT32_MIN, "<-2147483648>");
277 ti("<%hzd>", S_SIZE, -1, "<-1>");
278 ti("<%hzd>", S_SIZE, 0, "<0>");
279 ti("<%hzd>", S_SIZE, 1, "<1>");
280 ti("<%hzd>", S_SIZE, INT32_MAX, "<2147483647>");
281
282 /*
283 * Undefined behaviour of %d.
284 * Do not test by default to avoid noise.
285 * But provide the tests anyway to help track down
286 * unintended changes of behaviour when needed.
287 */
288
289 if (picky) {
290 ti("<%#d>", S_INT, 42, "<42>");
291 ti("<%Ld>", S_INT, 42, "<42>");
292 }
293
294 /*
295 * Valid use cases of %u.
296 */
297
298 tu("<%u>", S_INT, 0, "<0>");
299 tu("<%u>", S_INT, 1, "<1>");
300 tu("<%u>", S_INT, 42, "<42>");
301 tu("<%u>", S_INT, UINT32_MAX, "<4294967295>");
302 tu("<%-4u>", S_INT, 42, "<42 >");
303 tu("<%04u>", S_INT, 42, "<0042>");
304 tu("<%-04u>", S_INT, 42, "<42 >");
305 tu("<%4.3u>", S_INT, 42, "< 042>");
306 tu("<%-4.3u>", S_INT, 42, "<042 >");
307 tu("<%04.3u>", S_INT, 42, "< 042>");
308
309 tu("<%hhu>", S_CHAR, 0, "<0>");
310 tu("<%hhu>", S_CHAR, UINT8_MAX, "<255>");
311 tu("<%hhu>", S_CHAR, -1, "<255>");
312 tu("<%-4hhu>", S_CHAR, 42, "<42 >");
313 tu("<%04hhu>", S_CHAR, 42, "<0042>");
314
315 tu("<%hu>", S_SHORT, 0, "<0>");
316 tu("<%hu>", S_SHORT, UINT16_MAX, "<65535>");
317 tu("<%hlu>", S_LONG, 0, "<0>");
318 tu("<%hlu>", S_LONG, UINT32_MAX, "<4294967295>");
319 tu("<%hllu>", S_LL, 0, "<0>");
320 tu("<%hllu>", S_LL, UINT64_MAX, "<18446744073709551615>");
321 tu("<%h-19llu>", S_LL, 123456789123456789ULL, "<123456789123456789 >");
322 tu("<%hju>", S_MAX, 0, "<0>");
323 tu("<%hju>", S_MAX, UINT64_MAX, "<18446744073709551615>");
324 tu("<%hzu>", S_SIZE, 0, "<0>");
325 tu("<%hzu>", S_SIZE, UINT32_MAX, "<4294967295>");
326
327 tu("<%hho>", S_CHAR, 0, "<0>");
328 tu("<%#hho>", S_CHAR, 0, "<0>");
329 tu("<%hho>", S_CHAR, UINT8_MAX, "<377>");
330 tu("<%#hho>", S_CHAR, UINT8_MAX, "<0377>");
331 tu("<%hho>", S_CHAR, -1, "<377>");
332 tu("<%#hho>", S_CHAR, -1, "<0377>");
333 tu("<%-4hho>", S_CHAR, 42, "<52 >");
334 tu("<%#-4hho>", S_CHAR, 42, "<052 >");
335 tu("<%04hho>", S_CHAR, 42, "<0052>");
336 tu("<%#04hho>", S_CHAR, 42, "<0052>");
337
338 tu("<%hx>", S_SHORT, 0, "<0>");
339 tu("<%#hx>", S_SHORT, 0, "<0>");
340 tu("<%hX>", S_SHORT, 0, "<0>");
341 tu("<%#hX>", S_SHORT, 0, "<0>");
342 tu("<%hx>", S_SHORT, 1, "<1>");
343 tu("<%#hx>", S_SHORT, 1, "<0x1>");
344 tu("<%hX>", S_SHORT, 1, "<1>");
345 tu("<%#hX>", S_SHORT, 1, "<0X1>");
346 tu("<%hx>", S_SHORT, 10, "<a>");
347 tu("<%#hx>", S_SHORT, 10, "<0xa>");
348 tu("<%hX>", S_SHORT, 10, "<A>");
349 tu("<%#hX>", S_SHORT, 10, "<0XA>");
350 tu("<%hx>", S_SHORT, UINT16_MAX, "<ffff>");
351 tu("<%#hx>", S_SHORT, UINT16_MAX, "<0xffff>");
352 tu("<%hX>", S_SHORT, UINT16_MAX, "<FFFF>");
353 tu("<%#hX>", S_SHORT, UINT16_MAX, "<0XFFFF>");
354
355 /*
356 * Undefined behaviour of %u.
357 */
358
359 if (picky) {
360 tu("<%#u>", S_INT, 42, "<42>");
361 tu("<% u>", S_INT, 42, "<42>");
362 tu("<%+u>", S_INT, 42, "<42>");
363 tu("<%Lu>", S_INT, 42, "<42>");
364 }
365
366 /*
367 * Summarize the results.
368 */
369
370 if (badret + badlen + badout)
371 errx(1, "ERRORS: %d fail + %d mismatch (incl. %d bad length)",
372 badret, badout, badlen);
373 else if (verbose)
374 warnx("SUCCESS");
375 return 0;
376}
diff --git a/src/regress/lib/libc/printf/string.c b/src/regress/lib/libc/printf/string.c
deleted file mode 100644
index 6e65a371a4..0000000000
--- a/src/regress/lib/libc/printf/string.c
+++ /dev/null
@@ -1,435 +0,0 @@
1/* $OpenBSD: string.c,v 1.2 2020/07/14 16:40:04 kettenis Exp $ */
2/*
3 * Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * Test the %c, %lc, %s, and %ls conversion specifiers with all their
18 * modifiers, in particular with the minus flag, width, and maxbytes.
19 * Also verify that other flags do nothing useful.
20 */
21#include <err.h>
22#include <errno.h>
23#include <locale.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
28#include <wchar.h>
29
30void tc(const char *, int, const char *);
31void tlc(const char *, wint_t, const char *);
32void tlc_expect_fail(const char *, wint_t);
33void ts(const char *, const char *, const char *);
34void tls(const char *, const wchar_t *, const char *);
35void tls_expect_fail(const char *, const wchar_t *);
36
37static int badret, badlen, badout; /* Error counters. */
38static int verbose; /* For debugging. */
39
40
41/*
42 * Print the single-byte character c with the format fmt,
43 * check that the result matches what we want,
44 * and report and count the error on failure.
45 */
46void
47tc(const char *fmt, int c, const char *want)
48{
49 char buf[32];
50 size_t len;
51 int irc, happy;
52
53 happy = 1;
54 irc = snprintf(buf, sizeof(buf), fmt, c);
55 len = strlen(want);
56 if (irc < 0) {
57 warn("printf(\"%s\", %d) returned %d", fmt, c, irc);
58 badret++;
59 return;
60 }
61 if ((unsigned long long)irc != len) {
62 warnx("printf(\"%s\", %d) returned %d (expected %zu)",
63 fmt, c, irc, len);
64 badlen++;
65 happy = 0;
66 }
67 if (strcmp(buf, want) != 0) {
68 warnx("printf(\"%s\", %d) wrote \"%s\" (expected \"%s\")",
69 fmt, c, buf, want);
70 badout++;
71 happy = 0;
72 }
73 if (verbose && happy)
74 warnx("printf(\"%s\", %d) wrote \"%s\" length %d (OK)",
75 fmt, c, buf, irc);
76}
77
78/*
79 * Print the wide character wc with the format fmt,
80 * check that the result matches what we want,
81 * and report and count the error on failure.
82 */
83void
84tlc(const char *fmt, wint_t wc, const char *want)
85{
86 char buf[32];
87 const char *charset;
88 size_t len;
89 int irc, happy;
90
91 happy = 1;
92 charset = MB_CUR_MAX > 1 ? "UTF-8" : "ASCII";
93 irc = snprintf(buf, sizeof(buf), fmt, wc);
94 len = strlen(want);
95 if (irc < 0) {
96 warn("%s printf(\"%s\", U+%.4X) returned %d",
97 charset, fmt, (unsigned int)wc, irc);
98 badret++;
99 return;
100 }
101 if ((unsigned long long)irc != len) {
102 warnx("%s printf(\"%s\", U+%.4X) returned %d (expected %zu)",
103 charset, fmt, (unsigned int)wc, irc, len);
104 badlen++;
105 happy = 0;
106 }
107 if (strcmp(buf, want) != 0) {
108 warnx("%s printf(\"%s\", U+%.4X) "
109 "wrote \"%s\" (expected \"%s\")",
110 charset, fmt, (unsigned int)wc, buf, want);
111 badout++;
112 happy = 0;
113 }
114 if (verbose && happy)
115 warnx("%s printf(\"%s\", U+%.4X) wrote \"%s\" length %d (OK)",
116 charset, fmt, (unsigned int)wc, buf, irc);
117}
118
119/*
120 * Try to print the invalid wide character wc with the format fmt,
121 * check that it fails as it should, and report and count if it doesn't.
122 */
123void
124tlc_expect_fail(const char *fmt, wint_t wc)
125{
126 char buf[32];
127 const char *charset;
128 int irc;
129
130 errno = 0;
131 charset = MB_CUR_MAX > 1 ? "UTF-8" : "ASCII";
132 irc = snprintf(buf, sizeof(buf), fmt, wc);
133 if (irc != -1) {
134 warn("%s printf(\"%s\", U+%.4X) returned %d",
135 charset, fmt, (unsigned int)wc, irc);
136 badret++;
137 } else if (errno != EILSEQ) {
138 warnx("%s printf(\"%s\", U+%.4X) errno %d (expected %d)",
139 charset, fmt, (unsigned int)wc, errno, EILSEQ);
140 badret++;
141 } else if (verbose)
142 warnx("%s printf(\"%s\", U+%.4X) returned %d errno %d (OK)",
143 charset, fmt, (unsigned int)wc, irc, errno);
144}
145
146/*
147 * Print the string s with the format fmt,
148 * check that the result matches what we want,
149 * and report and count the error on failure.
150 */
151void
152ts(const char *fmt, const char *s, const char *want)
153{
154 char buf[32];
155 size_t len;
156 int irc, happy;
157
158 happy = 1;
159 irc = snprintf(buf, sizeof(buf), fmt, s);
160 len = strlen(want);
161 if (irc < 0) {
162 warn("printf(\"%s\", \"%s\") returned %d", fmt, s, irc);
163 badret++;
164 return;
165 }
166 if ((unsigned long long)irc != len) {
167 warnx("printf(\"%s\", \"%s\") returned %d (expected %zu)",
168 fmt, s, irc, len);
169 badlen++;
170 happy = 0;
171 }
172 if (strcmp(buf, want) != 0) {
173 warnx("printf(\"%s\", \"%s\") wrote \"%s\" (expected \"%s\")",
174 fmt, s, buf, want);
175 badout++;
176 happy = 0;
177 }
178 if (verbose && happy)
179 warnx("printf(\"%s\", \"%s\") wrote \"%s\" length %d (OK)",
180 fmt, s, buf, irc);
181}
182
183/*
184 * Print the wide character string ws with the format fmt,
185 * check that the result matches what we want,
186 * and report and count the error on failure.
187 */
188void
189tls(const char *fmt, const wchar_t *ws, const char *want)
190{
191 char buf[32];
192 const char *charset;
193 size_t len;
194 int irc, happy;
195
196 happy = 1;
197 charset = MB_CUR_MAX > 1 ? "UTF-8" : "ASCII";
198 irc = snprintf(buf, sizeof(buf), fmt, ws);
199 len = strlen(want);
200 if (irc < 0) {
201 warn("%s printf(\"%s\", \"%ls\") returned %d",
202 charset, fmt, ws, irc);
203 badret++;
204 return;
205 }
206 if ((unsigned long long)irc != len) {
207 warnx("%s printf(\"%s\", \"%ls\") returned %d (expected %zu)",
208 charset, fmt, ws, irc, len);
209 badlen++;
210 happy = 0;
211 }
212 if (strcmp(buf, want) != 0) {
213 warnx("%s printf(\"%s\", \"%ls\") "
214 "wrote \"%s\" (expected \"%s\")",
215 charset, fmt, ws, buf, want);
216 badout++;
217 happy = 0;
218 }
219 if (verbose && happy)
220 warnx("%s printf(\"%s\", \"%ls\") wrote \"%s\" length %d (OK)",
221 charset, fmt, ws, buf, irc);
222}
223
224/*
225 * Try to print the invalid wide character string ws with the format fmt,
226 * check that it fails as it should, and report and count if it doesn't.
227 */
228void
229tls_expect_fail(const char *fmt, const wchar_t *ws)
230{
231 char buf[32];
232 const char *charset;
233 int irc;
234
235 errno = 0;
236 charset = MB_CUR_MAX > 1 ? "UTF-8" : "ASCII";
237 irc = snprintf(buf, sizeof(buf), fmt, ws);
238 if (irc != -1) {
239 warn("%s printf(\"%s\", U+%.4X, ...) returned %d",
240 charset, fmt, (unsigned int)*ws, irc);
241 badret++;
242 } else if (errno != EILSEQ) {
243 warnx("%s printf(\"%s\", U+%.4X, ...) errno %d (expected %d)",
244 charset, fmt, (unsigned int)*ws, errno, EILSEQ);
245 badret++;
246 } else if (verbose)
247 warnx("%s printf(\"%s\", U+%.4X, ...) "
248 "returned %d errno %d (OK)",
249 charset, fmt, (unsigned int)*ws, irc, errno);
250}
251
252int
253main(int argc, char *argv[])
254{
255 const wchar_t ws[] = { 0x0421, 0x043e, 0x0444, 0x044f, 0 };
256 const wchar_t wsbad[] = { 0x0391, 0xdeef, 0x3c9, 0 };
257 int badarg, picky;
258 int ch;
259
260 badarg = picky = 0;
261 while ((ch = getopt(argc, argv, "pv")) != -1) {
262 switch (ch) {
263 case 'p':
264 picky = 1;
265 break;
266 case 'v':
267 verbose = 1;
268 break;
269 default:
270 badarg = 1;
271 break;
272 }
273 }
274 argc -= optind;
275 argv += optind;
276 if (argc > 0) {
277 warnx("unexpected argument \"%s\"", *argv);
278 badarg = 1;
279 }
280 if (badarg) {
281 fputs("usage: string [-pv]\n", stderr);
282 return 1;
283 }
284
285 /*
286 * Valid use cases of %c and %s.
287 */
288
289 tc("<%c>", '=', "<=>");
290 tc("<%c>", '\t', "<\t>");
291 tc("<%c>", 0xfe, "<\xfe>");
292 tc("<%-c>", '=', "<=>");
293 tc("<%2c>", '=', "< =>");
294 tc("<%-2c>", '=', "<= >");
295
296 ts("<%s>", "text", "<text>");
297 ts("<%-s>", "text", "<text>");
298 ts("<%6s>", "text", "< text>");
299 ts("<%-6s>", "text", "<text >");
300 ts("<%.2s>", "text", "<te>");
301 ts("<%4.2s>", "text", "< te>");
302 ts("<%-4.2s>", "text", "<te >");
303
304 /*
305 * Undefined behaviour of %c and %s.
306 * Do not test by default to avoid noise.
307 * But provide the tests anyway to help track down
308 * unintended changes of behaviour when needed.
309 */
310
311 if (picky) {
312 tc("<%#c>", '=', "<=>");
313 tc("<% -3c>", '=', "<= >");
314 tc("<%+-3c>", '=', "<= >");
315 tc("<%03c>", '=', "<00=>");
316 tc("<%-03c>", '=', "<= >");
317 tc("<%3.2c>", '=', "< =>");
318 tc("<%hc>", '=', "<=>");
319
320 ts("<%#s>", "text", "<text>");
321 ts("<% -6s>", "text", "<text >");
322 ts("<%+-6s>", "text", "<text >");
323 ts("<%06s>", "text", "<00text>");
324 ts("<%-06s>", "text", "<text >");
325 ts("<%hs>", "text", "<text>");
326 }
327
328 /*
329 * Valid use cases of %lc and %ls in the POSIX locale.
330 */
331
332 tlc("<%lc>", L'=', "<=>");
333 tlc("<%lc>", L'\t', "<\t>");
334 tlc_expect_fail("<%lc>", 0x03c0);
335 tlc("<%-lc>", L'=', "<=>");
336 tlc("<%2lc>", L'=', "< =>");
337 tlc("<%-2lc>", L'=', "<= >");
338
339 tls("<%ls>", L"text", "<text>");
340 tls_expect_fail("<%ls>", ws);
341 tls_expect_fail("<%ls>", wsbad);
342 tls("<%-ls>", L"text", "<text>");
343 tls("<%6ls>", L"text", "< text>");
344 tls("<%-6ls>", L"text", "<text >");
345 tls("<%.2ls>", L"text", "<te>");
346 tls("<%4.2ls>", L"text", "< te>");
347 tls("<%-4.2ls>", L"text", "<te >");
348
349 /*
350 * Undefined behaviour of %lc and %ls in the POSIX locale.
351 */
352
353 if (picky) {
354 tlc("<%lc>", 0x00fe, "<\xfe>");
355 tlc("<%#lc>", L'=', "<=>");
356 tlc("<% -3lc>", L'=', "<= >");
357 tlc("<%+-3lc>", L'=', "<= >");
358 tlc("<%03lc>", L'=', "<00=>");
359 tlc("<%-03lc>", L'=', "<= >");
360 tlc("<%3.2lc>", L'=', "< =>");
361 tc("<%llc>", '=', "<=>");
362
363 tls("<%#ls>", L"text", "<text>");
364 tls("<% -6ls>", L"text", "<text >");
365 tls("<%+-6ls>", L"text", "<text >");
366 tls("<%06ls>", L"text", "<00text>");
367 tls("<%-06ls>", L"text", "<text >");
368 ts("<%lls>", "text", "<text>");
369 }
370
371 /*
372 * Valid use cases of %lc and %ls in a UTF-8 locale.
373 */
374
375 if (setlocale(LC_CTYPE, "C.UTF-8") == NULL)
376 err(1, "setlocale");
377
378 tlc("<%lc>", L'=', "<=>");
379 tlc("<%lc>", L'\t', "<\t>");
380 tlc("<%lc>", 0x00fe, "<\xc3\xbe>");
381 tlc("<%lc>", 0x03c0, "<\xcf\x80>");
382 tlc_expect_fail("<%lc>", 0x123456);
383 tlc("<%-lc>", L'=', "<=>");
384 tlc("<%-lc>", 0x03c0, "<\xcf\x80>");
385 tlc("<%2lc>", L'=', "< =>");
386 tlc("<%3lc>", 0x03c0, "< \xcf\x80>");
387 tlc("<%-2lc>", L'=', "<= >");
388 tlc("<%-3lc>", 0x03c0, "<\xcf\x80 >");
389
390 tls("<%ls>", ws, "<\xd0\xa1\xd0\xbe\xd1\x84\xd1\x8f>");
391 tls_expect_fail("<%ls>", wsbad);
392 tls("<%-ls>", ws, "<\xd0\xa1\xd0\xbe\xd1\x84\xd1\x8f>");
393 tls("<%9ls>", ws, "< \xd0\xa1\xd0\xbe\xd1\x84\xd1\x8f>");
394 tls("<%-9ls>", ws, "<\xd0\xa1\xd0\xbe\xd1\x84\xd1\x8f >");
395 tls("<%.4ls>", ws, "<\xd0\xa1\xd0\xbe>");
396 tls("<%.3ls>", ws, "<\xd0\xa1>");
397 tls("<%6.4ls>", ws, "< \xd0\xa1\xd0\xbe>");
398 tls("<%3.3ls>", ws, "< \xd0\xa1>");
399 tls("<%-6.4ls>", ws, "<\xd0\xa1\xd0\xbe >");
400 tls("<%-3.3ls>", ws, "<\xd0\xa1 >");
401
402 /*
403 * Undefined behaviour of %lc and %ls in a UTF-8 locale.
404 */
405
406 if (picky) {
407 tlc("<%#lc>", 0x03c0, "<\xcf\x80>");
408 tlc("<% -4lc>", 0x03c0, "<\xcf\x80 >");
409 tlc("<%+-4lc>", 0x03c0, "<\xcf\x80 >");
410 tlc("<%04lc>", 0x03c0, "<00\xcf\x80>");
411 tlc("<%-04lc>", 0x03c0, "<\xcf\x80 >");
412 tlc("<%4.5lc>", 0x03c0, "< \xcf\x80>");
413 tlc("<%4.3lc>", 0x03c0, "< \xcf\x80>");
414 tlc("<%4.1lc>", 0x03c0, "< \xcf\x80>");
415 tc("<%llc>", 0xfe, "<\xfe>");
416
417 tls("<%#ls>", ws + 2, "<\xd1\x84\xd1\x8f>");
418 tls("<% -6ls>", ws + 2, "<\xd1\x84\xd1\x8f >");
419 tls("<%+-6ls>", ws + 2, "<\xd1\x84\xd1\x8f >");
420 tls("<%06ls>", ws + 2, "<00\xd1\x84\xd1\x8f>");
421 tls("<%-06ls>", ws + 2, "<\xd1\x84\xd1\x8f >");
422 ts("<%lls>", "text", "<text>");
423 }
424
425 /*
426 * Summarize the results.
427 */
428
429 if (badret + badlen + badout)
430 errx(1, "ERRORS: %d fail + %d mismatch (incl. %d bad length)",
431 badret, badout, badlen);
432 else if (verbose)
433 warnx("SUCCESS");
434 return 0;
435}