diff options
author | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2020-04-16 11:46:02 +0100 |
---|---|---|
committer | Szabolcs Nagy <szabolcs.nagy@arm.com> | 2020-04-24 13:28:47 +0100 |
commit | 22fd93176f9eca0ee38954e233826d05fdb31b0f (patch) | |
tree | f0e6908e1804a1943a56a445ebec861f31a967d6 /string/test | |
parent | 563b710ddc13810bd89fc17f057f4f7f8479e744 (diff) | |
download | arm-optimized-routines-22fd93176f9eca0ee38954e233826d05fdb31b0f.tar.gz |
string: test cleanups
Tests printed too much output on broken string function
and the output was not entirely useful.
Added a new header file with some common logic for
printing buffers nicely.
In str* tests len now means string length (not buffer
size which was confusing).
Diffstat (limited to 'string/test')
-rw-r--r-- | string/test/memchr.c | 16 | ||||
-rw-r--r-- | string/test/memcmp.c | 44 | ||||
-rw-r--r-- | string/test/memcpy.c | 16 | ||||
-rw-r--r-- | string/test/memmove.c | 40 | ||||
-rw-r--r-- | string/test/memset.c | 35 | ||||
-rw-r--r-- | string/test/stpcpy.c | 24 | ||||
-rw-r--r-- | string/test/strchr.c | 23 | ||||
-rw-r--r-- | string/test/strchrnul.c | 26 | ||||
-rw-r--r-- | string/test/strcmp.c | 49 | ||||
-rw-r--r-- | string/test/strcpy.c | 24 | ||||
-rw-r--r-- | string/test/stringtest.h | 50 | ||||
-rw-r--r-- | string/test/strlen.c | 25 | ||||
-rw-r--r-- | string/test/strncmp.c | 69 | ||||
-rw-r--r-- | string/test/strnlen.c | 27 | ||||
-rw-r--r-- | string/test/strrchr.c | 26 |
15 files changed, 278 insertions, 216 deletions
diff --git a/string/test/memchr.c b/string/test/memchr.c index 391c9df..15531c6 100644 --- a/string/test/memchr.c +++ b/string/test/memchr.c @@ -11,6 +11,7 @@ #include <string.h> #include <limits.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -32,9 +33,6 @@ F(__memchr_arm) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define SP 512 #define LEN 250000 @@ -57,6 +55,8 @@ static void test(const struct fun *fun, int align, size_t seekpos, int i; void *p; + if (err_count >= ERR_LIMIT) + return; if (array_len > LEN || seekpos >= array_len || align >= A) abort(); @@ -71,8 +71,8 @@ static void test(const struct fun *fun, int align, size_t seekpos, if (p != f) { ERR("%s(%p,0x%02x,%zu) returned %p\n", fun->name, s, seekchar, param_len, p); - ERR("expected: %p\n", f); - abort(); + printf("expected: %p\n", f); + quote("str", s, param_len); } } @@ -80,7 +80,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int a = 0; a < A; a++) { for (int n = 0; n < 100; n++) for (int sp = 0; sp < n-1; sp++) @@ -93,8 +93,8 @@ int main() test(funtab+i, a, LEN-1-n, LEN, MAX_LEN-n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/memcmp.c b/string/test/memcmp.c index 114f1d7..28160ef 100644 --- a/string/test/memcmp.c +++ b/string/test/memcmp.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -28,9 +29,6 @@ F(__memcmp_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 static unsigned char s1buf[LEN+2*A]; @@ -41,7 +39,7 @@ static void *alignup(void *p) return (void*)(((uintptr_t)p + A-1) & -A); } -static void test(const struct fun *fun, int s1align, int s2align, int len, int diffpos) +static void test(const struct fun *fun, int s1align, int s2align, int len, int diffpos, int delta) { unsigned char *src1 = alignup(s1buf); unsigned char *src2 = alignup(s2buf); @@ -49,25 +47,29 @@ static void test(const struct fun *fun, int s1align, int s2align, int len, int d unsigned char *s2 = src2 + s2align; int r; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || s1align >= A || s2align >= A) abort(); - if (diffpos && diffpos >= len) + if (diffpos >= len) + abort(); + if ((diffpos < 0) != (delta == 0)) abort(); for (int i = 0; i < len+A; i++) src1[i] = src2[i] = '?'; for (int i = 0; i < len; i++) s1[i] = s2[i] = 'a' + i%23; - if (diffpos) - s1[diffpos]++; + if (delta) + s1[diffpos] += delta; r = fun->fun(s1, s2, len); - if ((!diffpos && r != 0) || (diffpos && r == 0)) { + if ((delta == 0 && r != 0) || (delta > 0 && r <= 0) || (delta < 0 && r >= 0)) { ERR("%s(align %d, align %d, %d) failed, returned %d\n", fun->name, s1align, s2align, len, r); - ERR("src1: %.*s\n", s1align+len+1, src1); - ERR("src2: %.*s\n", s2align+len+1, src2); + quoteat("src1", src1, len+A, diffpos); + quoteat("src2", src2, len+A, diffpos); } } @@ -75,21 +77,27 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; - for (n = 0; n < 100; n++) { - test(funtab+i, d, s, n, 0); - test(funtab+i, d, s, n, n / 2); + test(funtab+i, d, s, 0, -1, 0); + test(funtab+i, d, s, 1, -1, 0); + test(funtab+i, d, s, 1, 0, -1); + test(funtab+i, d, s, 1, 0, 1); + for (n = 2; n < 100; n++) { + test(funtab+i, d, s, n, -1, 0); + test(funtab+i, d, s, n, 0, -1); + test(funtab+i, d, s, n, n - 1, -1); + test(funtab+i, d, s, n, n / 2, 1); } for (; n < LEN; n *= 2) { - test(funtab+i, d, s, n, 0); - test(funtab+i, d, s, n, n / 2); + test(funtab+i, d, s, n, -1, 0); + test(funtab+i, d, s, n, n / 2, -1); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/memcpy.c b/string/test/memcpy.c index 8572452..bf1bbae 100644 --- a/string/test/memcpy.c +++ b/string/test/memcpy.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -30,9 +31,6 @@ F(__memcpy_arm) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 static unsigned char dbuf[LEN+2*A]; @@ -55,6 +53,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) void *p; int i; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || dalign >= A || salign >= A) abort(); for (i = 0; i < len+A; i++) { @@ -70,8 +70,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) for (i = 0; i < len+A; i++) { if (dst[i] != want[i]) { ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len); - ERR("got : %.*s\n", dalign+len+1, dst); - ERR("want: %.*s\n", dalign+len+1, want); + quoteat("got", dst, len+A, i); + quoteat("want", want, len+A, i); break; } } @@ -81,7 +81,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; @@ -90,8 +90,8 @@ int main() for (; n < LEN; n *= 2) test(funtab+i, d, s, n); } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/memmove.c b/string/test/memmove.c index 7891b14..04f4c3c 100644 --- a/string/test/memmove.c +++ b/string/test/memmove.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -28,9 +29,6 @@ F(__memmove_aarch64_simd) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 static unsigned char dbuf[LEN+2*A]; @@ -53,6 +51,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) void *p; int i; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || dalign >= A || salign >= A) abort(); for (i = 0; i < len+A; i++) { @@ -68,8 +68,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) for (i = 0; i < len+A; i++) { if (dst[i] != want[i]) { ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len); - ERR("got : %.*s\n", dalign+len+1, dst); - ERR("want: %.*s\n", dalign+len+1, want); + quoteat("got", dst, len+A, i); + quoteat("want", want, len+A, i); break; } } @@ -78,13 +78,15 @@ static void test(const struct fun *fun, int dalign, int salign, int len) static void test_overlap(const struct fun *fun, int dalign, int salign, int len) { unsigned char *src = alignup(sbuf); - unsigned char *dst = alignup(sbuf); + unsigned char *dst = src; unsigned char *want = wbuf; unsigned char *s = src + salign; unsigned char *d = dst + dalign; unsigned char *w = wbuf + dalign; void *p; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || dalign >= A || salign >= A) abort(); @@ -92,16 +94,9 @@ static void test_overlap(const struct fun *fun, int dalign, int salign, int len) src[i] = want[i] = '?'; for (int i = 0; i < len; i++) - s[i] = w[i] = 'a' + i%23; - - /* Copy the potential overlap range. */ - if (s < d) { - for (int i = 0; i < (uintptr_t)d-(uintptr_t)s; i++) - want[salign+i] = src[salign+i]; - } else { - for (int i = 0; i < (uintptr_t)s-(uintptr_t)d; i++) - want[len + dalign + i] = src[len + dalign + i]; - } + s[i] = want[salign+i] = 'a' + i%23; + for (int i = 0; i < len; i++) + w[i] = s[i]; p = fun->fun(d, s, len); if (p != d) @@ -109,9 +104,8 @@ static void test_overlap(const struct fun *fun, int dalign, int salign, int len) for (int i = 0; i < len+A; i++) { if (dst[i] != want[i]) { ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len); - ERR("got : %.*s\n", dalign+len+1, dst); - ERR("want: %.*s\n", dalign+len+1, want); - abort(); + quoteat("got", dst, len+A, i); + quoteat("want", want, len+A, i); break; } } @@ -119,11 +113,9 @@ static void test_overlap(const struct fun *fun, int dalign, int salign, int len) int main() { - test_overlap(funtab+0, 2, 1, 1); - int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; @@ -136,8 +128,8 @@ int main() test_overlap(funtab+i, d, s, n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/memset.c b/string/test/memset.c index 48c10fa..8b05bd6 100644 --- a/string/test/memset.c +++ b/string/test/memset.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -27,9 +28,6 @@ F(__memset_arm) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 static unsigned char sbuf[LEN+2*A]; @@ -39,12 +37,6 @@ static void *alignup(void *p) return (void*)(((uintptr_t)p + A-1) & -A); } -static void err(const char *name, unsigned char *src, int salign, int c, int len) -{ - ERR("%s(align %d, %d, %d) failed\n", name, salign, c, len); - ERR("got : %.*s\n", salign+len+1, src); -} - static void test(const struct fun *fun, int salign, int c, int len) { unsigned char *src = alignup(sbuf); @@ -52,14 +44,14 @@ static void test(const struct fun *fun, int salign, int c, int len) void *p; int i; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || salign >= A) abort(); for (i = 0; i < len+A; i++) src[i] = '?'; for (i = 0; i < len; i++) s[i] = 'a' + i%23; - for (; i<len%A; i++) - s[i] = '*'; p = fun->fun(s, c, len); if (p != s) @@ -67,19 +59,22 @@ static void test(const struct fun *fun, int salign, int c, int len) for (i = 0; i < salign; i++) { if (src[i] != '?') { - err(fun->name, src, salign, c, len); + ERR("%s(align %d, %d, %d) failed\n", fun->name, salign, c, len); + quoteat("got", src, len+A, i); return; } } - for (i = salign; i < len; i++) { + for (; i < salign+len; i++) { if (src[i] != (unsigned char)c) { - err(fun->name, src, salign, c, len); + ERR("%s(align %d, %d, %d) failed\n", fun->name, salign, c, len); + quoteat("got", src, len+A, i); return; } } - for (; i < len%A; i++) { - if (src[i] != '*') { - err(fun->name, src, salign, c, len); + for (; i < len+A; i++) { + if (src[i] != '?') { + ERR("%s(align %d, %d, %d) failed\n", fun->name, salign, c, len); + quoteat("got", src, len+A, i); return; } } @@ -89,7 +84,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int s = 0; s < A; s++) { int n; for (n = 0; n < 100; n++) { @@ -103,8 +98,8 @@ int main() test(funtab+i, s, 0xaa25, n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/stpcpy.c b/string/test/stpcpy.c index 9050227..9001057 100644 --- a/string/test/stpcpy.c +++ b/string/test/stpcpy.c @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -29,14 +30,11 @@ F(__stpcpy_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 -static char dbuf[LEN+2*A]; -static char sbuf[LEN+2*A]; -static char wbuf[LEN+2*A]; +static char dbuf[LEN+2*A+1]; +static char sbuf[LEN+2*A+1]; +static char wbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -54,6 +52,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) void *p; int i; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || dalign >= A || salign >= A) abort(); for (i = 0; i < len+A; i++) { @@ -62,7 +62,7 @@ static void test(const struct fun *fun, int dalign, int salign, int len) } for (i = 0; i < len; i++) s[i] = w[i] = 'a' + i%23; - s[i] = w[i] = '\0'; + s[len] = w[len] = '\0'; p = fun->fun(d, s); if (p != d + len) @@ -70,8 +70,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) for (i = 0; i < len+A; i++) { if (dst[i] != want[i]) { ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len); - ERR("got : %.*s\n", dalign+len+1, dst); - ERR("want: %.*s\n", dalign+len+1, want); + quoteat("got", dst, len+A, i); + quoteat("want", want, len+A, i); break; } } @@ -81,7 +81,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; @@ -90,8 +90,8 @@ int main() for (; n < LEN; n *= 2) test(funtab+i, d, s, n); } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strchr.c b/string/test/strchr.c index 80a454a..d6ed39a 100644 --- a/string/test/strchr.c +++ b/string/test/strchr.c @@ -11,6 +11,7 @@ #include <string.h> #include <limits.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -30,13 +31,10 @@ F(__strchr_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define SP 512 #define LEN 250000 -static char sbuf[LEN+2*A]; +static char sbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -51,24 +49,27 @@ static void test(const struct fun *fun, int align, int seekpos, int len) int seekchar = 0x1; void *p; - if (len > LEN || seekpos >= len - 1 || align >= A) + if (err_count >= ERR_LIMIT) + return; + if (len > LEN || seekpos >= len || align >= A) abort(); if (seekchar >= 'a' && seekchar <= 'a' + 23) abort(); for (int i = 0; i < len + A; i++) src[i] = '?'; - for (int i = 0; i < len - 2; i++) + for (int i = 0; i < len; i++) s[i] = 'a' + i%23; if (seekpos != -1) s[seekpos] = seekchar; - s[len - 1] = '\0'; + s[len] = '\0'; p = fun->fun(s, seekchar); if (p != f) { ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p); - ERR("expected: %p\n", f); + quoteat("input", s, len+A, seekpos); + printf("expected: %p\n", f); abort(); } } @@ -77,7 +78,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int a = 0; a < A; a++) { int n; for (n = 1; n < 100; n++) { @@ -90,8 +91,8 @@ int main() test(funtab+i, a, n / 2, n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strchrnul.c b/string/test/strchrnul.c index 4e3f681..78192c4 100644 --- a/string/test/strchrnul.c +++ b/string/test/strchrnul.c @@ -13,6 +13,7 @@ #include <string.h> #include <limits.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -32,13 +33,10 @@ F(__strchrnul_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define SP 512 #define LEN 250000 -static char sbuf[LEN+2*A]; +static char sbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -49,29 +47,31 @@ static void test(const struct fun *fun, int align, int seekpos, int len) { char *src = alignup(sbuf); char *s = src + align; - char *f = seekpos != -1 ? s + seekpos : s + len - 1; + char *f = seekpos != -1 ? s + seekpos : s + len; int seekchar = 0x1; void *p; - if (len > LEN || seekpos >= len - 1 || align >= A) + if (err_count >= ERR_LIMIT) + return; + if (len > LEN || seekpos >= len || align >= A) abort(); if (seekchar >= 'a' && seekchar <= 'a' + 23) abort(); for (int i = 0; i < len + A; i++) src[i] = '?'; - for (int i = 0; i < len - 2; i++) + for (int i = 0; i < len; i++) s[i] = 'a' + i%23; if (seekpos != -1) s[seekpos] = seekchar; - s[len - 1] = '\0'; + s[len] = '\0'; p = fun->fun(s, seekchar); if (p != f) { ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p); - ERR("expected: %p\n", f); - abort(); + quoteat("input", s, len+A, seekpos); + printf("expected: %p\n", f); } } @@ -79,7 +79,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int a = 0; a < A; a++) { int n; for (n = 1; n < 100; n++) { @@ -92,8 +92,8 @@ int main() test(funtab+i, a, n / 2, n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strcmp.c b/string/test/strcmp.c index 91fa9dd..32f4c2a 100644 --- a/string/test/strcmp.c +++ b/string/test/strcmp.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -34,20 +35,17 @@ F(__strcmp_armv6m) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 -static char s1buf[LEN+2*A]; -static char s2buf[LEN+2*A]; +static char s1buf[LEN+2*A+1]; +static char s2buf[LEN+2*A+1]; static void *alignup(void *p) { return (void*)(((uintptr_t)p + A-1) & -A); } -static void test(const struct fun *fun, int s1align, int s2align, int len, int diffpos) +static void test(const struct fun *fun, int s1align, int s2align, int len, int diffpos, int delta) { char *src1 = alignup(s1buf); char *src2 = alignup(s2buf); @@ -55,26 +53,30 @@ static void test(const struct fun *fun, int s1align, int s2align, int len, int d char *s2 = src2 + s2align; int r; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || s1align >= A || s2align >= A) abort(); - if (diffpos > 1 && diffpos >= len-1) + if (diffpos >= len) + abort(); + if ((diffpos < 0) != (delta == 0)) abort(); for (int i = 0; i < len+A; i++) src1[i] = src2[i] = '?'; - for (int i = 0; i < len-1; i++) + for (int i = 0; i < len; i++) s1[i] = s2[i] = 'a' + i%23; - if (diffpos > 1) - s1[diffpos]++; + if (delta) + s1[diffpos] += delta; s1[len] = s2[len] = '\0'; r = fun->fun(s1, s2); - if (((diffpos <= 1) && r != 0) || (diffpos > 1 && r == 0)) { + if ((delta == 0 && r != 0) || (delta > 0 && r <= 0) || (delta < 0 && r >= 0)) { ERR("%s(align %d, align %d, %d) failed, returned %d\n", fun->name, s1align, s2align, len, r); - ERR("src1: %.*s\n", s1align+len+1, src1); - ERR("src2: %.*s\n", s2align+len+1, src2); + quoteat("src1", src1, len+A, diffpos); + quoteat("src2", src2, len+A, diffpos); } } @@ -82,21 +84,26 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; - for (n = 0; n < 100; n++) { - test(funtab+i, d, s, n, 0); - test(funtab+i, d, s, n, n / 2); + test(funtab+i, d, s, 0, -1, 0); + test(funtab+i, d, s, 1, -1, 0); + test(funtab+i, d, s, 1, 0, 1); + test(funtab+i, d, s, 1, 0, -1); + for (n = 2; n < 100; n++) { + test(funtab+i, d, s, n, -1, 0); + test(funtab+i, d, s, n, n - 1, -1); + test(funtab+i, d, s, n, n / 2, 1); } for (; n < LEN; n *= 2) { - test(funtab+i, d, s, n, 0); - test(funtab+i, d, s, n, n / 2); + test(funtab+i, d, s, n, -1, 0); + test(funtab+i, d, s, n, n / 2, -1); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strcpy.c b/string/test/strcpy.c index ea74c9e..68fc76f 100644 --- a/string/test/strcpy.c +++ b/string/test/strcpy.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -30,14 +31,11 @@ F(__strcpy_arm) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 -static char dbuf[LEN+2*A]; -static char sbuf[LEN+2*A]; -static char wbuf[LEN+2*A]; +static char dbuf[LEN+2*A+1]; +static char sbuf[LEN+2*A+1]; +static char wbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -55,6 +53,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) void *p; int i; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || dalign >= A || salign >= A) abort(); for (i = 0; i < len+A; i++) { @@ -63,7 +63,7 @@ static void test(const struct fun *fun, int dalign, int salign, int len) } for (i = 0; i < len; i++) s[i] = w[i] = 'a' + i%23; - s[i] = w[i] = '\0'; + s[len] = w[len] = '\0'; p = fun->fun(d, s); if (p != d) @@ -71,8 +71,8 @@ static void test(const struct fun *fun, int dalign, int salign, int len) for (i = 0; i < len+A; i++) { if (dst[i] != want[i]) { ERR("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign, len); - ERR("got : %.*s\n", dalign+len+1, dst); - ERR("want: %.*s\n", dalign+len+1, want); + quoteat("got", dst, len+A, i); + quoteat("want", want, len+A, i); break; } } @@ -82,7 +82,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; @@ -91,8 +91,8 @@ int main() for (; n < LEN; n *= 2) test(funtab+i, d, s, n); } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/stringtest.h b/string/test/stringtest.h new file mode 100644 index 0000000..b9c034a --- /dev/null +++ b/string/test/stringtest.h @@ -0,0 +1,50 @@ +/* + * Common string test code. + * + * Copyright (c) 2020, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +#include <ctype.h> +#include <stdio.h> + +/* Accounting errors for a test case. */ +static int err_count; +#define ERR_LIMIT 10 +#define ERR(...) (err_count++, printf(__VA_ARGS__)) + +static inline void quotechar(unsigned char c) +{ + if (isprint(c)) + putchar(c); + else + printf("\\x%02x", c); +} + +/* quoted print around at or the entire string if at < 0. */ +static void quoteat(const char *prefix, const void *p, int len, int at) +{ + static const int CTXLEN = 15; + int i; + const char *pre="\""; + const char *post="\""; + const char *s = p; + if (at > CTXLEN) { + s += at - CTXLEN; + len -= at - CTXLEN; + pre = "...\""; + } + if (at >= 0 && len > 2*CTXLEN + 1) { + len = 2*CTXLEN + 1; + post = "\"..."; + } + printf("%4s: %s", prefix, pre); + for (i = 0; i < len; i++) + quotechar(s[i]); + printf("%s\n", post); +} + +static inline void quote(const char *prefix, const void *p, int len) +{ + quoteat(prefix, p, len, -1); +} diff --git a/string/test/strlen.c b/string/test/strlen.c index 96e6cd6..b2e2ffa 100644 --- a/string/test/strlen.c +++ b/string/test/strlen.c @@ -11,6 +11,7 @@ #include <string.h> #include <limits.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -34,13 +35,10 @@ F(__strlen_armv6t2) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define SP 512 #define LEN 250000 -static char sbuf[LEN+2*A]; +static char sbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -53,21 +51,22 @@ static void test(const struct fun *fun, int align, int len) char *s = src + align; size_t r; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || align >= A) abort(); for (int i = 0; i < len + A; i++) src[i] = '?'; - for (int i = 0; i < len - 2; i++) + for (int i = 0; i < len; i++) s[i] = 'a' + i%23; - s[len - 1] = '\0'; + s[len] = '\0'; r = fun->fun(s); - if (r != len-1) { + if (r != len) { ERR("%s(%p) returned %zu\n", fun->name, s, r); - ERR("input: %.*s\n", align+len+1, src); - ERR("expected: %d\n", len); - abort(); + quote("input", src, len); + printf("expected: %d\n", len); } } @@ -75,7 +74,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int a = 0; a < A; a++) { int n; for (n = 1; n < 100; n++) @@ -83,8 +82,8 @@ int main() for (; n < LEN; n *= 2) test(funtab+i, a, n); } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strncmp.c b/string/test/strncmp.c index 43f941d..fea4d01 100644 --- a/string/test/strncmp.c +++ b/string/test/strncmp.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <string.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -28,20 +29,17 @@ F(__strncmp_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define LEN 250000 -static char s1buf[LEN+2*A]; -static char s2buf[LEN+2*A]; +static char s1buf[LEN+2*A+1]; +static char s2buf[LEN+2*A+1]; static void *alignup(void *p) { return (void*)(((uintptr_t)p + A-1) & -A); } -static void test(const struct fun *fun, int s1align, int s2align, int maxlen, int diffpos, int len) +static void test(const struct fun *fun, int s1align, int s2align, int maxlen, int diffpos, int len, int delta) { char *src1 = alignup(s1buf); char *src2 = alignup(s2buf); @@ -49,28 +47,34 @@ static void test(const struct fun *fun, int s1align, int s2align, int maxlen, in char *s2 = src2 + s2align; int r; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || s1align >= A || s2align >= A) abort(); - if (diffpos > 1 && diffpos >= len-1) + if (diffpos >= len) + abort(); + if ((diffpos < 0) != (delta == 0)) abort(); for (int i = 0; i < len+A; i++) src1[i] = src2[i] = '?'; - for (int i = 0; i < len-1; i++) + for (int i = 0; i < len; i++) s1[i] = s2[i] = 'a' + i%23; - if (diffpos > 1) - s1[diffpos]++; + if (delta) + s1[diffpos] += delta; s1[len] = s2[len] = '\0'; r = fun->fun(s1, s2, maxlen); - diffpos = maxlen <= diffpos ? 0 : diffpos; - - if (((diffpos <= 1) && r != 0) || (diffpos > 1 && r == 0)) { - ERR("%s(align %d, align %d, %d (%d)) failed, returned %d (%d)\n", - fun->name, s1align, s2align, maxlen, len, r, diffpos); - ERR("src1: %.*s\n", s1align+len+1, src1); - ERR("src2: %.*s\n", s2align+len+1, src2); + if (diffpos >= maxlen) { + diffpos = -1; + delta = 0; + } + if ((delta == 0 && r != 0) || (delta > 0 && r <= 0) || (delta < 0 && r >= 0)) { + ERR("%s(align %d, align %d, %d) (len=%d, diffpos=%d) failed, returned %d\n", + fun->name, s1align, s2align, maxlen, len, diffpos, r); + quoteat("src1", src1, len+A, diffpos); + quoteat("src2", src2, len+A, diffpos); } } @@ -78,25 +82,32 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int d = 0; d < A; d++) for (int s = 0; s < A; s++) { int n; - for (n = 0; n < 100; n++) { - test(funtab+i, d, s, n, 0, n); - test(funtab+i, d, s, n, n/2, n); - test(funtab+i, d, s, n/2, 0, n); - test(funtab+i, d, s, n/2, n/2, n); + test(funtab+i, d, s, 0, -1, 0, 0); + test(funtab+i, d, s, 1, -1, 0, 0); + test(funtab+i, d, s, 0, -1, 1, 0); + test(funtab+i, d, s, 1, -1, 1, 0); + test(funtab+i, d, s, 2, -1, 1, 0); + test(funtab+i, d, s, 1, 0, 1, 1); + test(funtab+i, d, s, 1, 0, 1, -1); + for (n = 2; n < 100; n++) { + test(funtab+i, d, s, n, -1, n, 0); + test(funtab+i, d, s, n, n/2, n, 1); + test(funtab+i, d, s, n/2, -1, n, 0); + test(funtab+i, d, s, n/2, n/2, n, -1); } for (; n < LEN; n *= 2) { - test(funtab+i, d, s, n, 0, n); - test(funtab+i, d, s, n, n/2, n); - test(funtab+i, d, s, n/2, 0, n); - test(funtab+i, d, s, n/2, n/2, n); + test(funtab+i, d, s, n, -1, n, 0); + test(funtab+i, d, s, n, n/2, n, -1); + test(funtab+i, d, s, n/2, -1, n, 0); + test(funtab+i, d, s, n/2, n/2, n, 1); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strnlen.c b/string/test/strnlen.c index db41f2a..29f85a0 100644 --- a/string/test/strnlen.c +++ b/string/test/strnlen.c @@ -13,6 +13,7 @@ #include <string.h> #include <limits.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -31,13 +32,10 @@ F(__strnlen_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define SP 512 #define LEN 250000 -static char sbuf[LEN+2*A]; +static char sbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -49,23 +47,24 @@ static void test(const struct fun *fun, int align, int maxlen, int len) char *src = alignup(sbuf); char *s = src + align; size_t r; - size_t e = maxlen < len ? maxlen : len - 1; + size_t e = maxlen < len ? maxlen : len; + if (err_count >= ERR_LIMIT) + return; if (len > LEN || align >= A) abort(); for (int i = 0; i < len + A; i++) src[i] = '?'; - for (int i = 0; i < len - 2; i++) + for (int i = 0; i < len; i++) s[i] = 'a' + i%23; - s[len - 1] = '\0'; + s[len] = '\0'; r = fun->fun(s, maxlen); if (r != e) { - ERR("%s(%p) returned %zu\n", fun->name, s, r); - ERR("input: %.*s\n", align+len+1, src); - ERR("expected: %d\n", len); - abort(); + ERR("%s(%p, %d) returned %zu\n", fun->name, s, maxlen, r); + quote("input", src, len+A); + printf("expected: %zu\n", e); } } @@ -73,7 +72,7 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int a = 0; a < A; a++) { int n; for (n = 1; n < 100; n++) @@ -85,8 +84,8 @@ int main() test(funtab+i, a, n/2, n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; diff --git a/string/test/strrchr.c b/string/test/strrchr.c index 532fa51..d3d0bc5 100644 --- a/string/test/strrchr.c +++ b/string/test/strrchr.c @@ -11,6 +11,7 @@ #include <string.h> #include <limits.h> #include "stringlib.h" +#include "stringtest.h" static const struct fun { @@ -29,13 +30,10 @@ F(__strrchr_aarch64_sve) {0, 0} }; -static int test_status; -#define ERR(...) (test_status=1, printf(__VA_ARGS__)) - #define A 32 #define SP 512 #define LEN 250000 -static char sbuf[LEN+2*A]; +static char sbuf[LEN+2*A+1]; static void *alignup(void *p) { @@ -50,25 +48,27 @@ static void test(const struct fun *fun, int align, int seekpos, int len) int seekchar = 0x1; void *p; - if (len > LEN || seekpos >= len - 1 || align >= A) + if (err_count >= ERR_LIMIT) + return; + if (len > LEN || seekpos >= len || align >= A) abort(); if (seekchar >= 'a' && seekchar <= 'a' + 23) abort(); for (int i = 0; i < len + A; i++) src[i] = '?'; - for (int i = 0; i < len - 2; i++) + for (int i = 0; i < len; i++) s[i] = 'a' + i%23; if (seekpos != -1) s[seekpos/2] = s[seekpos] = seekchar; - s[len - 1] = '\0'; + s[len] = '\0'; p = fun->fun(s, seekchar); if (p != f) { ERR("%s(%p,0x%02x,%d) returned %p\n", fun->name, s, seekchar, len, p); - ERR("expected: %p\n", f); - abort(); + quote("input", s, len); + printf("expected: %p\n", f); } } @@ -76,11 +76,11 @@ int main() { int r = 0; for (int i=0; funtab[i].name; i++) { - test_status = 0; + err_count = 0; for (int a = 0; a < A; a++) { int n; for (n = 1; n < 100; n++) { - for (int sp = 0; sp < n - 1; sp++) + for (int sp = 0; sp < n; sp++) test(funtab+i, a, sp, n); test(funtab+i, a, -1, n); } @@ -89,8 +89,8 @@ int main() test(funtab+i, a, n / 2, n); } } - printf("%s %s\n", test_status ? "FAIL" : "PASS", funtab[i].name); - if (test_status) + printf("%s %s\n", err_count ? "FAIL" : "PASS", funtab[i].name); + if (err_count) r = -1; } return r; |