Make C memory safe like Rust

This change enables Address Sanitizer systemically w/ `make MODE=dbg`.
Our version of Rust's `unsafe` keyword is named `noasan` which is used
for two functions that do aligned memory chunking, like `strcpy.c` and
we need to fix the tiny DEFLATE code, but that's it everything else is
fabulous you can have all the fischer price security blankets you need

Best of all is we're now able to use the ASAN data in Blinkenlights to
colorize the memory dumps. See the screenshot below of a test program:

  https://justine.lol/blinkenlights/asan.png

Which is operating on float arrays stored on the stack, with red areas
indicating poisoned memory, and the green areas indicate valid memory.
This commit is contained in:
Justine Tunney 2021-02-01 03:33:13 -08:00
parent fdc3fa9148
commit 1ff9ab95ac
153 changed files with 2545 additions and 2077 deletions

View file

@ -18,12 +18,13 @@
*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(comparator, testByteCompare) {
char *b1 = tmalloc(1);
char *b2 = tmalloc(1);
char *b1 = malloc(1);
char *b2 = malloc(1);
/* sign doesn't matter */
EXPECT_EQ(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0);
EXPECT_LT(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0);
@ -41,26 +42,26 @@ TEST(comparator, testByteCompare) {
/* two's complement bane */
EXPECT_GT(cmpsb(memcpy(b1, "\x7f", 1), memcpy(b2, "\x80", 1)), 0);
EXPECT_LT(cmpub(memcpy(b1, "\x7f", 1), memcpy(b2, "\x80", 1)), 0);
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
TEST(comparator, testWordCompare) {
char *b1 = tmalloc(2);
char *b2 = tmalloc(2);
char *b1 = malloc(2);
char *b2 = malloc(2);
EXPECT_EQ(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_GT(cmpsw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_LT(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0);
EXPECT_EQ(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_LT(cmpuw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_GT(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0);
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
TEST(comparator, testDoublewordCompare) {
char *b1 = tmalloc(4);
char *b2 = tmalloc(4);
char *b1 = malloc(4);
char *b2 = malloc(4);
EXPECT_EQ(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
@ -79,13 +80,13 @@ TEST(comparator, testDoublewordCompare) {
EXPECT_GT(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x7f", 4)),
0);
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
TEST(comparator, testQuadwordCompare) {
char *b1 = tmalloc(8);
char *b2 = tmalloc(8);
char *b1 = malloc(8);
char *b2 = malloc(8);
EXPECT_EQ(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
@ -104,6 +105,6 @@ TEST(comparator, testQuadwordCompare) {
EXPECT_GT(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8)),
0);
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}

View file

@ -38,9 +38,9 @@ int32_t *a, *b, *c;
TEST(djbsort, test4) {
static const int kA[] = {4, 3, 2, 1};
n = ARRAYLEN(kA);
a = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
b = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
c = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
a = memcpy(gc(malloc(n * 4)), kA, n * 4);
b = memcpy(gc(malloc(n * 4)), kA, n * 4);
c = memcpy(gc(malloc(n * 4)), kA, n * 4);
insertionsort(a, n);
djbsort$avx2(b, n);
djbsort(c, n);
@ -65,9 +65,9 @@ TEST(djbsort, test64) {
-1323943608, -1219421355, -582289873, 1062699814,
};
n = ARRAYLEN(kA);
a = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
b = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
c = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
a = memcpy(gc(malloc(n * 4)), kA, n * 4);
b = memcpy(gc(malloc(n * 4)), kA, n * 4);
c = memcpy(gc(malloc(n * 4)), kA, n * 4);
insertionsort(a, n);
djbsort(c, n);
ASSERT_EQ(0, memcmp(a, c, n * 4));

View file

@ -19,6 +19,7 @@
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -29,9 +30,9 @@ TEST(qsort, test) {
const int32_t B[][2] = {{-31, 'd'}, {0, 'e'}, {1, 'j'}, {2, 'c'},
{2, 'g'}, {4, 'a'}, {65, 'b'}, {83, 'h'},
{99, 'f'}, {782, 'i'}};
int32_t(*M)[2] = tmalloc(sizeof(A));
int32_t(*M)[2] = malloc(sizeof(A));
memcpy(M, B, sizeof(A));
qsort(M, ARRAYLEN(A), sizeof(*M), cmpsl);
EXPECT_EQ(0, memcmp(M, B, sizeof(B)));
tfree(M);
free(M);
}

View file

@ -18,6 +18,7 @@
*/
#include "libc/dns/dns.h"
#include "libc/dns/dnsheader.h"
#include "libc/mem/mem.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -28,20 +29,20 @@ TEST(serializednsheader, test) {
header.id = 255;
header.bf1 = true;
header.qdcount = 1;
uint8_t *buf = tmalloc(12);
uint8_t *buf = malloc(12);
ASSERT_EQ(12, serializednsheader(buf, 12, header));
EXPECT_BINEQ(u" λ☺  ☺      ", buf);
tfree(buf);
free(buf);
}
TEST(serializednsheader, fuzzSymmetry) {
uint8_t *buf = tmalloc(12);
struct DnsHeader *in = tmalloc(sizeof(struct DnsHeader));
struct DnsHeader *out = tmalloc(sizeof(struct DnsHeader));
uint8_t *buf = malloc(12);
struct DnsHeader *in = malloc(sizeof(struct DnsHeader));
struct DnsHeader *out = malloc(sizeof(struct DnsHeader));
ASSERT_EQ(12, serializednsheader(buf, 12, *in));
ASSERT_EQ(12, deserializednsheader(out, buf, 12));
ASSERT_EQ(0, memcmp(in, out, 12));
tfree(out);
tfree(in);
tfree(buf);
free(out);
free(in);
free(buf);
}

View file

@ -17,21 +17,22 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dns/dns.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(dnsnamecmp, testEmpty) {
char *A = strcpy(tmalloc(1), "");
char *B = strcpy(tmalloc(1), "");
char *A = strcpy(malloc(1), "");
char *B = strcpy(malloc(1), "");
EXPECT_EQ(dnsnamecmp(A, B), 0);
EXPECT_EQ(dnsnamecmp(A, A), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}
TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) {
char *A = tmalloc(2);
char *B = tmalloc(2);
char *A = malloc(2);
char *B = malloc(2);
EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "a")), 0);
EXPECT_EQ(dnsnamecmp(A, A), 0);
EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "A")), 0);
@ -39,13 +40,13 @@ TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) {
EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "b")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "B")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "d"), strcpy(B, "a")), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}
TEST(dnsnamecmp, testMultiLabel_lexiReverse) {
char *A = tmalloc(16);
char *B = tmalloc(16);
char *A = malloc(16);
char *B = malloc(16);
EXPECT_EQ(dnsnamecmp(strcpy(A, "a.example"), strcpy(B, "a.example")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.example")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.examplz")), 0);
@ -53,48 +54,48 @@ TEST(dnsnamecmp, testMultiLabel_lexiReverse) {
EXPECT_EQ(dnsnamecmp(strcpy(A, "c.a.example"), strcpy(B, "c.a.example")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "d.a.example"), strcpy(B, "c.a.example")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "cat.example"), strcpy(B, "lol.example")), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}
TEST(dnsnamecmp, testTldDotQualifier_canBeEqualToDottedNames) {
char *A = tmalloc(16);
char *B = tmalloc(16);
char *A = malloc(16);
char *B = malloc(16);
EXPECT_EQ(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "aaa.example")), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}
TEST(dnsnamecmp, testFullyQualified_alwaysComesFirst) {
char *A = tmalloc(16);
char *B = tmalloc(16);
char *A = malloc(16);
char *B = malloc(16);
EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "zzz")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example."), strcpy(A, "aaa")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example.")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example.")), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}
TEST(dnsnamecmp, testLikelySld_alwaysComesBeforeLocalName) {
char *A = tmalloc(16);
char *B = tmalloc(16);
char *A = malloc(16);
char *B = malloc(16);
EXPECT_LT(dnsnamecmp(strcpy(B, "z.e"), strcpy(A, "a")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example"), strcpy(A, "zzz")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example"), strcpy(A, "aaa")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example")), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}
TEST(dnsnamecmp, testLikelySubdomain_alwaysComesAfterSld) {
char *A = tmalloc(16);
char *B = tmalloc(16);
char *A = malloc(16);
char *B = malloc(16);
EXPECT_LT(dnsnamecmp(strcpy(B, "a.e"), strcpy(A, "z.a.e")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "z.a.e"), strcpy(B, "a.e")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "b.e"), strcpy(A, "a.b.e")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "a.b.e"), strcpy(B, "b.e")), 0);
tfree(B);
tfree(A);
free(B);
free(A);
}

View file

@ -19,11 +19,12 @@
#include "libc/dns/dns.h"
#include "libc/dns/dnsquestion.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/testlib/testlib.h"
TEST(serializednsquestion, test) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 4);
char *name = tstrdup("foo.bar");
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1 + 4);
char *name = strdup("foo.bar");
struct DnsQuestion dq;
dq.qname = name;
dq.qtype = 0x0201;
@ -31,19 +32,19 @@ TEST(serializednsquestion, test) {
EXPECT_EQ(1 + 3 + 1 + 3 + 1 + 4,
serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 4, dq));
EXPECT_BINEQ(u"♥foo♥bar ☻☺☺☻", buf);
tfree(name);
tfree(buf);
free(name);
free(buf);
}
TEST(serializednsquestion, testNoSpace) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 3);
char *name = tstrdup("foo.bar");
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1 + 3);
char *name = strdup("foo.bar");
struct DnsQuestion dq;
dq.qname = name;
dq.qtype = 0x0201;
dq.qclass = 0x0102;
EXPECT_EQ(-1, serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 3, dq));
EXPECT_EQ(ENOSPC, errno);
tfree(name);
tfree(buf);
free(name);
free(buf);
}

View file

@ -18,61 +18,62 @@
*/
#include "libc/dns/dns.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(pascalifydnsname, testEmpty) {
uint8_t *buf = tmalloc(1);
char *name = tstrdup("");
uint8_t *buf = malloc(1);
char *name = strdup("");
EXPECT_EQ(0, pascalifydnsname(buf, 1, name));
EXPECT_BINEQ(u" ", buf);
tfree(name);
tfree(buf);
free(name);
free(buf);
}
TEST(pascalifydnsname, testOneLabel) {
uint8_t *buf = tmalloc(1 + 3 + 1);
char *name = tstrdup("foo");
uint8_t *buf = malloc(1 + 3 + 1);
char *name = strdup("foo");
EXPECT_EQ(1 + 3, pascalifydnsname(buf, 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo ", buf);
tfree(name);
tfree(buf);
free(name);
free(buf);
}
TEST(pascalifydnsname, testTwoLabels) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
char *name = tstrdup("foo.bar");
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1);
char *name = strdup("foo.bar");
EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo♥bar ", buf);
tfree(name);
tfree(buf);
free(name);
free(buf);
}
TEST(pascalifydnsname, testFqdnDot_isntIncluded) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
char *name = tstrdup("foo.bar.");
uint8_t *buf = malloc(1 + 3 + 1 + 3 + 1);
char *name = strdup("foo.bar.");
EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo♥bar ", buf);
tfree(name);
tfree(buf);
free(name);
free(buf);
}
TEST(pascalifydnsname, testTooLong) {
uint8_t *buf = tmalloc(1);
char *name = tmalloc(1000);
uint8_t *buf = malloc(1);
char *name = malloc(1000);
memset(name, '.', 999);
name[999] = '\0';
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
EXPECT_EQ(ENAMETOOLONG, errno);
tfree(name);
tfree(buf);
free(name);
free(buf);
}
TEST(pascalifydnsname, testNoSpace) {
uint8_t *buf = tmalloc(1);
char *name = tstrdup("foo");
uint8_t *buf = malloc(1);
char *name = strdup("foo");
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
EXPECT_EQ(ENOSPC, errno);
tfree(name);
tfree(buf);
free(name);
free(buf);
}

View file

@ -626,17 +626,17 @@ TEST(xasprintf, twosBane) {
TEST(snprintf, testFixedWidthString_wontOverrunInput) {
const int N = 2;
char *buf = tmalloc(N + 1);
char *inp = memcpy(tmalloc(N), "hi", N);
char *buf = malloc(N + 1);
char *inp = memcpy(malloc(N), "hi", N);
EXPECT_EQ(2, snprintf(buf, N + 1, "%.*s", N, inp));
EXPECT_BINEQ(u"hi ", buf);
tfree(inp);
tfree(buf);
free(inp);
free(buf);
}
TEST(snprintf, testFixedWidthStringIsNull_wontOverrunBuffer) {
int N = 3;
char *buf = tmalloc(N + 1);
char *buf = malloc(N + 1);
EXPECT_EQ(6, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"(nu ", buf);
EXPECT_EQ(6, snprintf(buf, N + 1, "%#.*s", pushpop(N), pushpop(NULL)));
@ -645,12 +645,12 @@ TEST(snprintf, testFixedWidthStringIsNull_wontOverrunBuffer) {
EXPECT_BINEQ(u"NUL ", buf);
EXPECT_EQ(4, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"NUL ", buf);
tfree(buf);
free(buf);
}
TEST(snprintf, testFixedWidthStringIsNull_wontLeakMemory) {
int N = 16;
char *buf = tmalloc(N + 1);
char *buf = malloc(N + 1);
memset(buf, 0, N + 1);
EXPECT_EQ(6, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"(null)           ", buf);
@ -663,7 +663,7 @@ TEST(snprintf, testFixedWidthStringIsNull_wontLeakMemory) {
memset(buf, 0, N + 1);
EXPECT_EQ(4, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"NULL             ", buf);
tfree(buf);
free(buf);
}
TEST(snprintf, twosBaneWithTypePromotion) {

View file

@ -22,7 +22,6 @@ TEST_LIBC_FMT_DIRECTDEPS = \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
LIBC_LOG_ASAN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \

View file

@ -18,6 +18,7 @@
*/
#include "dsp/core/q.h"
#include "libc/intrin/pmulhrsw.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -108,6 +109,15 @@ TEST(pmulhrsw, testFakeFloat) {
} /* clang-format on */;
FOR88(QD[y][x] = F2Q(15, D[y][x]));
FOR88(QM[y][x] = F2Q(15, M[y][x]));
/* for (y = 0; y < 8; ++y) { */
/* for (x = 0; x < 8; ++x) { */
/* CHECK_NE(8, x); */
/* CHECK_NE(8, y); */
/* QM[y][x] = F2Q(15, M[y][x]); */
/* CHECK_NE(8, x); */
/* CHECK_NE(8, y); */
/* } */
/* } */
FOR8(pmulhrsw(QQ[y], QD[y], QM[y]));
FOR88(Q[y][x] = Q2F(15, QQ[y][x]));
FOR88(R[y][x] = D[y][x] * M[y][x]);

View file

@ -52,10 +52,6 @@ o/$(MODE)/test/libc/intrin/%.com.dbg: \
$(APE)
@$(APELINK)
# $(TEST_LIBC_INTRIN_OBJS): \
# OVERRIDE_CFLAGS += \
# -fsanitize=address
.PHONY: o/$(MODE)/test/libc/intrin
o/$(MODE)/test/libc/intrin: \
$(TEST_LIBC_INTRIN_BINS) \

View file

@ -19,6 +19,7 @@
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/log/check.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/kompressor.h"
#include "libc/nexgen32e/lz4.h"
#include "libc/runtime/ezmap.internal.h"
@ -30,13 +31,13 @@ TEST(lz4, decompress_emptyStringWithoutChecksum) {
/* lz4 -9 --content-size --no-frame-crc /tmp/empty - | hexdump -C */
static char kLz4Data[] = {0x04, 0x22, 0x4d, 0x18, 0x60, 0x40,
0x82, 0x00, 0x00, 0x00, 0x00};
char *src = memcpy(tmalloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data));
char *dst = tmalloc(1);
char *src = memcpy(malloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data));
char *dst = malloc(1);
*dst = 'z';
ASSERT_EQ(dst, lz4decode(dst, src));
ASSERT_EQ('z', *dst);
tfree(dst);
tfree(src);
free(dst);
free(src);
}
TEST(lz4, decompress_oneLetterWithoutChecksum) {
@ -45,12 +46,12 @@ TEST(lz4, decompress_oneLetterWithoutChecksum) {
static char kLz4Data[] = {0x04, 0x22, 0x4d, 0x18, 0x68, 0x40, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01,
0x00, 0x00, 0x80, 0x61, 0x00, 0x00, 0x00, 0x00};
char *src = memcpy(tmalloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data));
char *dst = tmalloc(1);
char *src = memcpy(malloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data));
char *dst = malloc(1);
ASSERT_EQ(dst + 1, lz4decode(dst, src));
ASSERT_EQ('a', *dst);
tfree(dst);
tfree(src);
free(dst);
free(src);
}
TEST(lz4, decompress_runLengthDecode) {
@ -60,13 +61,13 @@ TEST(lz4, decompress_runLengthDecode) {
0x04, 0x22, 0x4d, 0x18, 0x68, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x0b, 0x00, 0x00, 0x00, 0x1f, 0x61, 0x01, 0x00, 0x07,
0x50, 0x61, 0x61, 0x61, 0x61, 0x61, 0x00, 0x00, 0x00, 0x00};
char *src = memcpy(tmalloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data));
char *src = memcpy(malloc(sizeof(kLz4Data)), kLz4Data, sizeof(kLz4Data));
const char *want = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
char *dst = tmalloc(strlen(want));
char *dst = malloc(strlen(want));
ASSERT_EQ(dst + strlen(want), lz4decode(dst, src));
ASSERT_STREQN(want, dst, strlen(want));
tfree(dst);
tfree(src);
free(dst);
free(src);
}
TEST(lz4, zoneFileGmt) {

View file

@ -18,6 +18,7 @@
*/
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -30,14 +31,14 @@ char *b1, *b2;
TEST(memmove, overlapping) {
for (i = 0; i < N; i += S) {
for (j = 10; j < N; j += S) {
b1 = tmalloc(N);
b2 = tmalloc(N);
b1 = malloc(N);
b2 = malloc(N);
n = min(N - i, N - j);
memcpy(b2, b1 + i, n);
ASSERT_EQ(b1 + j, memmove(b1 + j, b1 + i, n));
ASSERT_EQ(0, memcmp(b1 + j, b2, n));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}
}
@ -45,14 +46,14 @@ TEST(memmove, overlapping) {
TEST(memmove, overlappingDirect) {
for (i = 0; i < N; i += S) {
for (j = 10; j < N; j += S) {
b1 = tmalloc(N);
b2 = tmalloc(N);
b1 = malloc(N);
b2 = malloc(N);
n = min(N - i, N - j);
memcpy(b2, b1 + i, n);
ASSERT_EQ(b1 + j, (memmove)(b1 + j, b1 + i, n));
ASSERT_EQ(0, memcmp(b1 + j, b2, n));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.h"
#include "libc/testlib/testlib.h"
@ -26,20 +27,20 @@ TEST(memset, size0_doesNothing) {
}
TEST(memset, size1) {
char *b = tgc(tmalloc(1));
char *b = gc(malloc(1));
_memset(b, 7, 1);
EXPECT_EQ(7, b[0]);
}
TEST(memset, size2) {
char *b = tgc(tmalloc(2));
char *b = gc(malloc(2));
_memset(b, 7, 2);
EXPECT_EQ(7, b[0]);
EXPECT_EQ(7, b[1]);
}
TEST(memset, size3) {
char *b = tgc(tmalloc(3));
char *b = gc(malloc(3));
_memset(b, 7, 3);
EXPECT_EQ(7, b[0]);
EXPECT_EQ(7, b[1]);
@ -47,7 +48,7 @@ TEST(memset, size3) {
}
TEST(memset, size4) {
char *b = tgc(tmalloc(4));
char *b = gc(malloc(4));
_memset(b, 7, 4);
EXPECT_EQ(7, b[0]);
EXPECT_EQ(7, b[1]);
@ -56,7 +57,7 @@ TEST(memset, size4) {
}
TEST(memset, size5) {
char *b = tgc(tmalloc(5));
char *b = gc(malloc(5));
_memset(b, 7, 5);
EXPECT_EQ(7, b[0]);
EXPECT_EQ(7, b[1]);
@ -70,7 +71,7 @@ TEST(memset, testMulTrick4) {
unsigned long x;
long di, si, dx, ax;
volatile uint8_t *b;
b = tgc(tmalloc(4));
b = gc(malloc(4));
for (i = 0; i < 255; ++i) {
for (j = -1; j < 1; ++j) {
x = j;
@ -93,7 +94,7 @@ TEST(memset, testMulTrick8) {
unsigned long x;
long di, si, dx, ax;
volatile uint8_t *b;
b = tgc(tmalloc(8));
b = gc(malloc(8));
for (i = 0; i < 255; ++i) {
for (j = -1; j < 1; ++j) {
x = j;

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
@ -23,36 +24,34 @@
#include "libc/testlib/testlib.h"
TEST(strtolower, testAligned) {
EXPECT_STREQ("azcdabcdabcdabcd",
strtolower(tgc(tstrdup("AZCDabcdABCDabcd"))));
EXPECT_STREQ("azcdabcdabcdabcd", strtolower(gc(strdup("AZCDabcdABCDabcd"))));
EXPECT_STREQ("azcdabcdabcdabcdabcdabcdabcdabcd",
strtolower(tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabcd"))));
strtolower(gc(strdup("AZCDabcdABCDabcdABCDabcdABCDabcd"))));
}
TEST(strtolower, testUnaligned) {
EXPECT_STREQ("1", strtolower(tgc(tstrdup("1"))));
EXPECT_STREQ("1", strtolower(gc(strdup("1"))));
EXPECT_STREQ(
"zcdabcdabcdabcdabcdabcdabcdabc",
strtolower((char *)tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabc")) + 1));
strtolower((char *)gc(strdup("AZCDabcdABCDabcdABCDabcdABCDabc")) + 1));
}
TEST(strtoupper, testAligned) {
EXPECT_STREQ("AZCDABCDABCDABCD",
strtoupper(tgc(tstrdup("AZCDabcdABCDabcd"))));
EXPECT_STREQ("AZCDABCDABCDABCD", strtoupper(gc(strdup("AZCDabcdABCDabcd"))));
EXPECT_STREQ("AZCDABCDABCDABCDABCDABCDABCDABCD",
strtoupper(tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabcd"))));
strtoupper(gc(strdup("AZCDabcdABCDabcdABCDabcdABCDabcd"))));
}
TEST(strtoupper, testUnaligned) {
EXPECT_STREQ("1", strtoupper(tgc(tstrdup("1"))));
EXPECT_STREQ("1", strtoupper(gc(strdup("1"))));
EXPECT_STREQ(
"ZCDABCDABCDABCDABCDABCDABCDABC",
strtoupper((char *)tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabc")) + 1));
strtoupper((char *)gc(strdup("AZCDabcdABCDabcdABCDabcdABCDabc")) + 1));
}
BENCH(strtolower, bench) {
size_t size = FRAMESIZE;
char *data = tgc(tmalloc(size));
char *data = gc(malloc(size));
EZBENCH2(
"strtolower",
{

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/mem/mem.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -24,8 +25,8 @@
TEST(devrand, test) {
if (IsWindows()) return;
const size_t kSize = 8;
void *A = tmalloc(kSize);
void *B = tmalloc(kSize);
void *A = malloc(kSize);
void *B = malloc(kSize);
memset(A, 0, kSize);
memset(B, 0, kSize);
EXPECT_EQ(0, devrand(A, kSize));
@ -33,6 +34,6 @@ TEST(devrand, test) {
EXPECT_BINNE(u"        ", A);
EXPECT_BINNE(u"        ", B);
EXPECT_NE(0, memcmp(A, B, kSize));
tfree(B);
tfree(A);
free(B);
free(A);
}

View file

@ -21,6 +21,7 @@ TEST_LIBC_RAND_CHECKS = \
TEST_LIBC_RAND_DIRECTDEPS = \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RAND \
LIBC_RUNTIME \

View file

@ -16,76 +16,77 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/runtime/internal.h"
#include "libc/testlib/testlib.h"
TEST(GetDosArgv, empty) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(0, GetDosArgv(u"", buf, size, argv, max));
EXPECT_EQ(NULL, argv[0]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, emptyish) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(0, GetDosArgv(u" ", buf, size, argv, max));
EXPECT_EQ(NULL, argv[0]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, basicUsage) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(3, GetDosArgv(u"a\t \"b c\" d ", buf, size, argv, max));
EXPECT_STREQ("a", argv[0]);
EXPECT_STREQ("b c", argv[1]);
EXPECT_STREQ("d", argv[2]);
EXPECT_EQ(NULL, argv[3]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, advancedUsage) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(2, GetDosArgv(u"(╯°□°)╯︵ ┻━┻", buf, size, argv, max));
EXPECT_STREQ("(╯°□°)╯︵", argv[0]);
EXPECT_STREQ("┻━┻", argv[1]);
EXPECT_EQ(NULL, argv[2]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, testAegeanGothicSupplementaryPlanes) {
size_t max = 4; /* these symbols are almost as old as dos */
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(2, GetDosArgv(u"𐄷𐄸𐄹𐄺𐄻𐄼 𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", buf, size, argv, max));
EXPECT_STREQ("𐄷𐄸𐄹𐄺𐄻𐄼", argv[0]);
EXPECT_STREQ("𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷", argv[1]);
EXPECT_EQ(NULL, argv[2]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, realWorldUsage) {
size_t max = 512;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(5, GetDosArgv(u"C:\\Users\\jtunn\\printargs.com oh yes yes yes",
buf, size, argv, max));
EXPECT_STREQ("C:\\Users\\jtunn\\printargs.com", argv[0]);
@ -94,21 +95,21 @@ TEST(GetDosArgv, realWorldUsage) {
EXPECT_STREQ("yes", argv[3]);
EXPECT_STREQ("yes", argv[4]);
EXPECT_EQ(NULL, argv[5]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, bufferOverrun_countIsStillAccurate_truncatesMemoryWithGrace) {
size_t max = 3;
size_t size = 7;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(3, GetDosArgv(u"a\t \"b c\" d ", buf, size, argv, max));
EXPECT_STREQ("a", argv[0]);
EXPECT_STREQ("b c", argv[1]);
EXPECT_EQ(NULL, argv[2]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, pureScanningMode) {
@ -121,50 +122,50 @@ TEST(GetDosArgv, pureScanningMode) {
TEST(GetDosArgv, justSlashQuote) {
size_t max = 4, size = 16;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(1, GetDosArgv(u"\"\\\\\\\"\"", buf, size, argv, max));
EXPECT_STREQ("\\\"", argv[0]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, quoteInMiddleOfArg_wontSplitArg) {
size_t max = 4, size = 16;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(1, GetDosArgv(u"hi\"\"there", buf, size, argv, max));
EXPECT_STREQ("hithere", argv[0]);
max = 4, size = 16;
EXPECT_EQ(1, GetDosArgv(u"hi\" \"there", buf, size, argv, max));
EXPECT_STREQ("hi there", argv[0]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, waqQuoting1) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(2,
GetDosArgv(u"a\\\\\"\"\"\"\"\"\"\"b c\" d", buf, size, argv, max));
EXPECT_STREQ("a\\\"\"b", argv[0]);
EXPECT_STREQ("c d", argv[1]);
EXPECT_EQ(NULL, argv[2]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}
TEST(GetDosArgv, waqQuoting2) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
char *buf = malloc(size * sizeof(char));
char **argv = malloc(max * sizeof(char *));
EXPECT_EQ(2, GetDosArgv(u"\"a\\\"b c\" d", buf, size, argv, max));
EXPECT_STREQ("a\"b c", argv[0]);
EXPECT_STREQ("d", argv[1]);
EXPECT_EQ(NULL, argv[2]);
tfree(argv);
tfree(buf);
free(argv);
free(buf);
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/runtime/internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -24,16 +25,16 @@ TEST(GetDosEnviron, testOneVariable) {
#define kEnv u"A=Und wird die Welt auch in Flammen stehen\0"
size_t max = 2;
size_t size = sizeof(kEnv) >> 1;
char *block = tmalloc(size);
char16_t *env = memcpy(tmalloc(sizeof(kEnv)), kEnv, sizeof(kEnv));
char **envp = tmalloc(max * sizeof(char *));
char *block = malloc(size);
char16_t *env = memcpy(malloc(sizeof(kEnv)), kEnv, sizeof(kEnv));
char **envp = malloc(max * sizeof(char *));
EXPECT_EQ(1, GetDosEnviron(env, block, size, envp, max));
EXPECT_STREQ("A=Und wird die Welt auch in Flammen stehen", envp[0]);
EXPECT_EQ(NULL, envp[1]);
ASSERT_BINEQ(u"A=Und wird die Welt auch in Flammen stehen  ", block);
tfree(envp);
tfree(env);
tfree(block);
free(envp);
free(env);
free(block);
#undef kEnv
}
@ -43,16 +44,16 @@ TEST(GetDosEnviron, testTwoVariables) {
u"𐌴𐌵𐌶𐌷=Wir werden wieder auferstehen\0")
size_t max = 3;
size_t size = 1024;
char *block = tmalloc(size);
char16_t *env = memcpy(tmalloc(sizeof(kEnv)), kEnv, sizeof(kEnv));
char **envp = tmalloc(max * sizeof(char *));
char *block = malloc(size);
char16_t *env = memcpy(malloc(sizeof(kEnv)), kEnv, sizeof(kEnv));
char **envp = malloc(max * sizeof(char *));
EXPECT_EQ(2, GetDosEnviron(env, block, size, envp, max));
EXPECT_STREQ("𐌰𐌱𐌲𐌳=Und wird die Welt auch in Flammen stehen", envp[0]);
EXPECT_STREQ("𐌴𐌵𐌶𐌷=Wir werden wieder auferstehen", envp[1]);
EXPECT_EQ(NULL, envp[2]);
tfree(envp);
tfree(env);
tfree(block);
free(envp);
free(env);
free(block);
#undef kEnv
}
@ -60,16 +61,16 @@ TEST(GetDosEnviron, testOverrun_truncatesWithGrace) {
#define kEnv u"A=Und wird die Welt auch in Flammen stehen\0"
size_t max = 2;
size_t size = sizeof(kEnv) >> 2;
char *block = tmalloc(size);
char16_t *env = memcpy(tmalloc(sizeof(kEnv)), kEnv, sizeof(kEnv));
char **envp = tmalloc(max * sizeof(char *));
char *block = malloc(size);
char16_t *env = memcpy(malloc(sizeof(kEnv)), kEnv, sizeof(kEnv));
char **envp = malloc(max * sizeof(char *));
EXPECT_EQ(1, GetDosEnviron(env, block, size, envp, max));
EXPECT_STREQ("A=Und wird die Welt ", envp[0]);
EXPECT_EQ(NULL, envp[1]);
ASSERT_BINEQ(u"A=Und wird die Welt   ", block);
tfree(envp);
tfree(env);
tfree(block);
free(envp);
free(env);
free(block);
#undef kEnv
}
@ -79,24 +80,24 @@ TEST(GetDosEnviron, testEmpty_doesntTouchMemory) {
TEST(GetDosEnviron, testEmpty_zeroTerminatesWheneverPossible_1) {
size_t max = 1;
char **envp = tmalloc(max * sizeof(char *));
char **envp = malloc(max * sizeof(char *));
EXPECT_EQ(0, GetDosEnviron(u"", NULL, 0, envp, max));
EXPECT_EQ(NULL, envp[0]);
tfree(envp);
free(envp);
}
TEST(GetDosEnviron, testEmpty_zeroTerminatesWheneverPossible_2) {
size_t size = 1;
char *block = tmalloc(size);
char *block = malloc(size);
EXPECT_EQ(0, GetDosEnviron(u"", block, size, NULL, 0));
EXPECT_BINEQ(u" ", block);
tfree(block);
free(block);
}
TEST(GetDosEnviron, testEmpty_zeroTerminatesWheneverPossible_3) {
size_t size = 2;
char *block = tmalloc(size);
char *block = malloc(size);
EXPECT_EQ(0, GetDosEnviron(u"", block, size, NULL, 0));
EXPECT_BINEQ(u" ", block);
tfree(block);
free(block);
}

View file

@ -43,7 +43,7 @@ TEST(mmap, testMapFile) {
EXPECT_EQ(5, write(fd, "hello", 5));
EXPECT_NE(-1, fdatasync(fd));
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0)));
EXPECT_STREQ("hello", p);
EXPECT_STREQN("hello", p, 5);
EXPECT_NE(-1, munmap(p, 5));
EXPECT_NE(-1, close(fd));
EXPECT_NE(-1, unlink(path));
@ -59,7 +59,7 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
EXPECT_NE(MAP_FAILED,
(p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
EXPECT_NE(-1, close(fd));
EXPECT_STREQ("hello", p);
EXPECT_STREQN("hello", p, 5);
p[1] = 'a';
EXPECT_NE(-1, msync(p, PAGESIZE, MS_SYNC));
ASSERT_NE(-1, (fd = open(path, O_RDONLY)));

View file

@ -28,7 +28,6 @@ TEST_LIBC_RUNTIME_DIRECTDEPS = \
LIBC_FMT \
LIBC_INTRIN \
LIBC_LOG \
LIBC_LOG_ASAN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RAND \
@ -62,12 +61,6 @@ $(TEST_LIBC_RUNTIME_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
# ifeq (,$(MODE))
# $(TEST_LIBC_RUNTIME_OBJS): \
# OVERRIDE_CFLAGS += \
# -fsanitize=address
# endif
o/$(MODE)/test/libc/runtime/getenv_test.com.runs: \
o/$(MODE)/test/libc/runtime/getenv_test.com
@HELLO=THERE build/runit $@ $<

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
@ -44,12 +45,12 @@ TEST(inet_ntop, testBadFamily) {
}
TEST(inet_ntop, testNoSpace) {
char *buf = memcpy(tmalloc(16), "hi", 3);
char *buf = memcpy(malloc(16), "hi", 3);
uint8_t localhost[4] = {127, 0, 0, 1};
ASSERT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 0));
EXPECT_EQ(ENOSPC, errno);
ASSERT_STREQ("hi", buf);
ASSERT_EQ(NULL, inet_ntop(AF_INET, localhost, buf, 7));
ASSERT_STREQ("", buf);
tfree(buf);
free(buf);
}

View file

@ -26,6 +26,7 @@ TEST_LIBC_SOCK_DIRECTDEPS = \
LIBC_CALLS \
LIBC_FMT \
LIBC_INTRIN \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_SOCK \

View file

@ -16,6 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/rand/rand.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
@ -40,19 +42,30 @@ TEST(memccpy, testZeroLength_doesNothing) {
}
TEST(memccpy, memcpy) {
unsigned n, n2;
unsigned n, n1, n2;
char *b1, *b2, *b3, *e1, *e2;
for (n = 0; n < 1026; ++n) {
b1 = tmalloc(n);
b2 = tmalloc(n);
b3 = tmalloc(n);
b1 = calloc(1, n);
b2 = calloc(1, n);
b3 = calloc(1, n);
rngset(b1, n, rand64, -1);
e1 = tinymemccpy(b2, b1, 31337, n);
e2 = memccpy(b3, b1, 31337, n);
n2 = e1 ? e1 - b1 : n;
ASSERT_EQ(e1, e2);
n1 = e1 ? e1 - b2 : n;
n2 = e2 ? e2 - b3 : n;
ASSERT_LE(n1, n);
ASSERT_LE(n2, n);
ASSERT_EQ(n1, n2,
"n=%ld\r\n\t"
"n1=%8ld e1=%p b2=%p %p\r\n\t"
"n2=%8ld e2=%p b3=%p %p\r\n\t"
"%#.*s\r\n\t"
"%#.*s\r\n\t"
"%#.*s",
n, n1, e1, b2, e1 - b2, n2, e2, b3, e2 - b3, n, b1, n, b2, n, b3);
ASSERT_EQ(0, memcmp(b2, b3, n2));
tfree(b3);
tfree(b2);
tfree(b1);
free(b3);
free(b2);
free(b1);
}
}

View file

@ -24,61 +24,61 @@
TEST(memcpy, memcpy) {
char *b1, *b2;
for (unsigned n = 0; n < 1026; ++n) {
b1 = tmalloc(n);
b2 = tmalloc(n);
b1 = malloc(n);
b2 = malloc(n);
ASSERT_EQ(b1, memcpy(b1, b2, n));
ASSERT_EQ(0, memcmp(b1, b2, n));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}
TEST(memcpy, memcpyDirect) {
char *b1, *b2;
for (unsigned n = 0; n < 1026; ++n) {
b1 = tmalloc(n);
b2 = tmalloc(n);
b1 = malloc(n);
b2 = malloc(n);
ASSERT_EQ(b1, (memcpy)(b1, b2, n));
ASSERT_EQ(0, memcmp(b1, b2, n));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}
TEST(memcpy, mempcpy) {
char *b1, *b2;
for (unsigned n = 0; n < 1026; ++n) {
b1 = tmalloc(n);
b2 = tmalloc(n);
b1 = malloc(n);
b2 = malloc(n);
ASSERT_EQ(b1 + n, mempcpy(b1, b2, n));
ASSERT_EQ(0, memcmp(b1, b2, n));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}
TEST(memcpy, mempcpyDirect) {
char *b1, *b2;
for (unsigned n = 0; n < 1026; ++n) {
b1 = tmalloc(n);
b2 = tmalloc(n);
b1 = malloc(n);
b2 = malloc(n);
ASSERT_EQ(b1 + n, (mempcpy)(b1, b2, n));
ASSERT_EQ(0, memcmp(b1, b2, n));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}
TEST(memcpy, overlapping_isFineIfCopyingBackwards) {
for (size_t i = 0; i < 32; ++i) {
char *b1 = tmalloc(64 + i);
char *b2 = tmalloc(64 + i);
char *b1 = malloc(64 + i);
char *b2 = malloc(64 + i);
memcpy(b1, b2, 64);
memcpy(b1, b1 + i, 64 - i);
memmove(b2, b2 + i, 64 - i);
ASSERT_EQ(0, memcmp(b1, b2, 64));
tfree(b2);
tfree(b1);
free(b2);
free(b1);
}
}

View file

@ -18,6 +18,7 @@
*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/str/internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -27,7 +28,7 @@ FIXTURE(memmem, tiny) {
memmemi = tinymemmem;
}
#define MakeMemory(SL) memcpy(tmalloc(sizeof(SL) - 1), SL, sizeof(SL) - 1)
#define MakeMemory(SL) memcpy(malloc(sizeof(SL) - 1), SL, sizeof(SL) - 1)
TEST(memmem, test) {
char *needle = MakeMemory("abcdefgh");
@ -36,40 +37,40 @@ TEST(memmem, test) {
memcpy(needle, "aaaaaaaa", 8);
memcpy(haystk, "acccccccbbbbbbbbaaaaaaaadddddddd", 32);
EXPECT_BINEQ(u"aaaaaaaadddddddd", memmemi(haystk, 32, needle, 8));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testNoMatch) {
char *needle = MakeMemory("abcdefzh");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_EQ(NULL, memmemi(haystk, 32, needle, 8));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testStartOfMemory) {
char *needle = MakeMemory("acccc");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_EQ(&haystk[0], memmemi(haystk, 32, needle, 5));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testEndOfMemory) {
char *needle = MakeMemory("123");
char *haystk = MakeMemory("abc123");
EXPECT_EQ(&haystk[3], memmemi(haystk, 6, needle, 3));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testCrossesSseRegister) {
char *needle = MakeMemory("eeeeeeeeeeeeefffffffffffff");
char *haystk = MakeMemory("eeeeeeeeeeeeeeeeffffffffffffffffrrrrrrrrrrrrrrrr");
EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testHasNulCharacters) {
@ -77,39 +78,39 @@ TEST(memmem, testHasNulCharacters) {
char *haystk =
MakeMemory("eeeeeeeeeeeeeeee\0fffffffffffffffrrrrrrrrrrrrrrrr");
EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testWeird) {
char *needle = MakeMemory("-*-+-+-+-+-+-+-+");
char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+");
EXPECT_EQ(14, (intptr_t)memmemi(haystk, 32, needle, 16) - (intptr_t)haystk);
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testEmptyNeedle_matchesStartOfHaystack) {
char *needle = tmalloc(0);
char *needle = malloc(0);
char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+");
EXPECT_EQ(0, (intptr_t)memmemi(haystk, 32, needle, 0) - (intptr_t)haystk);
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testEmptyHaystack_alwaysReturnsNull) {
char *needle = MakeMemory("-*-+-+-+-+-+-+-+");
char *haystk = tmalloc(0);
char *haystk = malloc(0);
EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 16));
EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 1));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}
TEST(memmem, testEmptyHaystackAndNeedle_returnsHaystack) {
char *needle = tmalloc(0);
char *haystk = tmalloc(0);
char *needle = malloc(0);
char *haystk = malloc(0);
EXPECT_EQ(haystk, memmemi(haystk, 0, needle, 0));
tfree(haystk);
tfree(needle);
free(haystk);
free(needle);
}

View file

@ -17,6 +17,7 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/str/oldutf16.internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
@ -34,38 +35,38 @@ TEST(pututf16, testEmpty) {
TEST(pututf16, testNul) {
size = 1;
buf = tmalloc(size * sizeof(char16_t));
buf = malloc(size * sizeof(char16_t));
EXPECT_EQ(1, pututf16(buf, size, u'\0', false));
EXPECT_EQ(u'\0', buf[0]);
buf[0] = '\7';
EXPECT_EQ(1, (pututf16)(buf, size, u'\0', false));
EXPECT_EQ(u'\0', buf[0]);
tfree(buf);
free(buf);
}
TEST(pututf16, testAscii) {
size = 1;
buf = tmalloc(size * sizeof(char16_t));
buf = malloc(size * sizeof(char16_t));
EXPECT_EQ(1, pututf16(buf, size, u'j', false));
EXPECT_EQ(u'j', buf[0]);
EXPECT_EQ(1, (pututf16)(buf, size, u't', false));
EXPECT_EQ(u't', buf[0]);
tfree(buf);
free(buf);
}
TEST(pututf16, testGothicSupplementaryPlane) {
size = 2;
buf = tmalloc(size * sizeof(char16_t));
buf = malloc(size * sizeof(char16_t));
EXPECT_EQ(2, pututf16(buf, size, L'𐌰', false));
EXPECT_STREQN(u"𐌰", buf, 1);
EXPECT_EQ(2, (pututf16)(buf, size, L'𐌱', false));
EXPECT_STREQN(u"𐌱", buf, 1);
tfree(buf);
free(buf);
}
TEST(pututf16, testEmojiAndEmojiPresentationModifier_areBothInAstralPlanes) {
n = 8;
b = tgc(tmalloc(sizeof(char16_t) * n));
b = gc(malloc(sizeof(char16_t) * n));
str = L"\U0001F466\U0001F3FF";
memset(b, 0, n * sizeof(char16_t));
EXPECT_EQ(2, pututf16(b, n, str[0], false));

View file

@ -19,9 +19,11 @@
#include "libc/bits/bits.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/cachesize.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
@ -64,27 +66,27 @@ TEST(wcscasecmp, emptyString) {
}
TEST(strncmp, emptyString) {
char *s1 = strcpy(tmalloc(1), "");
char *s2 = strcpy(tmalloc(1), "");
char *s1 = strcpy(malloc(1), "");
char *s2 = strcpy(malloc(1), "");
ASSERT_EQ(0, strncmp(s1, s2, 0));
ASSERT_EQ(0, strncmp(s1, s2, 1));
ASSERT_EQ(0, strncmp(s1, s2, -1));
ASSERT_EQ(0, strncmp(s1, s1, -1));
ASSERT_EQ(0, strncmp(s2, s2, -1));
tfree(s2);
tfree(s1);
free(s2);
free(s1);
}
TEST(strncasecmp, emptyString) {
char *s1 = strcpy(tmalloc(1), "");
char *s2 = strcpy(tmalloc(1), "");
char *s1 = strcpy(malloc(1), "");
char *s2 = strcpy(malloc(1), "");
ASSERT_EQ(0, strncasecmp(s1, s2, 0));
ASSERT_EQ(0, strncasecmp(s1, s2, 1));
ASSERT_EQ(0, strncasecmp(s1, s2, -1));
ASSERT_EQ(0, strncasecmp(s1, s1, -1));
ASSERT_EQ(0, strncasecmp(s2, s2, -1));
tfree(s2);
tfree(s1);
free(s2);
free(s1);
}
/*───────────────────────────────────────────────────────────────────────────│─╗
@ -92,13 +94,13 @@ TEST(strncasecmp, emptyString) {
*/
TEST(strncmp, testInequality) {
char *s1 = strcpy(tmalloc(2), "1");
char *s2 = strcpy(tmalloc(1), "");
char *s1 = strcpy(malloc(2), "1");
char *s2 = strcpy(malloc(1), "");
ASSERT_EQ(0, strncmp(s1, s2, 0));
ASSERT_EQ('1', strncmp(s1, s2, 1));
ASSERT_EQ(-'1', strncmp(s2, s1, 1));
tfree(s2);
tfree(s1);
free(s2);
free(s1);
}
/*───────────────────────────────────────────────────────────────────────────│─╗
@ -318,8 +320,8 @@ TEST(strcasecmp8to16, testItWorksCase) {
*/
TEST(strncmp, testEqualManyNs) {
char *s1 = tmalloc(PAGESIZE);
char *s2 = tmalloc(PAGESIZE);
char *s1 = malloc(PAGESIZE);
char *s2 = malloc(PAGESIZE);
memset(s1, 7, PAGESIZE);
memset(s2, 7, PAGESIZE);
s1[PAGESIZE - 1] = '\0';
@ -328,13 +330,13 @@ TEST(strncmp, testEqualManyNs) {
ASSERT_EQ(0, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 0));
ASSERT_EQ(0, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 1));
}
tfree(s2);
tfree(s1);
free(s2);
free(s1);
}
TEST(strncmp, testNotEqualManyNs) {
char *s1 = tmalloc(PAGESIZE);
char *s2 = tmalloc(PAGESIZE);
char *s1 = malloc(PAGESIZE);
char *s2 = malloc(PAGESIZE);
for (unsigned i = 1; i <= 128; ++i) {
memset(s1, 7, PAGESIZE);
memset(s2, 7, PAGESIZE);
@ -343,8 +345,8 @@ TEST(strncmp, testNotEqualManyNs) {
ASSERT_EQ(-255, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 0));
ASSERT_EQ(-255, strncmp(s1 + PAGESIZE - i, s2 + PAGESIZE - i, i + 1));
}
tfree(s2);
tfree(s1);
free(s2);
free(s1);
}
/*───────────────────────────────────────────────────────────────────────────│─╗
@ -354,40 +356,40 @@ TEST(strncmp, testNotEqualManyNs) {
TEST(strncmp, testStringNulTerminatesBeforeExplicitLength) {
const char kRdi[] = "";
const char kRsi[] = "TZ=America/Los_Angeles";
char *rdi = memcpy(tmalloc(sizeof(kRdi)), kRdi, sizeof(kRdi));
char *rsi = memcpy(tmalloc(sizeof(kRsi)), kRsi, sizeof(kRsi));
char *rdi = memcpy(malloc(sizeof(kRdi)), kRdi, sizeof(kRdi));
char *rsi = memcpy(malloc(sizeof(kRsi)), kRsi, sizeof(kRsi));
size_t rdx = 3;
EXPECT_EQ(strncmp(rdi, rdi, rdx), 0);
EXPECT_LT(strncmp(rdi, rsi, rdx), 0);
EXPECT_GT(strncmp(rsi, rdi, rdx), 0);
tfree(rsi);
tfree(rdi);
free(rsi);
free(rdi);
}
TEST(strncasecmp, testStringNulTerminatesBeforeExplicitLength) {
const char kRdi[] = "";
const char kRsi[] = "TZ=America/Los_Angeles";
char *rdi = memcpy(tmalloc(sizeof(kRdi)), kRdi, sizeof(kRdi));
char *rsi = memcpy(tmalloc(sizeof(kRsi)), kRsi, sizeof(kRsi));
char *rdi = memcpy(malloc(sizeof(kRdi)), kRdi, sizeof(kRdi));
char *rsi = memcpy(malloc(sizeof(kRsi)), kRsi, sizeof(kRsi));
size_t rdx = 3;
EXPECT_EQ(strncasecmp(rdi, rdi, rdx), 0);
EXPECT_LT(strncasecmp(rdi, rsi, rdx), 0);
EXPECT_GT(strncasecmp(rsi, rdi, rdx), 0);
tfree(rsi);
tfree(rdi);
free(rsi);
free(rdi);
}
TEST(strncmp16, testStringNulTerminatesBeforeExplicitLength) {
const char16_t kRdi[] = u"";
const char16_t kRsi[] = u"TZ=America/Los_Angeles";
char16_t *rdi = memcpy(tmalloc(sizeof(kRdi)), kRdi, sizeof(kRdi));
char16_t *rsi = memcpy(tmalloc(sizeof(kRsi)), kRsi, sizeof(kRsi));
char16_t *rdi = memcpy(malloc(sizeof(kRdi)), kRdi, sizeof(kRdi));
char16_t *rsi = memcpy(malloc(sizeof(kRsi)), kRsi, sizeof(kRsi));
size_t rdx = 3;
EXPECT_EQ(strncmp16(rdi, rdi, rdx), 0);
EXPECT_LT(strncmp16(rdi, rsi, rdx), 0);
EXPECT_GT(strncmp16(rsi, rdi, rdx), 0);
tfree(rsi);
tfree(rdi);
free(rsi);
free(rdi);
}
/*───────────────────────────────────────────────────────────────────────────│─╗
@ -422,33 +424,33 @@ TEST(memcmp, testTwosComplementBane_unsignedBehavior) {
}
TEST(strcmp16, testTwosComplementBane_hasUnsignedBehavior) {
char16_t *B1 = tmalloc(8);
char16_t *B2 = tmalloc(8);
char16_t *B1 = malloc(8);
char16_t *B2 = malloc(8);
B1[1] = L'\0';
B2[1] = L'\0';
EXPECT_EQ(strcmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\x00\x80", 2)), 0);
EXPECT_LT(strcmp16(memcpy(B1, "\xff\x7f", 2), memcpy(B2, "\x00\x80", 2)), 0);
EXPECT_GT(strcmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\xff\x7f", 2)), 0);
tfree(B2);
tfree(B1);
free(B2);
free(B1);
}
TEST(strncmp16, testTwosComplementBane_hasUnsignedBehavior) {
char16_t *B1 = tmalloc(4);
char16_t *B2 = tmalloc(4);
char16_t *B1 = malloc(4);
char16_t *B2 = malloc(4);
EXPECT_EQ(strncmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\x00\x80", 2), 1),
0);
EXPECT_LT(strncmp16(memcpy(B1, "\xff\x7f", 2), memcpy(B2, "\x00\x80", 2), 1),
0);
EXPECT_GT(strncmp16(memcpy(B1, "\x00\x80", 2), memcpy(B2, "\xff\x7f", 2), 1),
0);
tfree(B2);
tfree(B1);
free(B2);
free(B1);
}
TEST(wcscmp, testTwosComplementBane) {
wchar_t *B1 = tmalloc(8);
wchar_t *B2 = tmalloc(8);
wchar_t *B1 = malloc(8);
wchar_t *B2 = malloc(8);
B1[1] = L'\0';
B2[1] = L'\0';
EXPECT_EQ(wcscmp(memcpy(B1, "\x00\x00\x00\x80", 4),
@ -459,13 +461,13 @@ TEST(wcscmp, testTwosComplementBane) {
EXPECT_EQ(wcscmp(memcpy(B1, "\x00\x00\x00\x80", 4),
memcpy(B2, "\xff\xff\xff\x7f", 4)),
1);
tfree(B2);
tfree(B1);
free(B2);
free(B1);
}
TEST(wcsncmp, testTwosComplementBane) {
wchar_t *B1 = tmalloc(4);
wchar_t *B2 = tmalloc(4);
wchar_t *B1 = malloc(4);
wchar_t *B2 = malloc(4);
EXPECT_EQ(wcsncmp(memcpy(B1, "\x00\x00\x00\x80", 4),
memcpy(B2, "\x00\x00\x00\x80", 4), 1),
0);
@ -475,8 +477,8 @@ TEST(wcsncmp, testTwosComplementBane) {
EXPECT_EQ(wcsncmp(memcpy(B1, "\x00\x00\x00\x80", 4),
memcpy(B2, "\xff\xff\xff\x7f", 4), 1),
1);
tfree(B2);
tfree(B1);
free(B2);
free(B1);
}
/*───────────────────────────────────────────────────────────────────────────│─╗
@ -530,8 +532,8 @@ BENCH(bench_00_strcmp, bench) {
char *dupe, *data;
size = ROUNDDOWN(MAX(FRAMESIZE, getcachesize(kCpuCacheTypeData, 1)) / 2,
PAGESIZE);
data = tgc(tmalloc(size));
dupe = tgc(tmalloc(size));
data = gc(malloc(size));
dupe = gc(malloc(size));
fprintf(stderr, "\n");
EZBENCH2("strcmp [identity]", longstringislong(size, data),
@ -579,8 +581,8 @@ BENCH(bench_01_strcasecmp, bench) {
char *dupe, *data;
size = ROUNDDOWN(MAX(FRAMESIZE, getcachesize(kCpuCacheTypeData, 1)) / 2,
PAGESIZE);
data = tgc(tmalloc(size));
dupe = tgc(tmalloc(size));
data = gc(malloc(size));
dupe = gc(malloc(size));
fprintf(stderr, "\n");
EZBENCH2("strcasecmp [identity]", longstringislong(size, data),

View file

@ -18,7 +18,9 @@
*/
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/tinystrlen.internal.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
@ -88,10 +90,10 @@ TEST(strnlen_s, null_ReturnsZero) {
TEST(strnlen, nulNotFound_ReturnsSize) {
int sizes[] = {1, 2, 7, 8, 15, 16, 31, 32, 33};
for (unsigned i = 0; i < ARRAYLEN(sizes); ++i) {
char *buf = tmalloc(sizes[i]);
char *buf = malloc(sizes[i]);
memset(buf, ' ', sizes[i]);
ASSERT_EQ(sizes[i], strnlen(buf, sizes[i]), "%d", sizes[i]);
tfree(buf);
free(buf);
}
}
@ -134,15 +136,38 @@ TEST(tinystrnlen16, test) {
EXPECT_EQ(3, tinystrnlen16(u"123", 4));
}
TEST(strlen, fuzz) {
char *b;
size_t n, n1, n2;
for (n = 2; n < 1026; ++n) {
b = rngset(calloc(1, n), n - 1, rand64, -1);
n1 = strlen(b);
n2 = strlen$pure(b);
ASSERT_EQ(n1, n2);
n1 = strlen(b + 1);
n2 = strlen$pure(b + 1);
ASSERT_EQ(n1, n2);
free(b);
}
}
BENCH(strlen, bench) {
extern size_t strlen_(const char *) asm("strlen");
extern size_t strlen$pure_(const char *) asm("strlen$pure");
static char b[2048];
memset(b, -1, sizeof(b) - 1);
EZBENCH2("strlen 1", donothing, strlen_(""));
EZBENCH2("strlen$pure 1", donothing, strlen$pure_(""));
EZBENCH2("strlen 2", donothing, strlen_("1"));
EZBENCH2("strlen$pure 2", donothing, strlen$pure_("1"));
EZBENCH2("strlen 7", donothing, strlen_("123456"));
EZBENCH2("strlen$pure 7", donothing, strlen$pure_("123456"));
EZBENCH2("strlen 8", donothing, strlen_("1234567"));
EZBENCH2("strlen$pure 8", donothing, strlen$pure_("1234567"));
EZBENCH2("strlen 9", donothing, strlen_("12345678"));
EZBENCH2("strlen$pure 9", donothing, strlen$pure_("12345678"));
EZBENCH2("strlen 16", donothing, strlen_("123456781234567"));
EZBENCH2("strlen$pure 16", donothing, strlen$pure_("123456781234567"));
EZBENCH2("strlen 1023", donothing, strlen_(b));
EZBENCH2("strlen$pure 1023", donothing, strlen$pure_(b));
}

View file

@ -26,7 +26,7 @@
#include "libc/testlib/testlib.h"
#define MAKESTRING(NAME, VALUE) \
char *NAME = strcpy(tmalloc(sizeof(VALUE) + 16), VALUE)
char *NAME = strcpy(malloc(sizeof(VALUE) + 16), VALUE)
char *strstr$kmp(const char *haystak, const char *needle) {
return memmem(haystak, strlen(haystak), needle, strlen(needle));
@ -44,40 +44,40 @@ TEST(strstr, test_emptyString_isFoundAtBeginning) {
MAKESTRING(haystack, "abc123def");
ASSERT_STREQ(&haystack[0], strstri(haystack, gc(strdup(""))));
ASSERT_STREQ(&haystack[0], strstr(haystack, gc(strdup(""))));
tfree(haystack);
free(haystack);
}
TEST(strstr, test_notFound) {
MAKESTRING(haystack, "abc123def");
ASSERT_EQ(NULL, strstri(haystack, gc(strdup("xyz"))));
ASSERT_EQ(NULL, strstr(haystack, gc(strdup("xyz"))));
tfree(haystack);
free(haystack);
}
TEST(strstr, test_middleOfString) {
MAKESTRING(haystack, "abc123def");
ASSERT_STREQ(&haystack[3], strstri(haystack, gc(strdup("123"))));
ASSERT_STREQ(&haystack[3], strstr(haystack, gc(strdup("123"))));
tfree(haystack);
free(haystack);
}
TEST(strstr, test_endOfString) {
MAKESTRING(haystack, "abc123def");
ASSERT_STREQ(&haystack[8], strstri(haystack, gc(strdup("f"))));
ASSERT_STREQ(&haystack[8], strstr(haystack, gc(strdup("f"))));
tfree(haystack);
free(haystack);
}
TEST(strstr, test_secondXmmWord) {
MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbb123");
ASSERT_STREQ(&haystack[27], strstri(haystack, gc(strdup("123"))));
ASSERT_STREQ(&haystack[27], strstr(haystack, gc(strdup("123"))));
tfree(haystack);
free(haystack);
}
TEST(strstr, test_overlapsXmmWords) {
MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbbbbbb");
ASSERT_STREQ(&haystack[15], strstri(haystack, gc(strdup("eb"))));
ASSERT_STREQ(&haystack[15], strstr(haystack, gc(strdup("eb"))));
tfree(haystack);
free(haystack);
}

View file

@ -16,49 +16,50 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(strtok_r, testEmpty) {
static const char *const kInput = "";
static const char *const kSeparators = "/";
char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput);
char *s = strcpy(malloc(strlen(kInput) + 1), kInput);
char *state;
EXPECT_EQ(NULL, strtok_r(s, kSeparators, &state));
tfree(s);
free(s);
}
TEST(strtok_r, test) {
static const char *const kInput = ".,lol..cat..";
static const char *const kSeparators = ".,";
char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput);
char *s = strcpy(malloc(strlen(kInput) + 1), kInput);
char *state;
EXPECT_STREQ("lol", strtok_r(s, kSeparators, &state));
EXPECT_STREQ("cat", strtok_r(NULL, kSeparators, &state));
EXPECT_EQ(NULL, strtok_r(NULL, kSeparators, &state));
EXPECT_EQ(NULL, strtok_r(NULL, kSeparators, &state));
tfree(s);
free(s);
}
TEST(strtok, test) {
static const char *const kInput = ".,lol..cat..";
static const char *const kSeparators = ".,";
char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput);
char *s = strcpy(malloc(strlen(kInput) + 1), kInput);
EXPECT_STREQ("lol", strtok(s, kSeparators));
EXPECT_STREQ("cat", strtok(NULL, kSeparators));
EXPECT_EQ(NULL, strtok(NULL, kSeparators));
EXPECT_EQ(NULL, strtok(NULL, kSeparators));
tfree(s);
free(s);
}
TEST(strtok_r, testHostsTxtLine) {
static const char *const kInput = "203.0.113.1 lol.example. lol";
static const char *const kSeparators = " \t";
char *s = strcpy(tmalloc(strlen(kInput) + 1), kInput);
char *s = strcpy(malloc(strlen(kInput) + 1), kInput);
char *state;
EXPECT_STREQ("203.0.113.1", strtok_r(s, kSeparators, &state));
EXPECT_STREQ("lol.example.", strtok_r(NULL, kSeparators, &state));
EXPECT_STREQ("lol", strtok_r(NULL, kSeparators, &state));
EXPECT_EQ(NULL, strtok_r(NULL, kSeparators, &state));
tfree(s);
free(s);
}

View file

@ -47,11 +47,11 @@ TEST(tprecode16to8, testTooLittle_stillNulTerminates) {
TEST(tprecode16to8, testAscii_vectorSpeedupWorks) {
size_t size = 32;
char *buf = tmalloc(size);
char *buf = malloc(size);
EXPECT_EQ(31,
tprecode16to8(buf, size, u"babaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").ax);
EXPECT_STREQ("babaaaaaaaaaaaaaaaaaaaaaaaaaaaa", buf);
tfree(buf);
free(buf);
}
BENCH(tprecode16to8, bench) {

View file

@ -25,10 +25,10 @@
TEST(tprecode8to16, test) {
size_t size = 8;
char16_t *buf = tmalloc(size * sizeof(char16_t));
char16_t *buf = malloc(size * sizeof(char16_t));
EXPECT_EQ(7, tprecode8to16(buf, size, "hello☻♥").ax);
EXPECT_STREQ(u"hello☻♥", buf);
tfree(buf);
free(buf);
}
TEST(tprecode8to16, testEmptyOut_doesNothingButStillCountsSrcLength) {
@ -65,11 +65,11 @@ TEST(tprecode8to16, test2) {
TEST(tprecode8to16, testAscii_vectorSpeedupWorks) {
size_t size = 32;
char16_t *buf = tmalloc(size * sizeof(char16_t));
char16_t *buf = malloc(size * sizeof(char16_t));
EXPECT_EQ(31,
tprecode8to16(buf, size, "babaaaaaaaaaaaaaaaaaaaaaaaaaaaaa").ax);
EXPECT_STREQ(u"babaaaaaaaaaaaaaaaaaaaaaaaaaaaa", buf);
tfree(buf);
free(buf);
}
BENCH(tprecode8to16, bench) {

View file

@ -16,65 +16,14 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/mem/mem.h"
#include "libc/math.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
/* TODO(jart): calling malloc_usable_size was a terrible idea */
TEST(todo_jart, broken_in_opt_native_mode) {
(void)0;
(void)0;
}
int64_t fd;
TEST(gc, usageExample_c11) {
fd = open("/dev/null", O_WRONLY);
defer(close_s, &fd);
char *msg = gc(xasprintf("%d + %d = %d", 2, 2, 2 + 2));
write(fd, msg, strlen(msg));
}
TEST(gc, checkMallocUsableSizeWorksTheWayWeHopeItDoes) {
char *p = malloc(32);
EXPECT_GE(malloc_usable_size(p), 32);
free(p);
EXPECT_GE(malloc_usable_size(p), 0);
}
noinline void function1of1(char *p) {
EXPECT_GE(malloc_usable_size(gc(p)), 32);
}
TEST(gc, testOne) {
char *p = malloc(32);
function1of1(p);
EXPECT_EQ(malloc_usable_size(p), 0);
}
noinline void function2of2(char *p1, char *p2) {
EXPECT_GE(malloc_usable_size(p1), 32);
EXPECT_GE(malloc_usable_size(p2), 64);
gc(p2);
EXPECT_GE(malloc_usable_size(p1), 32);
EXPECT_GE(malloc_usable_size(p2), 64);
}
noinline void function1of2(char *p1, char *p2) {
EXPECT_GE(malloc_usable_size(p1), 32);
EXPECT_GE(malloc_usable_size(p2), 64);
function2of2(gc(p1), p2);
EXPECT_GE(malloc_usable_size(p1), 32);
EXPECT_GE(malloc_usable_size(p2), 0);
}
TEST(gc, testTwo) {
char *p1 = malloc(32);
char *p2 = malloc(64);
function1of2(p1, p2);
EXPECT_GE(malloc_usable_size(p1), 0);
EXPECT_GE(malloc_usable_size(p2), 0);
TEST(exp, test) {
ASSERT_STREQ("7.389056", gc(xasprintf("%f", exp(2.0))));
ASSERT_STREQ("6.389056", gc(xasprintf("%f", expm1(2.0))));
ASSERT_STREQ("6.389056", gc(xasprintf("%f", exp(2.0) - 1.0)));
}

View file

@ -0,0 +1,29 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/math.h"
#include "libc/testlib/testlib.h"
TEST(ilogb, test) {
/* TODO(jart): this */
/* EXPECT_EQ(0x7fffffff, ilogb(INFINITY)); */
EXPECT_EQ(0, ilogb(1));
EXPECT_EQ(1, ilogb(2));
EXPECT_EQ(2, ilogb(4));
EXPECT_EQ(63, ilogb(1e19));
}

View file

@ -19,7 +19,6 @@
#include "libc/limits.h"
#include "libc/math.h"
#include "libc/testlib/testlib.h"
#include "libc/tinymath/tinymath.h"
TEST(ilogb, yolo) {
EXPECT_EQ(0, ilogb(1));

View file

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/math.h"
#include "libc/testlib/testlib.h"
TEST(pow10, testLdbl) {
EXPECT_LDBL_EQ(1, pow10l(0));
EXPECT_LDBL_EQ(10, pow10l(1));
EXPECT_LDBL_EQ(100, pow10l(2));
}
TEST(pow10, testDouble) {
EXPECT_DOUBLE_EQ(1, pow10(0));
EXPECT_DOUBLE_EQ(10, pow10(1));
EXPECT_DOUBLE_EQ(100, pow10(2));
}
TEST(pow10, testFloat) {
EXPECT_FLOAT_EQ(1, pow10f(0));
EXPECT_FLOAT_EQ(10, pow10f(1));
EXPECT_FLOAT_EQ(100, pow10f(2));
}

View file

@ -20,35 +20,31 @@
#include "libc/runtime/gc.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
#include "libc/tinymath/tinymath.h"
#include "libc/x/x.h"
TEST(powl, testLongDouble) {
/* .4248496805467504836322459796959084815827285786480897 */
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(powl(0.7, 2.4))));
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(tinymath_powl(0.7, 2.4))));
}
TEST(powl, testDouble) {
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(pow(0.7, 2.4))));
EXPECT_STARTSWITH(".4248496805467504", gc(xdtoa(tinymath_pow(0.7, 2.4))));
}
TEST(powl, testFloat) {
EXPECT_STARTSWITH(".4248496", gc(xdtoa(powf(0.7f, 2.4f))));
EXPECT_STARTSWITH(".4248496", gc(xdtoa(tinymath_powf(0.7f, 2.4f))));
}
static long double do_powl(void) {
return CONCEAL("t", tinymath_powl(CONCEAL("t", 0.7), CONCEAL("t", 0.2)));
return CONCEAL("t", powl(CONCEAL("t", 0.7), CONCEAL("t", 0.2)));
}
static double do_pow(void) {
return CONCEAL("x", tinymath_pow(CONCEAL("x", 0.7), CONCEAL("x", 0.2)));
return CONCEAL("x", pow(CONCEAL("x", 0.7), CONCEAL("x", 0.2)));
}
static float do_powf(void) {
return CONCEAL("x", tinymath_powf(CONCEAL("x", 0.7f), CONCEAL("x", 0.2f)));
return CONCEAL("x", powf(CONCEAL("x", 0.7f), CONCEAL("x", 0.2f)));
}
BENCH(powl, bench) {

View file

@ -21,167 +21,163 @@
#include "libc/runtime/gc.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/tinymath/tinymath.h"
#include "libc/x/x.h"
float tinymath_roundf$k8(float);
double tinymath_round$k8(double);
FIXTURE(intrin, disableHardwareExtensions) {
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
}
TEST(round, testCornerCases) {
EXPECT_STREQ("-0", gc(xdtoa(tinymath_round(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(tinymath_round(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_round(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_round(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_round(-INFINITY))));
EXPECT_STREQ("-0", gc(xdtoa(round(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(round(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(round(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(round(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(round(-INFINITY))));
}
TEST(roundl, testCornerCases) {
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundl(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(tinymath_roundl(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_roundl(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_roundl(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_roundl(-INFINITY))));
EXPECT_STREQ("-0", gc(xdtoa(roundl(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(roundl(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(roundl(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(roundl(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(roundl(-INFINITY))));
}
TEST(round, test) {
EXPECT_STREQ("-3", gc(xdtoa(tinymath_round(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_round(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(tinymath_round(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_round(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_round(.4))));
EXPECT_STREQ("1", gc(xdtoa(tinymath_round(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_round(1.5))));
EXPECT_STREQ("3", gc(xdtoa(tinymath_round(2.5))));
EXPECT_STREQ("-3", gc(xdtoa(round(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(round(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(round(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(round(-.4))));
EXPECT_STREQ("0", gc(xdtoa(round(.4))));
EXPECT_STREQ("1", gc(xdtoa(round(.5))));
EXPECT_STREQ("2", gc(xdtoa(round(1.5))));
EXPECT_STREQ("3", gc(xdtoa(round(2.5))));
}
TEST(roundf, test) {
EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundf(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundf(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundf(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_roundf(.4))));
EXPECT_STREQ("1", gc(xdtoa(tinymath_roundf(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_roundf(1.5))));
EXPECT_STREQ("3", gc(xdtoa(tinymath_roundf(2.5))));
EXPECT_STREQ("-3", gc(xdtoa(roundf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(roundf(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(roundf(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(roundf(-.4))));
EXPECT_STREQ("0", gc(xdtoa(roundf(.4))));
EXPECT_STREQ("1", gc(xdtoa(roundf(.5))));
EXPECT_STREQ("2", gc(xdtoa(roundf(1.5))));
EXPECT_STREQ("3", gc(xdtoa(roundf(2.5))));
}
TEST(roundl, test) {
EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundl(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundl(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundl(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundl(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_roundl(.4))));
EXPECT_STREQ("1", gc(xdtoa(tinymath_roundl(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_roundl(1.5))));
EXPECT_STREQ("3", gc(xdtoa(tinymath_roundl(2.5))));
EXPECT_STREQ("-3", gc(xdtoa(roundl(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(roundl(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(roundl(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(roundl(-.4))));
EXPECT_STREQ("0", gc(xdtoa(roundl(.4))));
EXPECT_STREQ("1", gc(xdtoa(roundl(.5))));
EXPECT_STREQ("2", gc(xdtoa(roundl(1.5))));
EXPECT_STREQ("3", gc(xdtoa(roundl(2.5))));
}
TEST(nearbyint, test) {
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyint(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyint(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyint(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyint(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyint(.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyint(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyint(1.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyint(2.5))));
EXPECT_STREQ("-2", gc(xdtoa(nearbyint(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(nearbyint(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(nearbyint(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(nearbyint(-.4))));
EXPECT_STREQ("0", gc(xdtoa(nearbyint(.4))));
EXPECT_STREQ("0", gc(xdtoa(nearbyint(.5))));
EXPECT_STREQ("2", gc(xdtoa(nearbyint(1.5))));
EXPECT_STREQ("2", gc(xdtoa(nearbyint(2.5))));
}
TEST(nearbyintf, test) {
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintf(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintf(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintf(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintf(.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintf(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintf(1.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintf(2.5))));
EXPECT_STREQ("-2", gc(xdtoa(nearbyintf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(nearbyintf(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(nearbyintf(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(nearbyintf(-.4))));
EXPECT_STREQ("0", gc(xdtoa(nearbyintf(.4))));
EXPECT_STREQ("0", gc(xdtoa(nearbyintf(.5))));
EXPECT_STREQ("2", gc(xdtoa(nearbyintf(1.5))));
EXPECT_STREQ("2", gc(xdtoa(nearbyintf(2.5))));
}
TEST(nearbyintl, test) {
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintl(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintl(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintl(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintl(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintl(.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintl(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintl(1.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintl(2.5))));
EXPECT_STREQ("-2", gc(xdtoa(nearbyintl(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(nearbyintl(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(nearbyintl(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(nearbyintl(-.4))));
EXPECT_STREQ("0", gc(xdtoa(nearbyintl(.4))));
EXPECT_STREQ("0", gc(xdtoa(nearbyintl(.5))));
EXPECT_STREQ("2", gc(xdtoa(nearbyintl(1.5))));
EXPECT_STREQ("2", gc(xdtoa(nearbyintl(2.5))));
}
TEST(rint, test) {
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rint(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rint(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rint(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rint(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_rint(.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_rint(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_rint(1.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_rint(2.5))));
EXPECT_STREQ("-2", gc(xdtoa(rint(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(rint(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(rint(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(rint(-.4))));
EXPECT_STREQ("0", gc(xdtoa(rint(.4))));
EXPECT_STREQ("0", gc(xdtoa(rint(.5))));
EXPECT_STREQ("2", gc(xdtoa(rint(1.5))));
EXPECT_STREQ("2", gc(xdtoa(rint(2.5))));
}
TEST(rintf, test) {
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintf(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintf(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintf(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintf(.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintf(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintf(1.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintf(2.5))));
EXPECT_STREQ("-2", gc(xdtoa(rintf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(rintf(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(rintf(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(rintf(-.4))));
EXPECT_STREQ("0", gc(xdtoa(rintf(.4))));
EXPECT_STREQ("0", gc(xdtoa(rintf(.5))));
EXPECT_STREQ("2", gc(xdtoa(rintf(1.5))));
EXPECT_STREQ("2", gc(xdtoa(rintf(2.5))));
}
TEST(rintl, test) {
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintl(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintl(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintl(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintl(-.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintl(.4))));
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintl(.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintl(1.5))));
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintl(2.5))));
EXPECT_STREQ("-2", gc(xdtoa(rintl(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(rintl(-1.5))));
EXPECT_STREQ("-0", gc(xdtoa(rintl(-.5))));
EXPECT_STREQ("-0", gc(xdtoa(rintl(-.4))));
EXPECT_STREQ("0", gc(xdtoa(rintl(.4))));
EXPECT_STREQ("0", gc(xdtoa(rintl(.5))));
EXPECT_STREQ("2", gc(xdtoa(rintl(1.5))));
EXPECT_STREQ("2", gc(xdtoa(rintl(2.5))));
}
TEST(roundf, testCornerCases) {
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundf(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(tinymath_roundf(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(tinymath_roundf(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(tinymath_roundf(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(tinymath_roundf(-INFINITY))));
EXPECT_STREQ("-0", gc(xdtoa(roundf(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(roundf(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(roundf(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(roundf(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(roundf(-INFINITY))));
}
TEST(lroundf, test) {
EXPECT_EQ(-3, tinymath_lroundf(-2.5));
EXPECT_EQ(-2, tinymath_lroundf(-1.5));
EXPECT_EQ(-1, tinymath_lroundf(-.5));
EXPECT_EQ(0, tinymath_lroundf(-.0));
EXPECT_EQ(1, tinymath_lroundf(.5));
EXPECT_EQ(2, tinymath_lroundf(1.5));
EXPECT_EQ(3, tinymath_lroundf(2.5));
EXPECT_EQ(-3, lroundf(-2.5));
EXPECT_EQ(-2, lroundf(-1.5));
EXPECT_EQ(-1, lroundf(-.5));
EXPECT_EQ(0, lroundf(-.0));
EXPECT_EQ(1, lroundf(.5));
EXPECT_EQ(2, lroundf(1.5));
EXPECT_EQ(3, lroundf(2.5));
}
TEST(lround, test) {
EXPECT_EQ(-3, tinymath_lround(-2.5));
EXPECT_EQ(-2, tinymath_lround(-1.5));
EXPECT_EQ(-1, tinymath_lround(-.5));
EXPECT_EQ(-0, tinymath_lround(-.4));
EXPECT_EQ(0, tinymath_lround(.4));
EXPECT_EQ(1, tinymath_lround(.5));
EXPECT_EQ(2, tinymath_lround(1.5));
EXPECT_EQ(3, tinymath_lround(2.5));
EXPECT_EQ(-3, lround(-2.5));
EXPECT_EQ(-2, lround(-1.5));
EXPECT_EQ(-1, lround(-.5));
EXPECT_EQ(-0, lround(-.4));
EXPECT_EQ(0, lround(.4));
EXPECT_EQ(1, lround(.5));
EXPECT_EQ(2, lround(1.5));
EXPECT_EQ(3, lround(2.5));
}
TEST(lroundl, test) {
EXPECT_EQ(-3, tinymath_lroundl(-2.5));
EXPECT_EQ(-2, tinymath_lroundl(-1.5));
EXPECT_EQ(-1, tinymath_lroundl(-.5));
EXPECT_EQ(-0, tinymath_lroundl(-.4));
EXPECT_EQ(0, tinymath_lroundl(.4));
EXPECT_EQ(1, tinymath_lroundl(.5));
EXPECT_EQ(2, tinymath_lroundl(1.5));
EXPECT_EQ(3, tinymath_lroundl(2.5));
EXPECT_EQ(-3, lroundl(-2.5));
EXPECT_EQ(-2, lroundl(-1.5));
EXPECT_EQ(-1, lroundl(-.5));
EXPECT_EQ(-0, lroundl(-.4));
EXPECT_EQ(0, lroundl(.4));
EXPECT_EQ(1, lroundl(.5));
EXPECT_EQ(2, lroundl(1.5));
EXPECT_EQ(3, lroundl(2.5));
}

View file

@ -50,8 +50,8 @@ o/$(MODE)/test/libc/tinymath/%.com.dbg: \
@$(APELINK)
$(TEST_LIBC_TINYMATH_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/tinymath
o/$(MODE)/test/libc/tinymath: \