Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src swab(3): Rewrite this to be understandable.
details: https://anonhg.NetBSD.org/src/rev/9db298915448
branches: trunk
changeset: 372817:9db298915448
user: riastradh <riastradh%NetBSD.org@localhost>
date: Wed Dec 28 15:34:19 2022 +0000
description:
swab(3): Rewrite this to be understandable.
And make the tests work, and exercise all lengths up to 100.
Evidently the previous definition, presumably tightly optimized for
1980s-era compilers and CPUs, was too hard to understand, because it
was incorrectly tested for two decades and broken for years.
PR lib/57141
XXX pullup-8
XXX pullup-9
XXX pullup-10
diffstat:
lib/libc/string/swab.c | 94 ++++++++++++++++++-----------------------
tests/lib/libc/string/t_swab.c | 26 +++++++----
2 files changed, 58 insertions(+), 62 deletions(-)
diffs (184 lines):
diff -r 7ba9ebf944f7 -r 9db298915448 lib/libc/string/swab.c
--- a/lib/libc/string/swab.c Wed Dec 28 14:32:04 2022 +0000
+++ b/lib/libc/string/swab.c Wed Dec 28 15:34:19 2022 +0000
@@ -1,11 +1,9 @@
-/* $NetBSD: swab.c,v 1.19 2022/12/28 14:32:04 kre Exp $ */
+/* $NetBSD: swab.c,v 1.20 2022/12/28 15:34:19 riastradh Exp $ */
+
-/*
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Jeffrey Mogul.
+/*-
+ * Copyright (c) 2022 The NetBSD Foundation, Inc.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -15,66 +13,58 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-#if 0
-static char sccsid[] = "@(#)swab.c 8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: swab.c,v 1.19 2022/12/28 14:32:04 kre Exp $");
+__RCSID("$NetBSD: swab.c,v 1.20 2022/12/28 15:34:19 riastradh Exp $");
#endif
-#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <unistd.h>
void
-swab(const void * __restrict from, void * __restrict to, ssize_t len)
+swab(const void *__restrict src, void *__restrict dst, ssize_t nbytes)
{
- char temp;
- const char *fp;
- char *tp;
+ const char *p = src;
+ char *q = dst;
+ size_t n;
- if (len <= 1)
+ _DIAGASSERT(src != NULL);
+ _DIAGASSERT(dst != NULL);
+
+ if (nbytes <= 1)
return;
- _DIAGASSERT(from != NULL);
- _DIAGASSERT(to != NULL);
-
- len /= 2;
- fp = (const char *)from;
- tp = (char *)to;
-#define STEP temp = *fp++,*tp++ = *fp++,*tp++ = temp
+ /*
+ * Round nbytes/2 down; we ignore the last byte altogether if
+ * nbytes is odd. This way, if the destination array is
+ * uninitialized, sanitizers will recognize the last byte as
+ * still uninitialized and flag it as undefined.
+ */
+ for (n = nbytes/2; n --> 0; p += 2, q += 2) {
+ /*
+ * According to POSIX (2018), the behaviour is
+ * undefined if src and dst overlap. However, there
+ * are uses in-tree (xsrc/external/mit/xfwp/dist/io.c)
+ * that rely on swab(ptr, ptr, n) to do the swabbing
+ * in-place. So make sure this works if src == dst.
+ */
+ const char p0 = p[0], p1 = p[1];
- if (__predict_false(len == 1)) {
- STEP;
- return;
- }
-
- /* round to multiple of 8 */
- while ((len % 8) != 0)
- len--, STEP;
- len /= 8;
- if (len == 0)
- return;
- while (len-- != 0) {
- STEP; STEP; STEP; STEP;
- STEP; STEP; STEP; STEP;
+ q[0] = p1;
+ q[1] = p0;
}
}
diff -r 7ba9ebf944f7 -r 9db298915448 tests/lib/libc/string/t_swab.c
--- a/tests/lib/libc/string/t_swab.c Wed Dec 28 14:32:04 2022 +0000
+++ b/tests/lib/libc/string/t_swab.c Wed Dec 28 15:34:19 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_swab.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */
+/* $NetBSD: t_swab.c,v 1.3 2022/12/28 15:34:19 riastradh Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -39,15 +39,17 @@
#define MAXCHK 100
static void
-build(char *a, char *b, size_t n) {
+build(char *a, char *b, size_t n)
+{
size_t i;
- n >>= 1;
for (i = 0; i < n; i += 2) {
- b[i+1] = a[i] = (char)i;
- b[i] = a[i+1] = (char)(i+1);
+ b[i + 1] = a[i] = (char)i;
+ b[i] = a[i + 1] = (char)(i + 1);
}
- for (n <<= 1; n < MAXCHK; n++)
+ if (n & 1)
+ a[n - 1] = b[n - 1] = (char)~1;
+ for (; n < MAXCHK; n++)
a[n] = b[n] = (char)~0;
}
@@ -72,19 +74,23 @@
{
char a[MAXCHK], b[MAXCHK], r[MAXCHK];
size_t i;
+ bool failed = false;
- for (i = 0; i < MAXCHK; i += 2) {
+ for (i = 0; i < MAXCHK; i++) {
build(a, b, i);
(void)memset(r, ~0, MAXCHK);
swab(a, r, i);
+ if (i & 1) /* last byte unspecified if odd length */
+ r[i - 1] = (char )~1;
if (memcmp(b, r, MAXCHK) != 0) {
- fprintf(stderr, "pattern mismatch at %lu bytes",
- (unsigned long)i);
+ printf("pattern mismatch at %zu bytes\n", i);
dump("expect:", b, MAXCHK);
dump("result:", r, MAXCHK);
- atf_tc_fail("Check stderr for details");
+ failed = true;
}
}
+ if (failed)
+ atf_tc_fail_nonfatal("Check stdout for details");
}
ATF_TP_ADD_TCS(tp)
Home |
Main Index |
Thread Index |
Old Index