aboutsummaryrefslogtreecommitdiff
path: root/string/test
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2020-04-16 11:46:02 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2020-04-24 13:28:47 +0100
commit22fd93176f9eca0ee38954e233826d05fdb31b0f (patch)
treef0e6908e1804a1943a56a445ebec861f31a967d6 /string/test
parent563b710ddc13810bd89fc17f057f4f7f8479e744 (diff)
downloadarm-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.c16
-rw-r--r--string/test/memcmp.c44
-rw-r--r--string/test/memcpy.c16
-rw-r--r--string/test/memmove.c40
-rw-r--r--string/test/memset.c35
-rw-r--r--string/test/stpcpy.c24
-rw-r--r--string/test/strchr.c23
-rw-r--r--string/test/strchrnul.c26
-rw-r--r--string/test/strcmp.c49
-rw-r--r--string/test/strcpy.c24
-rw-r--r--string/test/stringtest.h50
-rw-r--r--string/test/strlen.c25
-rw-r--r--string/test/strncmp.c69
-rw-r--r--string/test/strnlen.c27
-rw-r--r--string/test/strrchr.c26
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;