Module Name:    src
Committed By:   matt
Date:           Sun Aug 23 06:40:49 UTC 2009

Modified Files:
        src/common/lib/libc/string [matt-nb5-mips64]: memset2.c

Log Message:
Add a unit test to this file.  Fix two bugs.


To generate a diff of this commit:
cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/common/lib/libc/string/memset2.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/common/lib/libc/string/memset2.c
diff -u src/common/lib/libc/string/memset2.c:1.1.2.1 src/common/lib/libc/string/memset2.c:1.1.2.2
--- src/common/lib/libc/string/memset2.c:1.1.2.1	Mon Aug 17 17:24:25 2009
+++ src/common/lib/libc/string/memset2.c	Sun Aug 23 06:40:49 2009
@@ -42,25 +42,37 @@
 #include <sys/endian.h>
 #include <machine/types.h>
 
+#ifdef TEST
+#include <assert.h>
+#define _DIAGASSERT(a)		assert(a)
+#endif
+
 #ifdef _FORTIFY_SOURCE
 #undef bzero
 #undef memset
 #endif
 
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: memset2.c,v 1.1.2.1 2009/08/17 17:24:25 matt Exp $");    
+__RCSID("$NetBSD: memset2.c,v 1.1.2.2 2009/08/23 06:40:49 matt Exp $");    
 #endif /* LIBC_SCCS and not lint */
 
 /*
- * Assume register_t is the widest non-synthetic type.
+ * Assume uregister_t is the widest non-synthetic unsigned type.
  */
-typedef register_t memword_t;
+typedef uregister_t memword_t;
 
 #ifdef BZERO
 static inline
 #define	memset memset0
 #endif
 
+#ifdef TEST
+static
+#define memset test_memset
+#endif
+
+CTASSERT((~(memword_t)0U >> 1) != ~(memword_t)0U);
+
 void *
 memset(void *addr, int c, size_t len)
 {
@@ -104,7 +116,7 @@
 		keep_mask = ~(memword_t)0U << (fill_count * 8);
 #endif
 #if BYTE_ORDER == LITTLE_ENDIAN
-		keep_mask = ~(memword_t)0U << (fill_count * 8);
+		keep_mask = ~(memword_t)0U >> (fill_count * 8);
 #endif
 		/*
 		 * Make sure dstp is aligned to a memword_t boundary.
@@ -133,14 +145,19 @@
 			 */
 			dstp++;
 			keep_mask = 0;
+		} else {
+			len += (uintptr_t)addr & (sizeof(memword_t) - 1);
 		}
 #else /* __OPTIMIZE_SIZE__ */
 		uint8_t *dp, *ep;
+		if (len < fill_count)
+			fill_count = len;
 		for (dp = (uint8_t *)dstp, ep = dp + fill_count;
 		     dp != ep; dp++)
 			*dp = fill;
+		if ((len -= fill_count) == 0)
+			return addr;
 		dstp = (memword_t *)ep;
-		len -= fill_count;
 #endif /* __OPTIMIZE_SIZE__ */
 	}
 
@@ -172,10 +189,10 @@
 		 * space in the first word.
 		 */
 #if BYTE_ORDER == BIG_ENDIAN
-		keep_mask |= ~(~(memword_t)0U >> (len * 8));
+		keep_mask |= ~(memword_t)0U >> (len * 8);
 #endif
 #if BYTE_ORDER == LITTLE_ENDIAN
-		keep_mask |= ~(~(memword_t)0U << (len * 8));
+		keep_mask |= ~(memword_t)0U << (len * 8);
 #endif
 		/*
 		 * Now we mask off the bytes we are filling and then fill in
@@ -206,3 +223,53 @@
 	memset(addr, 0, len);
 }
 #endif
+
+#ifdef TEST
+#include <stdbool.h>
+#include <stdio.h>
+
+#undef memset
+
+static union {
+	uint8_t bytes[sizeof(memword_t) * 4];
+	memword_t words[4];
+} testmem;
+
+int
+main(int argc, char **argv)
+{
+	size_t start;
+	size_t len;
+	bool failed = false;
+
+	for (start = 1; start < sizeof(testmem) - 1; start++) {
+		for (len = 1; start + len < sizeof(testmem) - 1; len++) {
+			bool ok = true;
+			size_t i;
+			uint8_t check_value;
+			memset(testmem.bytes, 0xff, sizeof(testmem));
+			test_memset(testmem.bytes + start, 0x00, len);
+			for (i = 0; i < sizeof(testmem); i++) {
+				if (i == 0 || i == start + len)
+					check_value = 0xff;
+				else if (i == start)
+					check_value = 0x00;
+				if (testmem.bytes[i] != check_value) {
+					if (ok)
+						printf("pass @ %zu .. %zu failed",
+						    start, start + len - 1);
+					ok = false;
+					printf(" [%zu]=0x%02x(!0x%02x)",
+					    i, testmem.bytes[i], check_value);
+				}
+			}
+			if (!ok) {
+				printf("\n");
+				failed = 1;
+			}
+		}
+	}
+
+	return failed ? 1 : 0;
+}
+#endif /* TEST */

Reply via email to