Initial import

This commit is contained in:
Justine Tunney
2020-06-15 07:18:57 -07:00
commit c91b3c5006
14915 changed files with 590219 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/alg/arraylist.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
struct string {
size_t i, n;
char *p;
};
struct string16 {
size_t i, n;
char16_t *p;
};
struct ArrayListInteger {
size_t i, n;
int *p;
};
TEST(append, worksGreatForScalars) {
char c = 'a';
struct string s;
memset(&s, 0, sizeof(s));
for (size_t i = 0; i < 1024; ++i) ASSERT_EQ(i, append(&s, &c));
ASSERT_EQ(1024, s.i);
for (size_t i = 0; i < s.i; ++i) ASSERT_EQ('a', s.p[i]);
free_s(&s.p);
}
TEST(append, isGenericallyTyped) {
int c = 0x31337;
struct ArrayListInteger s;
memset(&s, 0, sizeof(s));
for (size_t i = 0; i < 1024; ++i) ASSERT_EQ(i, append(&s, &c));
ASSERT_EQ(1024, s.i);
ASSERT_GT(malloc_usable_size(s.p), 1024 * sizeof(int));
for (size_t i = 0; i < s.i; ++i) ASSERT_EQ(0x31337, s.p[i]);
free_s(&s.p);
}
TEST(concat, worksGreatForStrings) {
const char *ks =
"Und wird die Welt auch in Flammen stehen\n"
"Wir werden wieder auferstehen\n";
struct string s;
memset(&s, 0, sizeof(s));
ASSERT_EQ(0, concat(&s, ks, strlen(ks)));
ASSERT_EQ(strlen(ks), concat(&s, ks, strlen(ks) + 1));
ASSERT_STREQ(
"Und wird die Welt auch in Flammen stehen\n"
"Wir werden wieder auferstehen\n"
"Und wird die Welt auch in Flammen stehen\n"
"Wir werden wieder auferstehen\n",
s.p);
ASSERT_EQ(strlen(ks) * 2 + 1, s.i);
free_s(&s.p);
}
TEST(concat, isGenericallyTyped) {
const char16_t *ks =
u"Drum hoch die Fäuste, hoch zum Licht.\n"
u"Unsere schwarzen Seelen bekommt ihr nicht.\n";
struct string16 s;
memset(&s, 0, sizeof(s));
ASSERT_EQ(0, concat(&s, ks, strlen16(ks)));
ASSERT_EQ(strlen16(ks), concat(&s, ks, strlen16(ks) + 1));
ASSERT_STREQ(
u"Drum hoch die Fäuste, hoch zum Licht.\n"
u"Unsere schwarzen Seelen bekommt ihr nicht.\n"
u"Drum hoch die Fäuste, hoch zum Licht.\n"
u"Unsere schwarzen Seelen bekommt ihr nicht.\n",
s.p);
ASSERT_EQ(strlen16(ks) * 2 + 1, s.i);
free_s(&s.p);
}

View File

@@ -0,0 +1,58 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/alg/bisectcarleft.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h"
TEST(bisectcarleft, testEmpty) {
const int32_t cells[][2] = {};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123));
}
TEST(bisectcarleft, testOneEntry) {
const int32_t cells[][2] = {{123, 31337}};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 122));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 124));
}
TEST(bisectcarleft, testNegativity_usesSignedBehavior) {
const int32_t cells[][2] = {{-2, 31337}};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -3));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -2));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -1));
}
TEST(bisectcarleft, testMultipleEntries) {
const int32_t cells[][2] = {{00, 0}, {11, 0}, {20, 0}, {33, 0}, {40, 0},
{50, 0}, {60, 0}, {70, 0}, {80, 0}, {90, 0}};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 10));
EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 11));
EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 12));
EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 19));
EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 20));
EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 21));
EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 32));
EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 33));
EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 34));
}

View File

@@ -0,0 +1,110 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(comparator, testByteCompare) {
char *b1 = tmalloc(1);
char *b2 = tmalloc(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);
EXPECT_GT(cmpsb(memcpy(b1, "z", 1), memcpy(b2, "a", 1)), 0);
EXPECT_EQ(cmpub(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0);
EXPECT_LT(cmpub(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0);
EXPECT_GT(cmpub(memcpy(b1, "z", 1), memcpy(b2, "a", 1)), 0);
/* sign matters */
EXPECT_EQ(cmpsb(memcpy(b1, "\xf0", 1), memcpy(b2, "\xf0", 1)), 0);
EXPECT_LT(cmpsb(memcpy(b1, "\xf0", 1), memcpy(b2, "\x10", 1)), 0);
EXPECT_GT(cmpsb(memcpy(b1, "\x10", 1), memcpy(b2, "\xf0", 1)), 0);
EXPECT_EQ(cmpub(memcpy(b1, "\xf0", 1), memcpy(b2, "\xf0", 1)), 0);
EXPECT_GT(cmpub(memcpy(b1, "\xf0", 1), memcpy(b2, "\x10", 1)), 0);
EXPECT_LT(cmpub(memcpy(b1, "\x10", 1), memcpy(b2, "\xf0", 1)), 0);
/* 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);
}
TEST(comparator, testWordCompare) {
char *b1 = tmalloc(2);
char *b2 = tmalloc(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);
}
TEST(comparator, testDoublewordCompare) {
char *b1 = tmalloc(4);
char *b2 = tmalloc(4);
EXPECT_EQ(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_GT(cmpsl(memcpy(b1, "\x00\x00\x00\x7f", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_LT(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x7f", 4)),
0);
EXPECT_EQ(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_LT(cmpul(memcpy(b1, "\x00\x00\x00\x7f", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_GT(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x7f", 4)),
0);
tfree(b2);
tfree(b1);
}
TEST(comparator, testQuadwordCompare) {
char *b1 = tmalloc(8);
char *b2 = tmalloc(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);
EXPECT_GT(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
EXPECT_LT(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8)),
0);
EXPECT_EQ(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
EXPECT_LT(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
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);
}

View File

@@ -0,0 +1,125 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
struct Bog {
unsigned i;
unsigned n;
const char *p[];
};
static testonly nodiscard struct Bog *NewBog(unsigned n) {
struct Bog *res = malloc(sizeof(struct Bog) + sizeof(const char *) * n);
res->i = 0;
res->n = n;
return res;
}
static testonly void ClearBog(struct Bog *bog) { bog->i = 0; }
static testonly void FreeBog(struct Bog **bog) { free(*bog), *bog = NULL; }
static const char *const elems[] = {"a", "aa", "aaz", "abz",
"bba", "bbc", "bbd", NULL};
testonly static void MakeTree(struct critbit0 *tree) {
memset(tree, 0, sizeof(*tree));
for (unsigned i = 0; elems[i]; ++i) {
ASSERT_EQ(true, critbit0_insert(tree, elems[i]));
}
}
TEST(critbit0, testContains) {
struct critbit0 tree[1];
MakeTree(tree);
for (unsigned i = 0; elems[i]; ++i) {
if (!critbit0_contains(tree, elems[i])) abort();
}
critbit0_clear(tree);
}
static const char *const elems2[] = {"a", "aa", "b", "bb", "ab",
"ba", "aba", "bab", NULL};
TEST(critbit0, testDelete) {
struct critbit0 tree = {0};
for (unsigned i = 1; elems2[i]; ++i) {
critbit0_clear(&tree);
for (unsigned j = 0; j < i; ++j) critbit0_insert(&tree, elems2[j]);
for (unsigned j = 0; j < i; ++j) {
if (!critbit0_contains(&tree, elems2[j])) abort();
}
for (unsigned j = 0; j < i; ++j) {
if (1 != critbit0_delete(&tree, elems2[j])) abort();
}
for (unsigned j = 0; j < i; ++j) {
if (critbit0_contains(&tree, elems2[j])) abort();
}
}
critbit0_clear(&tree);
}
static testonly intptr_t allprefixed_cb(const char *elem, void *arg) {
struct Bog *bog = arg;
ASSERT_LT(bog->i, bog->n);
bog->p[bog->i++] = elem;
return 0;
}
TEST(critbit0, testAllPrefixed) {
struct critbit0 tree[1];
MakeTree(tree);
struct Bog *a = NewBog(4);
ASSERT_EQ(0, critbit0_allprefixed(tree, "a", allprefixed_cb, a));
ASSERT_EQ(4, a->i);
ASSERT_STREQ("a", a->p[0]);
ASSERT_STREQ("aa", a->p[1]);
ASSERT_STREQ("aaz", a->p[2]);
ASSERT_STREQ("abz", a->p[3]);
ClearBog(a);
ASSERT_EQ(0, critbit0_allprefixed(tree, "aa", allprefixed_cb, a));
ASSERT_EQ(2, a->i);
ASSERT_STREQ("aa", a->p[0]);
ASSERT_STREQ("aaz", a->p[1]);
critbit0_clear(tree);
FreeBog(&a);
}
static testonly intptr_t allprefixed_cb_halt(const char *elem, void *arg) {
struct Bog *bog = arg;
ASSERT_LT(bog->i, bog->n);
bog->p[bog->i++] = elem;
return strcmp(elem, "aa") == 0 ? 123 : 0;
}
TEST(critbit0, testAllPrefixed_haltOnNonzero) {
struct critbit0 tree[1];
MakeTree(tree);
struct Bog *a = NewBog(4);
ASSERT_EQ(123, critbit0_allprefixed(tree, "a", allprefixed_cb_halt, a));
ASSERT_EQ(2, a->i);
ASSERT_STREQ("a", a->p[0]);
ASSERT_STREQ("aa", a->p[1]);
critbit0_clear(tree);
FreeBog(&a);
}

View File

@@ -0,0 +1,87 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/limits.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.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"
#include "libc/testlib/testlib.h"
void djbsort$avx2(int32_t *, long);
size_t n;
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);
insertionsort(n, a);
djbsort$avx2(b, n);
djbsort(n, c);
ASSERT_EQ(0, memcmp(a, b, n * 4));
ASSERT_EQ(0, memcmp(a, c, n * 4));
}
TEST(djbsort, test64) {
static const int kA[64] = {
-578159677, -506496753, 627992389, -1352456426, -632122174,
-1439460768, -1910607416, INT_MAX, 828129452, 388318786,
1361377655, 178046, -250539006, -933303681, 553663398,
801377571, 1798551167, 1926219590, 1322300030, 2005832294,
190425814, 1896617905, -549032465, -930529122, 953163359,
-1290004523, 447201234, 1351982281, 458539920, 791518325,
-1086386708, 291355635, INT_MIN, -1891018285, 1780601656,
1324222158, 1182663010, -1223576562, -676035738, 1367175631,
-1016599422, 1619595549, -783089669, -663931695, -1082674213,
1369114774, -1944970907, 196888289, 1400094001, -1170906601,
835635598, 1506409902, -1528765785, 1132926680, -351522751,
-1737707221, -209740191, -1857759507, -353087096, 763588876,
-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);
insertionsort(n, a);
djbsort(n, c);
ASSERT_EQ(0, memcmp(a, c, n * 4));
if (X86_HAVE(AVX2)) {
djbsort$avx2(b, n);
ASSERT_EQ(0, memcmp(a, b, n * 4));
}
}
BENCH(djbsort, bench) {
n = 256;
a = gc(memalign(32, n * 4));
EZBENCH2("insertionsort[255]", rngset(a, n * 4, rand64, -1),
insertionsort(n, a));
EZBENCH2("djbsort[255]", rngset(a, n * 4, rand64, -1), djbsort(n, a));
}

116
test/libc/alg/memmem_test.c Normal file
View File

@@ -0,0 +1,116 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/str/internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
void *(*memmemi)(const void *, size_t, const void *, size_t) = memmem;
FIXTURE(memmem, tiny) {
memmemi = tinymemmem;
}
#define MakeMemory(SL) memcpy(tmalloc(sizeof(SL) - 1), SL, sizeof(SL) - 1)
TEST(memmem, test) {
char *needle = MakeMemory("abcdefgh");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_BINEQ(u"abcdefghdddddddd", memmemi(haystk, 32, needle, 8));
memcpy(needle, "aaaaaaaa", 8);
memcpy(haystk, "acccccccbbbbbbbbaaaaaaaadddddddd", 32);
EXPECT_BINEQ(u"aaaaaaaadddddddd", memmemi(haystk, 32, needle, 8));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testNoMatch) {
char *needle = MakeMemory("abcdefzh");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_EQ(NULL, memmemi(haystk, 32, needle, 8));
tfree(haystk);
tfree(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);
}
TEST(memmem, testEndOfMemory) {
char *needle = MakeMemory("123");
char *haystk = MakeMemory("abc123");
EXPECT_EQ(&haystk[3], memmemi(haystk, 6, needle, 3));
tfree(haystk);
tfree(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);
}
TEST(memmem, testHasNulCharacters) {
char *needle = MakeMemory("eeeeeeeeeeeee\0ffffffffffff");
char *haystk =
MakeMemory("eeeeeeeeeeeeeeee\0fffffffffffffffrrrrrrrrrrrrrrrr");
EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26));
tfree(haystk);
tfree(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);
}
TEST(memmem, testEmptyNeedle_matchesStartOfHaystack) {
char *needle = tmalloc(0);
char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+");
EXPECT_EQ(0, (intptr_t)memmemi(haystk, 32, needle, 0) - (intptr_t)haystk);
tfree(haystk);
tfree(needle);
}
TEST(memmem, testEmptyHaystack_alwaysReturnsNull) {
char *needle = MakeMemory("-*-+-+-+-+-+-+-+");
char *haystk = tmalloc(0);
EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 16));
EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 1));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testEmptyHaystackAndNeedle_returnsHaystack) {
char *needle = tmalloc(0);
char *haystk = tmalloc(0);
EXPECT_EQ(haystk, memmemi(haystk, 0, needle, 0));
tfree(haystk);
tfree(needle);
}

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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(qsort, test) {
const int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'},
{0, 'e'}, {99, 'f'}, {2, 'g'}, {83, 'h'},
{782, 'i'}, {1, 'j'}};
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));
memcpy(M, B, sizeof(A));
qsort(M, ARRAYLEN(A), sizeof(*M), cmpsl);
EXPECT_EQ(0, memcmp(M, B, sizeof(B)));
tfree(M);
}

View File

@@ -0,0 +1,40 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/errno.h"
#include "libc/testlib/testlib.h"
#define S(x) x
#define REPLACESTR replacestr
#include "test/libc/alg/replacestr_test.inc"
#undef REPLACESTR
#undef S
#define S(x) u##x
#define REPLACESTR replacestr16
#include "test/libc/alg/replacestr_test.inc"
#undef REPLACESTR
#undef S
/* #define S(x) L##x */
/* #define REPLACESTR replacewcs */
/* #include "test/libc/alg/replacestr_test.inc" */
/* #undef REPLACESTR */
/* #undef S */

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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
TEST(REPLACESTR, demo) {
EXPECT_STREQ(S("hello friends"),
replacestr(S("hello world"), S("world"), S("friends")));
EXPECT_STREQ(S("bbbbbbbb"), replacestr(S("aaaa"), S("a"), S("bb")));
}
TEST(REPLACESTR, emptyString) {
EXPECT_STREQ(S(""), replacestr(S(""), S("x"), S("y")));
}
TEST(REPLACESTR, emptyNeedle) {
EXPECT_EQ(NULL, replacestr(S("a"), S(""), S("a")));
EXPECT_EQ(EINVAL, errno);
}
TEST(REPLACESTR, needleInReplacement_doesntExplode) {
EXPECT_STREQ(S("xxxxxxx"), replacestr(S("x"), S("x"), S("xxxxxxx")));
}

View File

@@ -0,0 +1,40 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/reverse.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/testlib/testlib.h"
TEST(reverse, test) {
/* this test gets DCE'd :) */
int A[3] = {1, 2, 3};
reverse(A, ARRAYLEN(A));
EXPECT_EQ(3, A[0]);
EXPECT_EQ(2, A[1]);
EXPECT_EQ(1, A[2]);
}
TEST(reverse, testEmpty) {
int A[3] = {1, 2, 3};
reverse(A, 0);
EXPECT_EQ(1, A[0]);
EXPECT_EQ(2, A[1]);
EXPECT_EQ(3, A[2]);
}

View File

@@ -0,0 +1,84 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/dce.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/gc.h"
#include "libc/str/internal.h"
#include "libc/testlib/testlib.h"
#define MAKESTRING(NAME, VALUE) \
char *NAME = strcpy(tmalloc(sizeof(VALUE) + 16), VALUE)
char *strstr$kmp(const char *haystak, const char *needle) {
return memmem(haystak, strlen(haystak), needle, strlen(needle));
}
char *(*strstri)(const char *, const char *) = strstr$kmp;
FIXTURE(strstr, sse42) {
if (X86_HAVE(SSE4_2)) {
strstri = strstr$sse42;
}
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}

126
test/libc/alg/tarjan_test.c Normal file
View File

@@ -0,0 +1,126 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/macros.h"
#include "libc/testlib/testlib.h"
STATIC_YOINK("realloc");
TEST(tarjan, empty_doesNothing) {
uint32_t sorted_vertices[1] = {-1u};
uint32_t edges[][2] = {{0, 0}};
uint32_t vertex_count = 0;
uint32_t edge_count = 0;
tarjan(vertex_count, (void *)edges, edge_count, sorted_vertices, NULL, NULL);
ASSERT_EQ(-1u, sorted_vertices[0]);
}
TEST(tarjan, topologicalSort_noCycles) {
enum VertexIndex { A = 0, B = 1, C = 2, D = 3 };
const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"};
uint32_t edges[][2] = {
{A /* depends on → */, B /* which must come before A */},
{A /* depends on → */, C /* which must come before A */},
{A /* depends on → */, D /* which must come before A */},
{B /* depends on → */, C /* which must come before B */},
{B /* depends on → */, D /* which must come before B */}};
/*
$ tsort <<EOF
B A
C A
D A
C B
D B
EOF
C
D
B
A
*/
uint32_t sorted[4], components[4], componentcount;
ASSERT_EQ(0, tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
sorted, components, &componentcount));
EXPECT_EQ(C, sorted[0]);
EXPECT_EQ(D, sorted[1]);
EXPECT_EQ(B, sorted[2]);
EXPECT_EQ(A, sorted[3]);
ASSERT_EQ(4, componentcount);
EXPECT_EQ(1, components[0]);
EXPECT_EQ(2, components[1]);
EXPECT_EQ(3, components[2]);
EXPECT_EQ(4, components[3]);
}
TEST(tarjan, testOneBigCycle_isDetected_weDontCareAboutOrderInsideTheCycle) {
enum VertexIndex { A = 0, B = 1, C = 2, D = 3 };
const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"};
/* ┌─────────┐
└→A→B→C→D─┘ */
uint32_t edges[][2] = {
{A /* depends on → */, B /* which must come before A */},
{B /* depends on → */, C /* which must come before B */},
{C /* depends on → */, D /* which must come before C */},
{D /* depends on → */, A /* which must come before D */}};
uint32_t sorted[4], components[4], componentcount;
ASSERT_EQ(0, tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
sorted, components, &componentcount));
ASSERT_EQ(1, componentcount);
EXPECT_EQ(4, components[0]);
}
TEST(tarjan, testHeaders) {
enum Headers {
LIBC_STR_STR,
LIBC_BITS_BITS,
LIBC_INTEGRAL,
LIBC_KEYWORDS,
LIBC_DCE,
LIBC_MACROS,
LIBC_MACROS_CPP,
};
const char *const vertices[] = {
[LIBC_STR_STR] = "libc/str/str.h",
[LIBC_BITS_BITS] = "libc/bits/bits.h",
[LIBC_INTEGRAL] = "libc/integral.h",
[LIBC_KEYWORDS] = "libc/keywords.h",
[LIBC_DCE] = "libc/dce.h",
[LIBC_MACROS] = "libc/macros.h",
[LIBC_MACROS_CPP] = "libc/macros-cpp.inc",
};
uint32_t edges[][2] = {
{LIBC_STR_STR, LIBC_BITS_BITS}, {LIBC_STR_STR, LIBC_INTEGRAL},
{LIBC_STR_STR, LIBC_KEYWORDS}, {LIBC_BITS_BITS, LIBC_DCE},
{LIBC_BITS_BITS, LIBC_INTEGRAL}, {LIBC_BITS_BITS, LIBC_KEYWORDS},
{LIBC_BITS_BITS, LIBC_MACROS}, {LIBC_MACROS, LIBC_MACROS_CPP},
};
uint32_t sorted[ARRAYLEN(vertices)];
uint32_t components[ARRAYLEN(vertices)];
uint32_t componentcount;
ASSERT_EQ(0, tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
sorted, components, &componentcount));
ASSERT_EQ(ARRAYLEN(vertices), componentcount);
EXPECT_STREQ("libc/dce.h", vertices[sorted[0]]);
EXPECT_STREQ("libc/integral.h", vertices[sorted[1]]);
EXPECT_STREQ("libc/keywords.h", vertices[sorted[2]]);
EXPECT_STREQ("libc/macros-cpp.inc", vertices[sorted[3]]);
EXPECT_STREQ("libc/macros.h", vertices[sorted[4]]);
EXPECT_STREQ("libc/bits/bits.h", vertices[sorted[5]]);
EXPECT_STREQ("libc/str/str.h", vertices[sorted[6]]);
}

63
test/libc/alg/test.mk Normal file
View File

@@ -0,0 +1,63 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_ALG
TEST_LIBC_ALG_SRCS := $(wildcard test/libc/alg/*.c)
TEST_LIBC_ALG_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_ALG_SRCS))
TEST_LIBC_ALG_COMS = $(TEST_LIBC_ALG_OBJS:%.o=%.com)
TEST_LIBC_ALG_BINS = $(TEST_LIBC_ALG_COMS) $(TEST_LIBC_ALG_COMS:%=%.dbg)
TEST_LIBC_ALG_OBJS = \
$(TEST_LIBC_ALG_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_ALG_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_ALG_TESTS = $(TEST_LIBC_ALG_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_ALG_CHECKS = \
$(TEST_LIBC_ALG_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_ALG_DIRECTDEPS = \
LIBC_ALG \
LIBC_RAND \
LIBC_LOG \
LIBC_STDIO \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X
TEST_LIBC_ALG_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_ALG_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/alg/alg.pkg: \
$(TEST_LIBC_ALG_OBJS) \
$(foreach x,$(TEST_LIBC_ALG_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/alg/%.com.dbg: \
$(TEST_LIBC_ALG_DEPS) \
o/$(MODE)/test/libc/alg/%.o \
o/$(MODE)/test/libc/alg/alg.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_ALG_OBJS): \
$(BUILD_FILES) \
test/libc/alg/test.mk
$(TEST_LIBC_ALG_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/alg
o/$(MODE)/test/libc/alg: \
$(TEST_LIBC_ALG_BINS) \
$(TEST_LIBC_ALG_CHECKS)

View File

@@ -0,0 +1,46 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(bitreverse, test) {
EXPECT_EQ(0xde, bitreverse8(123));
EXPECT_EQ(0xde, (bitreverse8)(123));
EXPECT_EQ(0xde00, bitreverse16(123));
EXPECT_EQ(0xde00, (bitreverse16)(123));
EXPECT_EQ(0xde000000u, bitreverse32(123));
EXPECT_EQ(0xde000000u, (bitreverse32)(123));
}
BENCH(bitreverse, bench) {
EZBENCH2("bitreverse8 mac", donothing,
EXPROPRIATE(bitreverse8(CONCEAL("r", 123))));
EZBENCH2("bitreverse8 fun", donothing,
EXPROPRIATE((bitreverse8)(CONCEAL("r", 123))));
EZBENCH2("bitreverse16 mac", donothing,
EXPROPRIATE(bitreverse16(CONCEAL("r", 123))));
EZBENCH2("bitreverse16 fun", donothing,
EXPROPRIATE((bitreverse16)(CONCEAL("r", 123))));
EZBENCH2("bitreverse32 mac", donothing,
EXPROPRIATE(bitreverse32(CONCEAL("r", 123))));
EZBENCH2("bitreverse32 fun", donothing,
EXPROPRIATE((bitreverse32)(CONCEAL("r", (123)))));
}

66
test/libc/bits/bt_test.c Normal file
View File

@@ -0,0 +1,66 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/testlib/testlib.h"
TEST(bt_uint16x4, test) {
uint16_t v[4] = {0};
EXPECT_FALSE(bt(v, 0));
EXPECT_FALSE(bt(v, 63));
EXPECT_FALSE(bts(v, 63));
EXPECT_TRUE(bt(v, 63));
EXPECT_TRUE(bts(v, 63));
}
TEST(bt_uint32x2, test) {
uint32_t v[2] = {0};
EXPECT_FALSE(bt(v, 0));
EXPECT_FALSE(bt(v, 63));
EXPECT_FALSE(bts(v, 63));
EXPECT_TRUE(bt(v, 63));
EXPECT_TRUE(bts(v, 63));
}
TEST(bt_uint64x1, test) {
uint64_t v = 0;
EXPECT_FALSE(bt(&v, 0));
EXPECT_FALSE(bt(&v, 63));
EXPECT_FALSE(bts(&v, 63));
EXPECT_TRUE(bt(&v, 63));
EXPECT_TRUE(bts(&v, 63));
}
TEST(bt_uint64, testPresent) {
uint64_t v = 1;
EXPECT_TRUE(bt(&v, 0));
EXPECT_FALSE(bt(&v, 63));
v = 0x8000000000000001;
EXPECT_TRUE(bt(&v, 0));
EXPECT_TRUE(bt(&v, 63));
}
TEST(bt_uint64, testPresent_avoidingDeadCodeElimination) {
volatile uint64_t v = 1;
EXPECT_TRUE(bt(&v, 0));
EXPECT_FALSE(bt(&v, 63));
v = 0x8000000000000001;
EXPECT_TRUE(bt(&v, 0));
EXPECT_TRUE(bt(&v, 63));
}

View File

@@ -0,0 +1,50 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/testlib/testlib.h"
TEST(TwosComplementBane, LiteralsThatAreLiterallyTheSameNumber) {
EXPECT_EQ(4, sizeof(INT_MIN));
EXPECT_EQ(8, sizeof(-2147483648));
EXPECT_TRUE(TYPE_SIGNED(-2147483648));
EXPECT_FALSE(TYPE_SIGNED(0x80000000));
EXPECT_FALSE(TYPE_SIGNED(-0x80000000));
}
TEST(ShiftArithmeticRight, DeclassifiedByGuySteele) {
EXPECT_EQ(-1u, SAR(-2u, 1u));
EXPECT_EQ(-1u, SAR(-1u, 1u));
EXPECT_EQ(0xc0000000u, SAR(0x80000000u, 1u));
}
TEST(RotateRight, Test) {
EXPECT_EQ(0x41122334u, ROR(0x11223344u, 4));
EXPECT_EQ(0x44112233u, ROR(0x11223344u, 8));
EXPECT_EQ(0x34411223u, ROR(0x11223344u, 12));
EXPECT_EQ(0x33441122u, ROR(0x11223344u, 16));
}
TEST(RotateLeft, Test) {
EXPECT_EQ(0x12233441u, ROL(0x11223344u, 4));
EXPECT_EQ(0x22334411u, ROL(0x11223344u, 8));
EXPECT_EQ(0x23344112u, ROL(0x11223344u, 12));
EXPECT_EQ(0x33441122u, ROL(0x11223344u, 16));
}

View File

@@ -0,0 +1,60 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/morton.h"
#include "libc/nexgen32e/kcpuids.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(morton, test) {
EXPECT_EQ(0, morton(0, 0));
EXPECT_EQ(1, morton(0, 1));
EXPECT_EQ(2, morton(1, 0));
EXPECT_EQ(3, morton(1, 1));
EXPECT_EQ(4, morton(0, 2));
EXPECT_EQ(~0ul, morton(~0ul, ~0ul));
EXPECT_EQ(0x7ffffffffffffffdul, morton(0x7ffffffeul, 0xfffffffful));
EXPECT_EQ(0b1010101000010101010, morton(0b0000001111, 0b1111000000));
}
TEST(unmorton, test) {
EXPECT_EQ(0, unmorton(0).ax);
EXPECT_EQ(0, unmorton(0).dx);
EXPECT_EQ(0, unmorton(1).ax);
EXPECT_EQ(1, unmorton(1).dx);
EXPECT_EQ(1, unmorton(2).ax);
EXPECT_EQ(0, unmorton(2).dx);
EXPECT_EQ(1, unmorton(3).ax);
EXPECT_EQ(1, unmorton(3).dx);
EXPECT_EQ(0, unmorton(4).ax);
EXPECT_EQ(2, unmorton(4).dx);
EXPECT_EQ(0xffffffffu, unmorton(~0ul).ax);
EXPECT_EQ(0xffffffffu, unmorton(~0ul).dx);
EXPECT_EQ(0x7ffffffeul, unmorton(0x7ffffffffffffffdul).ax);
EXPECT_EQ(0xfffffffful, unmorton(0x7ffffffffffffffdul).dx);
EXPECT_EQ(0b0000001111000000, unmorton(0b010101010000001010101).ax);
EXPECT_EQ(0b0000000000001111, unmorton(0b010101010000001010101).dx);
}
BENCH(morton, bench) {
EZBENCH2("morton", donothing,
EXPROPRIATE(morton(CONCEAL("r", 123), CONCEAL("r", 123))));
EZBENCH2("unmorton", donothing, EXPROPRIATE(unmorton(CONCEAL("r", 123))));
}

View File

@@ -0,0 +1,39 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/testlib/testlib.h"
TEST(rounddown2pow, test) {
EXPECT_EQ(0, rounddown2pow(0));
EXPECT_EQ(1, rounddown2pow(1));
EXPECT_EQ(2, rounddown2pow(2));
EXPECT_EQ(2, rounddown2pow(3));
EXPECT_EQ(4, rounddown2pow(4));
EXPECT_EQ(PAGESIZE / 2, rounddown2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE + 1));
EXPECT_EQ(PAGESIZE / 2, rounddown2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE + 1));
}

View File

@@ -0,0 +1,35 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/testlib/testlib.h"
TEST(roundup2log, test) {
EXPECT_EQ(0, roundup2log(0));
EXPECT_EQ(1, roundup2log(1));
EXPECT_EQ(1, roundup2log(2));
EXPECT_EQ(2, roundup2log(3));
EXPECT_EQ(2, roundup2log(4));
EXPECT_EQ(12, roundup2log(PAGESIZE - 1));
EXPECT_EQ(12, roundup2log(PAGESIZE));
EXPECT_EQ(13, roundup2log(PAGESIZE + 1));
EXPECT_EQ(12, roundup2log(PAGESIZE - 1));
EXPECT_EQ(12, roundup2log(PAGESIZE));
EXPECT_EQ(13, roundup2log(PAGESIZE + 1));
}

View File

@@ -0,0 +1,39 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/testlib/testlib.h"
TEST(roundup2pow, test) {
EXPECT_EQ(0, roundup2pow(0));
EXPECT_EQ(1, roundup2pow(1));
EXPECT_EQ(2, roundup2pow(2));
EXPECT_EQ(4, roundup2pow(3));
EXPECT_EQ(4, roundup2pow(4));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE * 2, roundup2pow(PAGESIZE + 1));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE * 2, roundup2pow(PAGESIZE + 1));
}

54
test/libc/bits/test.mk Normal file
View File

@@ -0,0 +1,54 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_BITS
TEST_LIBC_BITS_SRCS := $(wildcard test/libc/bits/*.c)
TEST_LIBC_BITS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_BITS_SRCS))
TEST_LIBC_BITS_COMS = $(TEST_LIBC_BITS_OBJS:%.o=%.com)
TEST_LIBC_BITS_OBJS = \
$(TEST_LIBC_BITS_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_BITS_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_BITS_BINS = \
$(TEST_LIBC_BITS_COMS) \
$(TEST_LIBC_BITS_COMS:%=%.dbg)
TEST_LIBC_BITS_TESTS = \
$(TEST_LIBC_BITS_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_BITS_CHECKS = \
$(TEST_LIBC_BITS_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_BITS_DIRECTDEPS = \
LIBC_X \
LIBC_BITS \
LIBC_NEXGEN32E \
LIBC_STUBS \
LIBC_TESTLIB
TEST_LIBC_BITS_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_BITS_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/bits/bits.pkg: \
$(TEST_LIBC_BITS_OBJS) \
$(foreach x,$(TEST_LIBC_BITS_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/bits/%.com.dbg: \
$(TEST_LIBC_BITS_DEPS) \
o/$(MODE)/test/libc/bits/%.o \
o/$(MODE)/test/libc/bits/bits.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_BITS_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/bits
o/$(MODE)/test/libc/bits: \
$(TEST_LIBC_BITS_BINS) \
$(TEST_LIBC_BITS_CHECKS)

View File

@@ -0,0 +1,31 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/testlib/testlib.h"
TEST(unsignedsubtract, testMacro) {
EXPECT_EQ(5ul, unsignedsubtract(7ul, 2ul));
EXPECT_EQ(18ul, unsignedsubtract(2ul, 0xfffffffffffffff0ul));
}
TEST(unsignedsubtract, testLinked) {
EXPECT_EQ(5ul, (unsignedsubtract)(7ul, 2ul));
EXPECT_EQ(18ul, (unsignedsubtract)(2ul, 0xfffffffffffffff0ul));
}

View File

@@ -0,0 +1,40 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/errno.h"
#include "libc/runtime/runtime.h"
#include "libc/calls/calls.h"
#include "libc/sysv/consts/ok.h"
#include "libc/testlib/testlib.h"
textstartup static void init(void) {
/* xxx: need better test environment thing */
if (!fileexists("test/libc/access_test.c")) exit(0);
}
const void *const ctors[] initarray = {init};
TEST(access, readDirectory) { ASSERT_EQ(0, access("test/libc/", F_OK)); }
TEST(access, readThisCode) {
ASSERT_EQ(0, access("test/libc/access_test.c", R_OK));
}
TEST(access, runThisExecutable) {
ASSERT_EQ(0, access(program_invocation_name, R_OK | X_OK));
}

View File

@@ -0,0 +1,90 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/calls.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
int rc;
struct stat st;
const char *path;
int64_t fd, emptyspace, physicalspace;
TEST(fallocate_000, setup) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);
}
TEST(fallocate_010, testBadFileDescriptor) {
if (IsFreebsd()) return; /* TODO: FreeBSD failing to set carry flag bug */
ASSERT_EQ(-1, fallocate(/*RHEL*/ 5, 0, 0, 1));
if (errno == ENOSYS) exit(0);
EXPECT_EQ(EBADF, errno);
}
TEST(fallocate_020, test) {
path = gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name));
ASSERT_NE(-1, (fd = creat(path, 0755)));
ASSERT_EQ(5, write(fd, "hello", 5));
errno = 31337;
ASSERT_NE(-1, fallocate(fd, 0, 0, 31337));
EXPECT_EQ(31337, errno);
ASSERT_EQ(5, write(fd, "world", 5));
ASSERT_NE(-1, close(fd));
ASSERT_NE(-1, stat(path, &st));
ASSERT_EQ(31337, st.st_size);
ASSERT_BINEQ(u"helloworld", gc(slurp(path, NULL)));
unlink(path);
}
TEST(fallocate_020, testSparseFile) {
ASSERT_NE(-1, stat("o", &st));
emptyspace = rounddown(6 * 1000 * 1000 * 1000, st.st_blksize);
physicalspace = roundup(4096, st.st_blksize);
path = gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid()));
ASSERT_NE(-1, (fd = creat(path, 0755)));
rc = fallocate(fd, 0, emptyspace, physicalspace);
if (rc == -1) {
/*
* most important feature is failing w/ enosys if not possible to
* allocate storage like a central banker prints money.
*/
ASSERT_EQ(ENOSYS, errno);
}
ASSERT_EQ(emptyspace, lseek(fd, emptyspace, SEEK_SET));
ASSERT_EQ(5, write(fd, "hello", 5));
ASSERT_NE(-1, fsync(fd));
ASSERT_NE(-1, close(fd));
ASSERT_NE(-1, stat(path, &st));
EXPECT_EQ(emptyspace + physicalspace, st.st_size);
/*
* don't care how much physical space system needs, so long as it's
* transparent and less than 10 percent the fake space
*/
EXPECT_NE(0, st.st_blocks);
EXPECT_LT(st.st_blocks * 512, emptyspace / 10);
unlink(path);
}

View File

@@ -0,0 +1,49 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/calls.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
int64_t fd;
struct stat st;
const char *path;
TEST(ftruncate, test) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);
path = gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid()));
ASSERT_NE(-1, (fd = creat(path, 0755)));
ASSERT_EQ(5, write(fd, "hello", 5));
errno = 31337;
ASSERT_NE(-1, ftruncate(fd, 31337));
EXPECT_EQ(31337, errno);
ASSERT_EQ(5, write(fd, "world", 5));
ASSERT_NE(-1, close(fd));
ASSERT_NE(-1, stat(path, &st));
ASSERT_EQ(31337, st.st_size);
ASSERT_BINEQ(u"helloworld", gc(slurp(path, NULL)));
unlink(path);
}

View File

@@ -0,0 +1,77 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
uint64_t i;
const char *oldpath, *bindir, *homedir, *binsh, *sh;
TEST(commandv_00, todo) { /* TODO(jart): Improve this on Windows. */
if (IsWindows()) exit(0);
}
TEST(commandv_001, setupFiles) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);
oldpath = strdup(getenv("PATH"));
homedir = xasprintf("o/tmp/home.%d", getpid());
bindir = xasprintf("o/tmp/bin.%d", getpid());
binsh = xasprintf("%s/sh.com", bindir);
ASSERT_NE(-1, mkdir(homedir, 0755));
ASSERT_NE(-1, mkdir(bindir, 0755));
ASSERT_NE(-1, touch(binsh, 0755));
ASSERT_NE(-1, setenv("PATH", bindir, true));
}
TEST(commandv_010, testSlashes_wontSearchPath_butChecksAccess) {
sh = defer(unlink, gc(xasprintf("%s/sh.com", homedir)));
EXPECT_NE(-1, touch(sh, 0755));
i = g_syscount;
EXPECT_STREQ(sh, commandv(sh));
if (!IsWindows()) EXPECT_EQ(i + 1 /* access() */, g_syscount);
}
TEST(commandv_010, testNoSlashes_searchesPath_withMemoization) {
if (IsTiny()) return;
i = g_syscount;
EXPECT_STREQ(binsh, commandv("sh.com"));
if (!IsWindows()) EXPECT_GT(g_syscount, i);
i = g_syscount;
EXPECT_STREQ(binsh, commandv("sh.com"));
if (!IsWindows()) EXPECT_EQ(g_syscount, i);
}
TEST(commandv_999, teardown) {
setenv("PATH", oldpath, true);
unlink(binsh);
rmdir(bindir);
rmdir(homedir);
free(bindir);
free(binsh);
free(homedir);
free(oldpath);
}

View File

@@ -0,0 +1,54 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/dirent.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(dirstream, test) {
DIR *dir;
struct dirent *ent;
char *dpath, *file1, *file2;
dpath = gc(xasprintf("%s%s%lu", kTmpPath, "dirstream", rand32()));
file1 = gc(xasprintf("%s/%s", dpath, "foo"));
file2 = gc(xasprintf("%s/%s", dpath, "bar"));
EXPECT_NE(-1, mkdir(dpath, 0755));
EXPECT_NE(-1, touch(file1, 0644));
EXPECT_NE(-1, touch(file2, 0644));
EXPECT_TRUE(NULL != (dir = opendir(dpath)));
bool hasfoo = false;
bool hasbar = false;
while ((ent = readdir(dir))) {
if (strcmp(ent->d_name, "foo")) hasfoo = true;
if (strcmp(ent->d_name, "bar")) hasbar = true;
}
EXPECT_TRUE(hasfoo);
EXPECT_TRUE(hasbar);
EXPECT_NE(-1, closedir(dir));
EXPECT_NE(-1, unlink(file2));
EXPECT_NE(-1, unlink(file1));
EXPECT_NE(-1, rmdir(dpath));
}

View File

@@ -0,0 +1,77 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/hefty/ntspawn.h"
#include "libc/errno.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(mkntcmdline, emptyArgvList_isntValidCommandLine) {
char *argv[] = {NULL};
EXPECT_EQ(NULL, gc(mkntcmdline(argv)));
EXPECT_EQ(EINVAL, errno);
}
TEST(mkntcmdline, emptyArgs_isEmptyString) {
char *argv[] = {"", NULL};
EXPECT_STREQ(u"", gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, ignoranceIsBliss) {
char *argv[] = {"echo", "hello", "world", NULL};
EXPECT_STREQ(u"echo hello world", gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, spaceInArgument_getQuotesWrappedAround) {
char *argv[] = {"echo", "hello there", "world", NULL};
EXPECT_STREQ(u"echo \"hello there\" world", gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, justQuote) {
char *argv[] = {"\"", NULL};
EXPECT_STREQ(u"\"\\\"\"", gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, justSlash) {
char *argv[] = {"\\", NULL};
EXPECT_STREQ(u"\\", gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, justSlashQuote) {
char *argv[] = {"\\\"", NULL};
EXPECT_STREQ(u"\"\\\\\\\"\"" /* "\\\"" */, gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, basicQuoting) {
char *argv[] = {"a\"b c", "d", NULL};
EXPECT_STREQ(u"\"a\\\"b c\" d" /* "a\"b c" d */, gc(mkntcmdline(argv)));
}
TEST(mkntcmdline, testUnicode) {
char *argv1[] = {
gc(strdup("(╯°□°)╯")),
gc(strdup("要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非")),
NULL,
};
EXPECT_STREQ(
u"(╯°□°)╯ \"要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非\"",
gc(mkntcmdline(memcpy(gc(malloc(sizeof(argv1))), argv1, sizeof(argv1)))));
}

View File

@@ -0,0 +1,39 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/gc.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/testlib/testlib.h"
TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) {
char *envp[] = {NULL};
ASSERT_BINEQ(u"  ", gc(mkntenvblock(envp)));
}
TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) {
char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL};
ASSERT_BINEQ(
u"c = d   "
u"h d u c = d   "
u"u = b   "
u"u h = d   "
u"Θù= ^ù  "
u"  ",
gc(mkntenvblock(envp)));
}

View File

@@ -0,0 +1,33 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/gc.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/testlib/testlib.h"
TEST(sortenvp, test) {
char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL};
char **sortedenvp = gc(sortenvp(envp));
EXPECT_STREQ("c=d", sortedenvp[0]);
EXPECT_STREQ("hduc=d", sortedenvp[1]);
EXPECT_STREQ("u=b", sortedenvp[2]);
EXPECT_STREQ("uh=d", sortedenvp[3]);
EXPECT_STREQ("韩=非", sortedenvp[4]);
EXPECT_EQ(NULL, sortedenvp[5]);
}

View File

@@ -0,0 +1,74 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/hefty/spawn.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/auxv.h"
#include "libc/sysv/consts/exit.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/testlib/testlib.h"
#define CMD (IsWindows() ? "cmd" : "sh")
#define ARG (IsWindows() ? "/c" : "-c")
#define COD (IsWindows() ? "echo %BOOP%" : "echo $BOOP")
#define OUT (IsWindows() ? u"hello♪◙" : u"hello◙")
TEST(spawnve, testIpc) {
ssize_t got;
int pid, wstatus;
char buf[16] = {0};
int tubes[3] = {STDIN_FILENO, -1, STDERR_FILENO};
errno = 0;
setenv("BOOP", "hello", true);
ASSERT_EQ(0, errno);
ASSERT_NE(-1, (pid = spawnlp(0, tubes, CMD, CMD, ARG, COD, NULL)));
ASSERT_EQ(0, errno);
ASSERT_NE(-1, (got = read(tubes[1], buf, sizeof(buf))));
ASSERT_EQ(0, errno);
ASSERT_NE(-1, waitpid(pid, &wstatus, 0));
ASSERT_EQ(0, errno);
EXPECT_EQ(0, WEXITSTATUS(wstatus));
EXPECT_BINEQ(OUT, buf);
}
TEST(spawnve, testExit) {
int pid, wstatus;
ASSERT_NE(-1, (pid = spawnlp(0, NULL, CMD, CMD, ARG, "exit 42", NULL)));
ASSERT_NE(-1, waitpid(pid, &wstatus, 0));
EXPECT_EQ(42, WEXITSTATUS(wstatus));
}
TEST(spawnve, testSpawnSelf) {
int pid, wstatus;
ASSERT_NE(-1,
(pid = spawnlp(0, NULL, (const char *)getauxval(AT_EXECFN),
program_invocation_name, "--testSpawnSelf", NULL)));
ASSERT_NE(-1, waitpid(pid, &wstatus, 0));
EXPECT_EQ(123, WEXITSTATUS(wstatus));
}
static textstartup void onspawnself() {
if (g_argc > 1 && strcmp(g_argv[1], "--testSpawnSelf") == 0) {
_exit(123);
}
}
const void *const onspawnself_ctor[] initarray = {onspawnself};

View File

@@ -0,0 +1,45 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/gc.h"
#include "libc/calls/internal.h"
#include "libc/testlib/testlib.h"
char16_t p[PATH_MAX];
TEST(mkntpath, testEmpty) {
EXPECT_EQ(0, mkntpath("", p));
EXPECT_STREQ(u"", p);
}
TEST(mkntpath, testSlashes) {
/*
* The Windows command prompt works fine with all reasonable
* unix-style paths. There only seems to be one exception, and that's
* all it takes to make the feature entirely useless to us, similar to
* the law of noncontradiction. We address the issue as follows:
*/
EXPECT_EQ(9, mkntpath("o/foo.com", p));
EXPECT_STREQ(u"o\\foo.com", p);
}
TEST(mkntpath, testUnicode) {
EXPECT_EQ(20, mkntpath("C:\\𐌰𐌱𐌲𐌳\\𐌴𐌵𐌶𐌷", p));
EXPECT_STREQ(u"C:\\𐌰𐌱𐌲𐌳\\𐌴𐌵𐌶𐌷", p);
}

View File

@@ -0,0 +1,34 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
testonly void OnCtrlC(int sig) { _exit(0); }
TEST(signal, test) {
if (IsWindows()) return; /* omg */
ASSERT_NE(SIG_ERR, signal(SIGINT, OnCtrlC));
ASSERT_NE(-1, raise(SIGINT));
die();
}

View File

@@ -0,0 +1,43 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/nt/files.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
char *pathname;
struct stat st;
TEST(stat_000, setupFiles) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);
}
TEST(stat_010, testEmptyFile_sizeIsZero) {
pathname = defer(
unlink,
gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid())));
ASSERT_NE(-1, touch(pathname, 0755));
EXPECT_NE(-1, stat(pathname, &st));
EXPECT_EQ(0, st.st_size);
}

60
test/libc/calls/test.mk Normal file
View File

@@ -0,0 +1,60 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_CALLS
TEST_LIBC_CALLS_SRCS := \
$(wildcard test/libc/calls/*.c) \
$(wildcard test/libc/calls/hefty/*.c)
TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS))
TEST_LIBC_CALLS_COMS = $(TEST_LIBC_CALLS_OBJS:%.o=%.com)
TEST_LIBC_CALLS_OBJS = \
$(TEST_LIBC_CALLS_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_CALLS_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_CALLS_BINS = \
$(TEST_LIBC_CALLS_COMS) \
$(TEST_LIBC_CALLS_COMS:%=%.dbg)
TEST_LIBC_CALLS_TESTS = \
$(TEST_LIBC_CALLS_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_CALLS_CHECKS = \
$(TEST_LIBC_CALLS_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_CALLS_DIRECTDEPS = \
LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_RAND \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X
TEST_LIBC_CALLS_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_CALLS_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/calls/calls.pkg: \
$(TEST_LIBC_CALLS_OBJS) \
$(foreach x,$(TEST_LIBC_CALLS_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/calls/%.com.dbg: \
$(TEST_LIBC_CALLS_DEPS) \
o/$(MODE)/test/libc/calls/%.o \
o/$(MODE)/test/libc/calls/calls.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/libc/calls
o/$(MODE)/test/libc/calls: \
$(TEST_LIBC_CALLS_BINS) \
$(TEST_LIBC_CALLS_CHECKS)

View File

@@ -0,0 +1,44 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/testlib/testlib.h"
TEST(basename, test) {
EXPECT_STREQ("", basename(""));
EXPECT_STREQ("hello", basename("hello"));
EXPECT_STREQ("there", basename("hello/there"));
EXPECT_STREQ("yo", basename("hello/there/yo"));
}
TEST(basename, testTrailingSlash_isIgnored) {
/* should be "foo" but basename() doesn't allocate memory */
EXPECT_STREQ("foo/", basename("foo/"));
EXPECT_STREQ("foo//", basename("foo//"));
}
TEST(basename, testOnlySlashes_oneSlashOnlyVasily) {
EXPECT_STREQ("/", basename("///"));
}
TEST(basename, testWindows_isGrantedRespect) {
EXPECT_STREQ("there", basename("hello\\there"));
EXPECT_STREQ("yo", basename("hello\\there\\yo"));
}

View File

@@ -0,0 +1,36 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(llog10, test) {
EXPECT_EQ(0, llog10(1));
EXPECT_EQ(0, llog10(2));
EXPECT_EQ(0, llog10(9));
EXPECT_EQ(1, llog10(10));
EXPECT_EQ(1, llog10(11));
EXPECT_EQ(1, llog10(99));
EXPECT_EQ(2, llog10(100));
EXPECT_EQ(2, llog10(101));
EXPECT_EQ(9, llog10(INT_MAX));
EXPECT_EQ(12, llog10(1000000000000));
}

View File

@@ -0,0 +1,50 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/conv/conv.h"
#include "libc/conv/sizemultiply.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
size_t out;
TEST(sizemultiply, testMultiplication) {
EXPECT_TRUE(sizemultiply(&out, 7, 11));
EXPECT_EQ(7 * 11, out);
EXPECT_TRUE(sizemultiply(&out, 11, 7));
EXPECT_EQ(7 * 11, out);
EXPECT_TRUE(sizemultiply(&out, 0, 11));
EXPECT_EQ(0 * 11, out);
EXPECT_TRUE(sizemultiply(&out, 11, 0));
EXPECT_EQ(0 * 11, out);
}
TEST(sizemultiply, testOverflow_alwaysReturnsSizeMax) {
EXPECT_FALSE(sizemultiply(&out, 7, SIZE_MAX));
EXPECT_EQ(SIZE_MAX, out);
EXPECT_FALSE(sizemultiply(&out, SIZE_MAX, 7));
EXPECT_EQ(SIZE_MAX, out);
}
TEST(sizemultiply, testOverflow_closeButNoCigar) {
EXPECT_TRUE(sizemultiply(&out, SIZE_MAX, 1));
EXPECT_EQ(SIZE_MAX, out);
EXPECT_TRUE(sizemultiply(&out, 1, SIZE_MAX));
EXPECT_EQ(SIZE_MAX, out);
}

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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/testlib/testlib.h"
/* todo(jart): work on this more */
TEST(strtoimax, testZero) { EXPECT_EQ(0, strtoimax("0", NULL, 0)); }
TEST(strtoimax, testDecimal) { EXPECT_EQ(-123, strtoimax("-123", NULL, 0)); }
TEST(strtoimax, testHex) { EXPECT_EQ(-255, strtoimax("-0xff", NULL, 0)); }
TEST(strtoimax, testOctal) { EXPECT_EQ(-123, strtoimax("-0173", NULL, 0)); }
TEST(strtoimax, testLimits) {
EXPECT_EQ(
((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("-1", NULL, 0));
EXPECT_EQ(
((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("0x7fffffffffffffffffffffffffffffff", NULL, 0));
}

View File

@@ -0,0 +1,35 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(strtoumax, testZero) { EXPECT_EQ(UINTMAX_MIN, strtoumax("0", NULL, 0)); }
TEST(strtoumax, testDecimal) { EXPECT_EQ(123, strtoumax("123", NULL, 0)); }
TEST(strtoumax, testHex) { EXPECT_EQ(255, strtoumax("0xff", NULL, 0)); }
TEST(strtoumax, testOctal) { EXPECT_EQ(123, strtoumax("0173", NULL, 0)); }
TEST(strtoumax, testMaximum) {
EXPECT_EQ(UINTMAX_MAX,
strtoumax("340282366920938463463374607431768211455", NULL, 0));
EXPECT_EQ(UINTMAX_MAX,
strtoumax("0xffffffffffffffffffffffffffffffff", NULL, 0));
}

57
test/libc/conv/test.mk Normal file
View File

@@ -0,0 +1,57 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_CONV
TEST_LIBC_CONV_SRCS := $(wildcard test/libc/conv/*.c)
TEST_LIBC_CONV_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CONV_SRCS))
TEST_LIBC_CONV_COMS = $(TEST_LIBC_CONV_OBJS:%.o=%.com)
TEST_LIBC_CONV_OBJS = \
$(TEST_LIBC_CONV_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_CONV_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_CONV_BINS = \
$(TEST_LIBC_CONV_COMS) \
$(TEST_LIBC_CONV_COMS:%=%.dbg)
TEST_LIBC_CONV_TESTS = \
$(TEST_LIBC_CONV_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_CONV_CHECKS = \
$(TEST_LIBC_CONV_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_CONV_DIRECTDEPS = \
LIBC_CONV \
LIBC_NEXGEN32E \
LIBC_STUBS \
LIBC_TESTLIB
TEST_LIBC_CONV_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_CONV_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/conv/conv.pkg: \
$(TEST_LIBC_CONV_OBJS) \
$(foreach x,$(TEST_LIBC_CONV_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/conv/%.com.dbg: \
$(TEST_LIBC_CONV_DEPS) \
o/$(MODE)/test/libc/conv/%.o \
o/$(MODE)/test/libc/conv/conv.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_CONV_OBJS): \
$(BUILD_FILES) \
test/libc/conv/test.mk
$(TEST_LIBC_CONV_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/conv
o/$(MODE)/test/libc/conv: \
$(TEST_LIBC_CONV_BINS) \
$(TEST_LIBC_CONV_CHECKS)

View File

@@ -0,0 +1,33 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timeval.h"
#include "libc/conv/conv.h"
#include "libc/nt/struct/filetime.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
TEST(timevaltofiletime, roundTrip) {
struct timeval tv1, tv2;
tv1.tv_sec = 31337;
tv1.tv_usec = 1337;
filetimetotimeval(&tv2, timevaltofiletime(&tv1));
EXPECT_EQ(31337, tv2.tv_sec);
EXPECT_EQ(1337, tv2.tv_usec);
}

View File

@@ -0,0 +1,333 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/crypto/rijndael.h"
#include "libc/dce.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
/**
* Test vectors published by:
*
* Morris Dworkin
* National Institute of Standards and Technology
* Recommendation for Block Cipher Modes of Operation: Methods and Techniques
* SP 800-38A (DOI)
* December 2001
*/
FIXTURE(rijndael, disableHardwareExtensions) {
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
}
/**
* F.1.1: ECB-AES128.Encrypt
*
* Key 2b7e151628aed2a6abf7158809cf4f3c
*
* Block No. 1
* Plaintext 6bc1bee22e409f96e93d7e117393172a
* Input Block 6bc1bee22e409f96e93d7e117393172a
* Output Block 3ad77bb40d7a3660a89ecaf32466ef97
* Ciphertext 3ad77bb40d7a3660a89ecaf32466ef97
*
* Block No. 2
* Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
* Input Block ae2d8a571e03ac9c9eb76fac45af8e51
* Output Block f5d3d58503b9699de785895a96fdbaaf
* Ciphertext f5d3d58503b9699de785895a96fdbaaf
*
* Block No. 3
* Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
* Input Block 30c81c46a35ce411e5fbc1191a0a52ef
* Output Block 43b1cd7f598ece23881b00e3ed030688
* Ciphertext 43b1cd7f598ece23881b00e3ed030688
*
* Block No. 4
* Plaintext f69f2445df4f9b17ad2b417be66c3710
* Input Block f69f2445df4f9b17ad2b417be66c3710
* Output Block 7b0c785e27e8ad3f8223207104725dd4
* Ciphertext 7b0c785e27e8ad3f8223207104725dd4
*/
TEST(aes128, testNistEcbRijndael) {
struct Rijndael ctx;
aes_block_t k1, block;
unhexbuf(&k1, 16, "2b7e151628aed2a6abf7158809cf4f3c");
rijndaelinit(&ctx, 10, k1, k1);
unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a");
block = rijndael(10, block, &ctx);
EXPECT_BINEQ("3ad77bb40d7a3660a89ecaf32466ef97", &block);
unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51");
block = rijndael(10, block, &ctx);
EXPECT_BINEQ("f5d3d58503b9699de785895a96fdbaaf", &block);
unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef");
block = rijndael(10, block, &ctx);
EXPECT_BINEQ("43b1cd7f598ece23881b00e3ed030688", &block);
unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710");
block = rijndael(10, block, &ctx);
EXPECT_BINEQ("7b0c785e27e8ad3f8223207104725dd4", &block);
}
/**
* F.1.2: ECB-AES128.Decrypt
*
* Key 2b7e151628aed2a6abf7158809cf4f3c
*
* Block No. 1
* Plaintext 3ad77bb40d7a3660a89ecaf32466ef97
* Input Block 3ad77bb40d7a3660a89ecaf32466ef97
* Output Block 6bc1bee22e409f96e93d7e117393172a
* Ciphertext 6bc1bee22e409f96e93d7e117393172a
*
* Block No. 2
* Plaintext f5d3d58503b9699de785895a96fdbaaf
* Input Block f5d3d58503b9699de785895a96fdbaaf
* Output Block ae2d8a571e03ac9c9eb76fac45af8e51
* Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51
*
* Block No. 3
* Plaintext 43b1cd7f598ece23881b00e3ed030688
* Input Block 43b1cd7f598ece23881b00e3ed030688
* Output Block 30c81c46a35ce411e5fbc1191a0a52ef
* Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef
*
* Block No. 4
* Plaintext 7b0c785e27e8ad3f8223207104725dd4
* Input Block 7b0c785e27e8ad3f8223207104725dd4
* Output Block f69f2445df4f9b17ad2b417be66c3710
* Ciphertext f69f2445df4f9b17ad2b417be66c3710
*/
TEST(aes128, testNistEcbUnrijndael) {
struct Rijndael ctx;
aes_block_t k1, block;
unhexbuf(&k1, 16, "2b7e151628aed2a6abf7158809cf4f3c");
unrijndaelinit(&ctx, 10, k1, k1);
unhexbuf(&block, 16, "3ad77bb40d7a3660a89ecaf32466ef97");
block = unrijndael(10, block, &ctx);
EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block);
unhexbuf(&block, 16, "f5d3d58503b9699de785895a96fdbaaf");
block = unrijndael(10, block, &ctx);
EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block);
unhexbuf(&block, 16, "43b1cd7f598ece23881b00e3ed030688");
block = unrijndael(10, block, &ctx);
EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block);
unhexbuf(&block, 16, "7b0c785e27e8ad3f8223207104725dd4");
block = unrijndael(10, block, &ctx);
EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block);
}
/**
* F.1.3: ECB-AES192.Encrypt
*
* Key 8e73b0f7da0e6452c810f32b809079e5
* 62f8ead2522c6b7b
*
* Block No. 1
* Plaintext 6bc1bee22e409f96e93d7e117393172a
* Input Block 6bc1bee22e409f96e93d7e117393172a
* Output Block bd334f1d6e45f25ff712a214571fa5cc
* Ciphertext bd334f1d6e45f25ff712a214571fa5cc
*
* Block No. 2
* Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
* Input Block ae2d8a571e03ac9c9eb76fac45af8e51
* Output Block 974104846d0ad3ad7734ecb3ecee4eef
* Ciphertext 974104846d0ad3ad7734ecb3ecee4eef
*
* Block No. 3
* Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
* Input Block 30c81c46a35ce411e5fbc1191a0a52ef
* Output Block ef7afd2270e2e60adce0ba2face6444e
* Ciphertext ef7afd2270e2e60adce0ba2face6444e
*
* Block No. 4
* Plaintext f69f2445df4f9b17ad2b417be66c3710
* Input Block f69f2445df4f9b17ad2b417be66c3710
* Output Block 9a4b41ba738d6c72fb16691603c18e0e
* Ciphertext 9a4b41ba738d6c72fb16691603c18e0e
*/
TEST(aes192, testNistEcbRijndael) {
struct Rijndael ctx;
aes_block_t k1, k2, block;
unhexbuf(&k1, 16, "8e73b0f7da0e6452c810f32b809079e5");
unhexbuf(&k2, 16, "62f8ead2522c6b7bDEADBEEFFEEDFACE");
rijndaelinit(&ctx, 12, k1, k2);
unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a");
block = rijndael(12, block, &ctx);
EXPECT_BINEQ("bd334f1d6e45f25ff712a214571fa5cc", &block);
unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51");
block = rijndael(12, block, &ctx);
EXPECT_BINEQ("974104846d0ad3ad7734ecb3ecee4eef", &block);
unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef");
block = rijndael(12, block, &ctx);
EXPECT_BINEQ("ef7afd2270e2e60adce0ba2face6444e", &block);
unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710");
block = rijndael(12, block, &ctx);
EXPECT_BINEQ("9a4b41ba738d6c72fb16691603c18e0e", &block);
}
/**
* F.1.4: ECB-AES192.Decrypt
*
* Key 8e73b0f7da0e6452c810f32b809079e5
* 62f8ead2522c6b7b
*
* Block No. 1
* Plaintext bd334f1d6e45f25ff712a214571fa5cc
* Input Block bd334f1d6e45f25ff712a214571fa5cc
* Output Block 6bc1bee22e409f96e93d7e117393172a
* Ciphertext 6bc1bee22e409f96e93d7e117393172a
*
* Block No. 2
* Plaintext 974104846d0ad3ad7734ecb3ecee4eef
* Input Block 974104846d0ad3ad7734ecb3ecee4eef
* Output Block ae2d8a571e03ac9c9eb76fac45af8e51
* Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51
*
* Block No. 3
* Plaintext ef7afd2270e2e60adce0ba2face6444e
* Input Block ef7afd2270e2e60adce0ba2face6444e
* Output Block 30c81c46a35ce411e5fbc1191a0a52ef
* Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef
*
* Block No. 4
* Plaintext 9a4b41ba738d6c72fb16691603c18e0e
* Input Block 9a4b41ba738d6c72fb16691603c18e0e
* Output Block f69f2445df4f9b17ad2b417be66c3710
* Ciphertext f69f2445df4f9b17ad2b417be66c3710
*/
TEST(aes192, testNistEcbUnrijndael) {
struct Rijndael ctx;
aes_block_t k1, k2, block;
unhexbuf(&k1, 16, "8e73b0f7da0e6452c810f32b809079e5");
unhexbuf(&k2, 16, "62f8ead2522c6b7bDEADBEEFFEEDFACE");
unrijndaelinit(&ctx, 12, k1, k2);
unhexbuf(&block, 16, "bd334f1d6e45f25ff712a214571fa5cc");
block = unrijndael(12, block, &ctx);
EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block);
unhexbuf(&block, 16, "974104846d0ad3ad7734ecb3ecee4eef");
block = unrijndael(12, block, &ctx);
EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block);
unhexbuf(&block, 16, "ef7afd2270e2e60adce0ba2face6444e");
block = unrijndael(12, block, &ctx);
EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block);
unhexbuf(&block, 16, "9a4b41ba738d6c72fb16691603c18e0e");
block = unrijndael(12, block, &ctx);
EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block);
}
/**
* F.1.5: ECB-AES256.Encrypt
*
* Key 603deb1015ca71be2b73aef0857d7781
* 1f352c073b6108d72d9810a30914dff4
*
* Block No. 1
* Plaintext 6bc1bee22e409f96e93d7e117393172a
* Input Block 6bc1bee22e409f96e93d7e117393172a
* Output Block f3eed1bdb5d2a03c064b5a7e3db181f8
* Ciphertext f3eed1bdb5d2a03c064b5a7e3db181f8
*
* Block No. 2
* Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
* Input Block ae2d8a571e03ac9c9eb76fac45af8e51
* Output Block 591ccb10d410ed26dc5ba74a31362870
* Ciphertext 591ccb10d410ed26dc5ba74a31362870
*
* Block No. 3
* Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
* Input Block 30c81c46a35ce411e5fbc1191a0a52ef
* Output Block b6ed21b99ca6f4f9f153e7b1beafed1d
* Ciphertext b6ed21b99ca6f4f9f153e7b1beafed1d
*
* Block No. 4
* Plaintext f69f2445df4f9b17ad2b417be66c3710
* Input Block f69f2445df4f9b17ad2b417be66c3710
* Output Block 23304b7a39f9f3ff067d8d8f9e24ecc7
* Ciphertext 23304b7a39f9f3ff067d8d8f9e24ecc7
*/
TEST(aes256, testNistEcbRijndael) {
struct Rijndael ctx;
aes_block_t k1, k2, block;
unhexbuf(&k1, 16, "603deb1015ca71be2b73aef0857d7781");
unhexbuf(&k2, 16, "1f352c073b6108d72d9810a30914dff4");
rijndaelinit(&ctx, 14, k1, k2);
unhexbuf(&block, 16, "6bc1bee22e409f96e93d7e117393172a");
block = rijndael(14, block, &ctx);
EXPECT_BINEQ("f3eed1bdb5d2a03c064b5a7e3db181f8", &block);
unhexbuf(&block, 16, "ae2d8a571e03ac9c9eb76fac45af8e51");
block = rijndael(14, block, &ctx);
EXPECT_BINEQ("591ccb10d410ed26dc5ba74a31362870", &block);
unhexbuf(&block, 16, "30c81c46a35ce411e5fbc1191a0a52ef");
block = rijndael(14, block, &ctx);
EXPECT_BINEQ("b6ed21b99ca6f4f9f153e7b1beafed1d", &block);
unhexbuf(&block, 16, "f69f2445df4f9b17ad2b417be66c3710");
block = rijndael(14, block, &ctx);
EXPECT_BINEQ("23304b7a39f9f3ff067d8d8f9e24ecc7", &block);
}
/**
* F.1.6: ECB-AES256.Decrypt
*
* Key 603deb1015ca71be2b73aef0857d7781
* 1f352c073b6108d72d9810a30914dff4
*
* Block No. 1
* Input Block f3eed1bdb5d2a03c064b5a7e3db181f8
* Plaintext f3eed1bdb5d2a03c064b5a7e3db181f8
* Ciphertext 6bc1bee22e409f96e93d7e117393172a
* Output Block 6bc1bee22e409f96e93d7e117393172a
*
* Block No. 2
* Input Block 591ccb10d410ed26dc5ba74a31362870
* Plaintext 591ccb10d410ed26dc5ba74a31362870
* Ciphertext ae2d8a571e03ac9c9eb76fac45af8e51
* Output Block ae2d8a571e03ac9c9eb76fac45af8e51
*
* Block No. 3
* Input Block b6ed21b99ca6f4f9f153e7b1beafed1d
* Plaintext b6ed21b99ca6f4f9f153e7b1beafed1d
* Ciphertext 30c81c46a35ce411e5fbc1191a0a52ef
* Output Block 30c81c46a35ce411e5fbc1191a0a52ef
*
* Block No. 4
* Input Block 23304b7a39f9f3ff067d8d8f9e24ecc7
* Plaintext 23304b7a39f9f3ff067d8d8f9e24ecc7
* Ciphertext f69f2445df4f9b17ad2b417be66c3710
* Output Block f69f2445df4f9b17ad2b417be66c3710
*/
TEST(aes256, testNistEcbUnrijndael) {
struct Rijndael ctx;
aes_block_t k1, k2, block;
unhexbuf(&k1, 16, "603deb1015ca71be2b73aef0857d7781");
unhexbuf(&k2, 16, "1f352c073b6108d72d9810a30914dff4");
unrijndaelinit(&ctx, 14, k1, k2);
unhexbuf(&block, 16, "f3eed1bdb5d2a03c064b5a7e3db181f8");
block = unrijndael(14, block, &ctx);
EXPECT_BINEQ("6bc1bee22e409f96e93d7e117393172a", &block);
unhexbuf(&block, 16, "591ccb10d410ed26dc5ba74a31362870");
block = unrijndael(14, block, &ctx);
EXPECT_BINEQ("ae2d8a571e03ac9c9eb76fac45af8e51", &block);
unhexbuf(&block, 16, "b6ed21b99ca6f4f9f153e7b1beafed1d");
block = unrijndael(14, block, &ctx);
EXPECT_BINEQ("30c81c46a35ce411e5fbc1191a0a52ef", &block);
unhexbuf(&block, 16, "23304b7a39f9f3ff067d8d8f9e24ecc7");
block = unrijndael(14, block, &ctx);
EXPECT_BINEQ("f69f2445df4f9b17ad2b417be66c3710", &block);
}

49
test/libc/crypto/test.mk Normal file
View File

@@ -0,0 +1,49 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_CRYPTO
TEST_LIBC_CRYPTO_SRCS := $(wildcard test/libc/crypto/*.c)
TEST_LIBC_CRYPTO_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CRYPTO_SRCS))
TEST_LIBC_CRYPTO_COMS = $(TEST_LIBC_CRYPTO_OBJS:%.o=%.com)
TEST_LIBC_CRYPTO_OBJS = \
$(TEST_LIBC_CRYPTO_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_CRYPTO_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_CRYPTO_BINS = \
$(TEST_LIBC_CRYPTO_COMS) \
$(TEST_LIBC_CRYPTO_COMS:%=%.dbg)
TEST_LIBC_CRYPTO_TESTS = \
$(TEST_LIBC_CRYPTO_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_CRYPTO_CHECKS = \
$(TEST_LIBC_CRYPTO_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_CRYPTO_DIRECTDEPS = \
LIBC_CRYPTO \
LIBC_NEXGEN32E \
LIBC_STUBS \
LIBC_TESTLIB
TEST_LIBC_CRYPTO_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_CRYPTO_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/crypto/crypto.pkg: \
$(TEST_LIBC_CRYPTO_OBJS) \
$(foreach x,$(TEST_LIBC_CRYPTO_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/crypto/%.com.dbg: \
$(TEST_LIBC_CRYPTO_DEPS) \
o/$(MODE)/test/libc/crypto/%.o \
o/$(MODE)/test/libc/crypto/crypto.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/libc/crypto
o/$(MODE)/test/libc/crypto: \
$(TEST_LIBC_CRYPTO_BINS) \
$(TEST_LIBC_CRYPTO_CHECKS)

View File

@@ -0,0 +1,48 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/dns/dnsheader.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(serializednsheader, test) {
struct DnsHeader header;
memset(&header, 0, sizeof(header));
header.id = 255;
header.bf1 = true;
header.qdcount = 1;
uint8_t *buf = tmalloc(12);
ASSERT_EQ(12, serializednsheader(buf, 12, header));
EXPECT_BINEQ(u" λ☺  ☺      ", buf);
tfree(buf);
}
TEST(serializednsheader, fuzzSymmetry) {
uint8_t *buf = tmalloc(12);
struct DnsHeader *in = tmalloc(sizeof(struct DnsHeader));
struct DnsHeader *out = tmalloc(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);
}

View File

@@ -0,0 +1,101 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(dnsnamecmp, testEmpty) {
char *A = strcpy(tmalloc(1), "");
char *B = strcpy(tmalloc(1), "");
EXPECT_EQ(dnsnamecmp(A, B), 0);
EXPECT_EQ(dnsnamecmp(A, A), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) {
char *A = tmalloc(2);
char *B = tmalloc(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);
EXPECT_EQ(dnsnamecmp(strcpy(A, "A"), strcpy(B, "a")), 0);
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);
}
TEST(dnsnamecmp, testMultiLabel_lexiReverse) {
char *A = tmalloc(16);
char *B = tmalloc(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);
EXPECT_GT(dnsnamecmp(strcpy(A, "a.zxample"), strcpy(B, "a.examplz")), 0);
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);
}
TEST(dnsnamecmp, testTldDotQualifier_canBeEqualToDottedNames) {
char *A = tmalloc(16);
char *B = tmalloc(16);
EXPECT_EQ(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "aaa.example")), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testFullyQualified_alwaysComesFirst) {
char *A = tmalloc(16);
char *B = tmalloc(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);
}
TEST(dnsnamecmp, testLikelySld_alwaysComesBeforeLocalName) {
char *A = tmalloc(16);
char *B = tmalloc(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);
}
TEST(dnsnamecmp, testLikelySubdomain_alwaysComesAfterSld) {
char *A = tmalloc(16);
char *B = tmalloc(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);
}

View File

@@ -0,0 +1,50 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/dns/dnsquestion.h"
#include "libc/errno.h"
#include "libc/testlib/testlib.h"
TEST(serializednsquestion, test) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 4);
char *name = tstrdup("foo.bar");
struct DnsQuestion dq;
dq.qname = name;
dq.qtype = 0x0201;
dq.qclass = 0x0102;
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);
}
TEST(serializednsquestion, testNoSpace) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 3);
char *name = tstrdup("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);
}

View File

@@ -0,0 +1,84 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/hoststxt.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/testlib/testlib.h"
static const char *ParseIp(unsigned char ip[4]) {
static char g_ipbuf[16];
return inet_ntop(AF_INET, ip, g_ipbuf, sizeof(g_ipbuf));
}
TEST(parsehoststxt, testEmpty) {
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(0, parsehoststxt(ht, f));
ASSERT_EQ(0, ht->entries.i);
freehoststxt(&ht);
fclose(f);
}
TEST(parsehoststxt, testCorrectlyTokenizesAndSorts) {
const char kInput[] =
"# this is a comment\n"
"# IP HOST1 HOST2\n"
"203.0.113.1 lol.example. lol\n"
"203.0.113.2 cat.example. cat\n";
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
ASSERT_EQ(0, parsehoststxt(ht, f));
sorthoststxt(ht);
ASSERT_EQ(4, ht->entries.i);
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].name]);
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].canon]);
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[0].ip));
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].name]);
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[1].canon]);
EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[1].ip));
EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[2].name]);
EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[2].canon]);
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[2].ip));
EXPECT_STREQ("lol", &ht->strings.p[ht->entries.p[3].name]);
EXPECT_STREQ("lol.example.", &ht->strings.p[ht->entries.p[3].canon]);
EXPECT_STREQ("203.0.113.1", ParseIp(ht->entries.p[3].ip));
freehoststxt(&ht);
fclose(f);
}
TEST(parsehoststxt, testIpv6_isIgnored) {
const char kInput[] =
"::1 boop\n"
"203.0.113.2 cat # ignore me\n";
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
ASSERT_EQ(0, parsehoststxt(ht, f));
ASSERT_EQ(1, ht->entries.i);
EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[0].name]);
EXPECT_STREQ("cat", &ht->strings.p[ht->entries.p[0].canon]);
EXPECT_STREQ("203.0.113.2", ParseIp(ht->entries.p[0].ip));
freehoststxt(&ht);
fclose(f);
}

View File

@@ -0,0 +1,76 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/dns/resolvconf.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/testlib/testlib.h"
static const char *FormatIp(struct sockaddr_in *ip) {
static char g_ipbuf[16];
return inet_ntop(ip->sin_family, &ip->sin_addr.s_addr, g_ipbuf, 16);
}
TEST(parseresolvconf, testEmpty) {
struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(0, parseresolvconf(rv, f));
ASSERT_EQ(0, rv->nameservers.i);
freeresolvconf(&rv);
fclose(f);
}
TEST(parseresolvconf, testCorrectlyTokenizes) {
const char kInput[] =
"# this is a comment\n"
"nameserver 203.0.113.2 \n"
" nameserver 203.0.113.1\n";
struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
ASSERT_EQ(2, parseresolvconf(rv, f));
ASSERT_EQ(2, rv->nameservers.i);
EXPECT_EQ(AF_INET, rv->nameservers.p[0].sin_family);
EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[0].sin_port));
EXPECT_STREQ("203.0.113.2", FormatIp(&rv->nameservers.p[0]));
EXPECT_EQ(AF_INET, rv->nameservers.p[1].sin_family);
EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[1].sin_port));
EXPECT_STREQ("203.0.113.1", FormatIp(&rv->nameservers.p[1]));
freeresolvconf(&rv);
fclose(f);
}
TEST(parseresolvconf, testSearchLocal_setsLoopback) {
const char kInput[] = "search local # boop\n";
struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
ASSERT_EQ(1, parseresolvconf(rv, f));
ASSERT_EQ(1, rv->nameservers.i);
EXPECT_EQ(AF_INET, rv->nameservers.p[0].sin_family);
EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[0].sin_port));
EXPECT_STREQ("127.0.0.1", FormatIp(&rv->nameservers.p[0]));
freeresolvconf(&rv);
fclose(f);
}

View File

@@ -0,0 +1,79 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/errno.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(pascalifydnsname, testEmpty) {
uint8_t *buf = tmalloc(1);
char *name = tstrdup("");
EXPECT_EQ(0, pascalifydnsname(buf, 1, name));
EXPECT_BINEQ(u" ", buf);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testOneLabel) {
uint8_t *buf = tmalloc(1 + 3 + 1);
char *name = tstrdup("foo");
EXPECT_EQ(1 + 3, pascalifydnsname(buf, 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo ", buf);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testTwoLabels) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
char *name = tstrdup("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);
}
TEST(pascalifydnsname, testFqdnDot_isntIncluded) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
char *name = tstrdup("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);
}
TEST(pascalifydnsname, testTooLong) {
uint8_t *buf = tmalloc(1);
char *name = tmalloc(1000);
memset(name, '.', 999);
name[999] = '\0';
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
EXPECT_EQ(ENAMETOOLONG, errno);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testNoSpace) {
uint8_t *buf = tmalloc(1);
char *name = tstrdup("foo");
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
EXPECT_EQ(ENOSPC, errno);
tfree(name);
tfree(buf);
}

View File

@@ -0,0 +1,83 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/dns/hoststxt.h"
#include "libc/mem/mem.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/testlib/testlib.h"
static const char *EzIp4Lookup(const struct HostsTxt *ht, const char *name) {
struct sockaddr_in addr4;
if (resolvehoststxt(ht, AF_INET, name, (void *)&addr4,
sizeof(struct sockaddr_in), NULL) > 0) {
static char g_ipbuf[16];
return inet_ntop(AF_INET, &addr4.sin_addr, g_ipbuf, sizeof(g_ipbuf));
} else {
return NULL;
}
}
static const char *EzCanonicalize(const struct HostsTxt *ht, const char *name) {
const char *res;
return resolvehoststxt(ht, AF_INET, name, NULL, 0, &res) > 0 ? res : NULL;
}
static const char kInput[] = "127.0.0.1 localhost\n"
"203.0.113.1 lol.example. lol\n"
"203.0.113.2 cat.example. cat\n";
TEST(resolvehoststxt, testBasicLookups) {
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
ASSERT_EQ(0, parsehoststxt(ht, f));
sorthoststxt(ht);
ASSERT_EQ(5, ht->entries.i);
EXPECT_STREQ("127.0.0.1", EzIp4Lookup(ht, "localhost"));
EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol"));
EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol.example"));
EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol.example."));
EXPECT_STREQ("203.0.113.2", EzIp4Lookup(ht, "cat"));
EXPECT_STREQ("203.0.113.2", EzIp4Lookup(ht, "cat.example."));
EXPECT_EQ(NULL, EzIp4Lookup(ht, "boop"));
freehoststxt(&ht);
fclose(f);
}
TEST(resolvehoststxt, testCanonicalize) {
struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt));
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
ASSERT_EQ(0, parsehoststxt(ht, f));
sorthoststxt(ht);
ASSERT_EQ(5, ht->entries.i);
EXPECT_STREQ("localhost", EzCanonicalize(ht, "localhost"));
EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol"));
EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol.example"));
EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol.example."));
EXPECT_STREQ("cat.example.", EzCanonicalize(ht, "cat"));
EXPECT_STREQ("cat.example.", EzCanonicalize(ht, "cat.example."));
EXPECT_EQ(NULL, EzCanonicalize(ht, "boop"));
freehoststxt(&ht);
fclose(f);
}

59
test/libc/dns/test.mk Normal file
View File

@@ -0,0 +1,59 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_DNS
TEST_LIBC_DNS_SRCS := $(wildcard test/libc/dns/*.c)
TEST_LIBC_DNS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_DNS_SRCS))
TEST_LIBC_DNS_COMS = $(TEST_LIBC_DNS_OBJS:%.o=%.com)
TEST_LIBC_DNS_OBJS = \
$(TEST_LIBC_DNS_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_DNS_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_DNS_BINS = \
$(TEST_LIBC_DNS_COMS) \
$(TEST_LIBC_DNS_COMS:%=%.dbg)
TEST_LIBC_DNS_TESTS = \
$(TEST_LIBC_DNS_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_DNS_CHECKS = \
$(TEST_LIBC_DNS_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_DNS_DIRECTDEPS = \
LIBC_CALLS_HEFTY \
LIBC_DNS \
LIBC_FMT \
LIBC_LOG \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STDIO \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X
TEST_LIBC_DNS_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_DNS_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/dns/dns.pkg: \
$(TEST_LIBC_DNS_OBJS) \
$(foreach x,$(TEST_LIBC_DNS_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/dns/%.com.dbg: \
$(TEST_LIBC_DNS_DEPS) \
o/$(MODE)/test/libc/dns/%.o \
o/$(MODE)/test/libc/dns/dns.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/libc/dns
o/$(MODE)/test/libc/dns: \
$(TEST_LIBC_DNS_BINS) \
$(TEST_LIBC_DNS_CHECKS)

View File

@@ -0,0 +1,653 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│
╚══════════════════════════════════════════════════════════════════════════════╝
│ @author (c) Marco Paland (info@paland.com) │
│ 2014-2019, PALANDesign Hannover, Germany │
│ │
│ @license The MIT License (MIT) │
│ │
│ Permission is hereby granted, free of charge, to any person obtaining a copy │
│ of this software and associated documentation files (the "Software"), to deal│
│ in the Software without restriction, including without limitation the rights │
│ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell │
│ copies of the Software, and to permit persons to whom the Software is │
│ furnished to do so, subject to the following conditions: │
│ │
│ The above copyright notice and this permission notice shall be included in │
│ all copies or substantial portions of the Software. │
│ │
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR │
│ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, │
│ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE │
│ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER │
│ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,│
│ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN │
│ THE SOFTWARE. │
└─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/progn.h"
#include "libc/bits/pushpop.h"
#include "libc/bits/safemacros.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
static char buffer[128];
#define Format(...) PROGN(snprintf(buffer, sizeof(buffer), __VA_ARGS__), buffer)
TEST(sprintf, test_space_flag) {
EXPECT_STREQ(" 42", Format("% d", 42));
EXPECT_STREQ("-42", Format("% d", -42));
EXPECT_STREQ(" 42", Format("% 5d", 42));
EXPECT_STREQ(" -42", Format("% 5d", -42));
EXPECT_STREQ(" 42", Format("% 15d", 42));
EXPECT_STREQ(" -42", Format("% 15d", -42));
EXPECT_STREQ(" -42", Format("% 15d", -42));
EXPECT_STREQ(" -42.987", Format("% 15.3f", -42.987));
EXPECT_STREQ(" 42.987", Format("% 15.3f", 42.987));
EXPECT_STREQ("Hello testing", Format("% s", "Hello testing"));
EXPECT_STREQ(" 1024", Format("% d", 1024));
EXPECT_STREQ("-1024", Format("% d", -1024));
EXPECT_STREQ(" 1024", Format("% i", 1024));
EXPECT_STREQ("-1024", Format("% i", -1024));
EXPECT_STREQ("1024", Format("% u", 1024));
EXPECT_STREQ("4294966272", Format("% u", 4294966272U));
EXPECT_STREQ("777", Format("% o", 511));
EXPECT_STREQ("37777777001", Format("% o", 4294966785U));
EXPECT_STREQ("1234abcd", Format("% x", 305441741));
EXPECT_STREQ("edcb5433", Format("% x", 3989525555U));
EXPECT_STREQ("1234ABCD", Format("% X", 305441741));
EXPECT_STREQ("EDCB5433", Format("% X", 3989525555U));
EXPECT_STREQ("x", Format("% c", 'x'));
}
TEST(sprintf, test_plus_flag) {
EXPECT_STREQ("+42", Format("%+d", 42));
EXPECT_STREQ("-42", Format("%+d", -42));
EXPECT_STREQ(" +42", Format("%+5d", 42));
EXPECT_STREQ(" -42", Format("%+5d", -42));
EXPECT_STREQ(" +42", Format("%+15d", 42));
EXPECT_STREQ(" -42", Format("%+15d", -42));
EXPECT_STREQ("+1024", Format("%+d", 1024));
EXPECT_STREQ("-1024", Format("%+d", -1024));
EXPECT_STREQ("+1024", Format("%+i", 1024));
EXPECT_STREQ("-1024", Format("%+i", -1024));
EXPECT_STREQ("1024", Format("%+u", 1024));
EXPECT_STREQ("4294966272", Format("%+u", 4294966272U));
EXPECT_STREQ("777", Format("%+o", 511));
EXPECT_STREQ("37777777001", Format("%+o", 4294966785U));
EXPECT_STREQ("1234abcd", Format("%+x", 305441741));
EXPECT_STREQ("edcb5433", Format("%+x", 3989525555U));
EXPECT_STREQ("1234ABCD", Format("%+X", 305441741));
EXPECT_STREQ("EDCB5433", Format("%+X", 3989525555U));
EXPECT_STREQ("+", Format("%+.0d", 0));
}
TEST(sprintf, test_flag0) {
EXPECT_STREQ("42", Format("%0d", 42));
EXPECT_STREQ("42", Format("%0ld", 42L));
EXPECT_STREQ("-42", Format("%0d", -42));
EXPECT_STREQ("00042", Format("%05d", 42));
EXPECT_STREQ("-0042", Format("%05d", -42));
EXPECT_STREQ("000000000000042", Format("%015d", 42));
EXPECT_STREQ("-00000000000042", Format("%015d", -42));
EXPECT_STREQ("000000000042.12", Format("%015.2f", 42.1234));
EXPECT_STREQ("00000000042.988", Format("%015.3f", 42.9876));
EXPECT_STREQ("-00000042.98760", Format("%015.5f", -42.9876));
}
TEST(sprintf, test_flag_minus) {
EXPECT_STREQ("42", Format("%-d", 42));
EXPECT_STREQ("-42", Format("%-d", -42));
EXPECT_STREQ("42 ", Format("%-5d", 42));
EXPECT_STREQ("-42 ", Format("%-5d", -42));
EXPECT_STREQ("42 ", Format("%-15d", 42));
EXPECT_STREQ("-42 ", Format("%-15d", -42));
EXPECT_STREQ("42", Format("%-0d", 42));
EXPECT_STREQ("-42", Format("%-0d", -42));
EXPECT_STREQ("42 ", Format("%-05d", 42));
EXPECT_STREQ("-42 ", Format("%-05d", -42));
EXPECT_STREQ("42 ", Format("%-015d", 42));
EXPECT_STREQ("-42 ", Format("%-015d", -42));
EXPECT_STREQ("42", Format("%0-d", 42));
EXPECT_STREQ("-42", Format("%0-d", -42));
EXPECT_STREQ("42 ", Format("%0-5d", 42));
EXPECT_STREQ("-42 ", Format("%0-5d", -42));
EXPECT_STREQ("42 ", Format("%0-15d", 42));
EXPECT_STREQ("-42 ", Format("%0-15d", -42));
}
TEST(sprintf, testAlternativeFormatting) {
EXPECT_STREQ("0", Format("%#x", 0));
EXPECT_STREQ("", Format("%#.0x", 0));
EXPECT_STREQ("0", Format("%#.1x", 0));
EXPECT_STREQ("", Format("%#.0llx", (long long)0));
EXPECT_STREQ("0x0000614e", Format("%#.8x", 0x614e));
EXPECT_STREQ("0b110", Format("%#b", 6));
}
TEST(sprintf, testHexBasePrefix_onlyConsumesLeadingZeroes) {
/* TODO(jart): Upstream bug fix for this behavior. */
EXPECT_STREQ("0x01", Format("%#04x", 0x1));
EXPECT_STREQ("0x12", Format("%#04x", 0x12));
EXPECT_STREQ("0x123", Format("%#04x", 0x123));
EXPECT_STREQ("0x1234", Format("%#04x", 0x1234));
}
TEST(sprintf, testBinaryBasePrefix_onlyConsumesLeadingZeroes) {
EXPECT_STREQ("0b01", Format("%#04b", 0b1));
EXPECT_STREQ("0b10", Format("%#04b", 0b10));
EXPECT_STREQ("0b101", Format("%#04b", 0b101));
EXPECT_STREQ("0b1010", Format("%#04b", 0b1010));
}
TEST(sprintf, testOctalBasePrefix_onlyConsumesLeadingZeroes) {
EXPECT_STREQ("0001", Format("%#04o", 01));
EXPECT_STREQ("0010", Format("%#04o", 010));
EXPECT_STREQ("0101", Format("%#04o", 0101));
EXPECT_STREQ("01010", Format("%#04o", 01010));
}
TEST(sprintf, test_specifier) {
EXPECT_STREQ("Hello testing", Format("Hello testing"));
EXPECT_STREQ("Hello testing", Format("%s", "Hello testing"));
EXPECT_STREQ("1024", Format("%d", 1024));
EXPECT_STREQ("-1024", Format("%d", -1024));
EXPECT_STREQ("1024", Format("%i", 1024));
EXPECT_STREQ("-1024", Format("%i", -1024));
EXPECT_STREQ("1024", Format("%u", 1024));
EXPECT_STREQ("4294966272", Format("%u", 4294966272U));
EXPECT_STREQ("777", Format("%o", 511));
EXPECT_STREQ("37777777001", Format("%o", 4294966785U));
EXPECT_STREQ("1234abcd", Format("%x", 305441741));
EXPECT_STREQ("edcb5433", Format("%x", 3989525555U));
EXPECT_STREQ("1234ABCD", Format("%X", 305441741));
EXPECT_STREQ("EDCB5433", Format("%X", 3989525555U));
EXPECT_STREQ("%", Format("%%"));
}
TEST(sprintf, test_width) {
EXPECT_STREQ("Hello testing", Format("%1s", "Hello testing"));
EXPECT_STREQ("1024", Format("%1d", 1024));
EXPECT_STREQ("-1024", Format("%1d", -1024));
EXPECT_STREQ("1024", Format("%1i", 1024));
EXPECT_STREQ("-1024", Format("%1i", -1024));
EXPECT_STREQ("1024", Format("%1u", 1024));
EXPECT_STREQ("4294966272", Format("%1u", 4294966272U));
EXPECT_STREQ("777", Format("%1o", 511));
EXPECT_STREQ("37777777001", Format("%1o", 4294966785U));
EXPECT_STREQ("1234abcd", Format("%1x", 305441741));
EXPECT_STREQ("edcb5433", Format("%1x", 3989525555U));
EXPECT_STREQ("1234ABCD", Format("%1X", 305441741));
EXPECT_STREQ("EDCB5433", Format("%1X", 3989525555U));
EXPECT_STREQ("x", Format("%1c", 'x'));
}
TEST(sprintf, test_width_20) {
/* TODO(jart): wut */
/* sprintf(buffer, "%20s", "Hello"); */
/* printf("'%s' %d\n", buffer, strlen(buffer)); */
/* EXPECT_STREQ(" Hello", buffer); */
EXPECT_STREQ(" 1024", Format("%20d", 1024));
EXPECT_STREQ(" -1024", Format("%20d", -1024));
EXPECT_STREQ(" 1024", Format("%20i", 1024));
EXPECT_STREQ(" -1024", Format("%20i", -1024));
EXPECT_STREQ(" 1024", Format("%20u", 1024));
EXPECT_STREQ(" 4294966272", Format("%20u", 4294966272U));
EXPECT_STREQ(" 777", Format("%20o", 511));
EXPECT_STREQ(" 37777777001", Format("%20o", 4294966785U));
EXPECT_STREQ(" 1234abcd", Format("%20x", 305441741));
EXPECT_STREQ(" edcb5433", Format("%20x", 3989525555U));
EXPECT_STREQ(" 1234ABCD", Format("%20X", 305441741));
EXPECT_STREQ(" EDCB5433", Format("%20X", 3989525555U));
EXPECT_STREQ(" x", Format("%20c", 'x'));
}
TEST(sprintf, test_width_star_20) {
EXPECT_STREQ(" Hello", Format("%*s", 20, "Hello"));
EXPECT_STREQ(" 1024", Format("%*d", 20, 1024));
EXPECT_STREQ(" -1024", Format("%*d", 20, -1024));
EXPECT_STREQ(" 1024", Format("%*i", 20, 1024));
EXPECT_STREQ(" -1024", Format("%*i", 20, -1024));
EXPECT_STREQ(" 1024", Format("%*u", 20, 1024));
EXPECT_STREQ(" 4294966272", Format("%*u", 20, 4294966272U));
EXPECT_STREQ(" 777", Format("%*o", 20, 511));
EXPECT_STREQ(" 37777777001", Format("%*o", 20, 4294966785U));
EXPECT_STREQ(" 1234abcd", Format("%*x", 20, 305441741));
EXPECT_STREQ(" edcb5433", Format("%*x", 20, 3989525555U));
EXPECT_STREQ(" 1234ABCD", Format("%*X", 20, 305441741));
EXPECT_STREQ(" EDCB5433", Format("%*X", 20, 3989525555U));
EXPECT_STREQ(" x", Format("%*c", 20, 'x'));
}
TEST(sprintf, test_width_minus_20) {
EXPECT_STREQ("Hello ", Format("%-20s", "Hello"));
EXPECT_STREQ("1024 ", Format("%-20d", 1024));
EXPECT_STREQ("-1024 ", Format("%-20d", -1024));
EXPECT_STREQ("1024 ", Format("%-20i", 1024));
EXPECT_STREQ("-1024 ", Format("%-20i", -1024));
EXPECT_STREQ("1024 ", Format("%-20u", 1024));
EXPECT_STREQ("1024.1234 ", Format("%-20.4f", 1024.1234));
EXPECT_STREQ("4294966272 ", Format("%-20u", 4294966272U));
EXPECT_STREQ("777 ", Format("%-20o", 511));
EXPECT_STREQ("37777777001 ", Format("%-20o", 4294966785U));
EXPECT_STREQ("1234abcd ", Format("%-20x", 305441741));
EXPECT_STREQ("edcb5433 ", Format("%-20x", 3989525555U));
EXPECT_STREQ("1234ABCD ", Format("%-20X", 305441741));
EXPECT_STREQ("EDCB5433 ", Format("%-20X", 3989525555U));
EXPECT_STREQ("x ", Format("%-20c", 'x'));
EXPECT_STREQ("| 9| |9 | | 9|", Format("|%5d| |%-2d| |%5d|", 9, 9, 9));
EXPECT_STREQ("| 10| |10| | 10|",
Format("|%5d| |%-2d| |%5d|", 10, 10, 10));
EXPECT_STREQ("| 9| |9 | | 9|",
Format("|%5d| |%-12d| |%5d|", 9, 9, 9));
EXPECT_STREQ("| 10| |10 | | 10|",
Format("|%5d| |%-12d| |%5d|", 10, 10, 10));
}
TEST(sprintf, test_width_0_minus_20) {
EXPECT_STREQ("Hello ", Format("%0-20s", "Hello"));
EXPECT_STREQ("1024 ", Format("%0-20d", 1024));
EXPECT_STREQ("-1024 ", Format("%0-20d", -1024));
EXPECT_STREQ("1024 ", Format("%0-20i", 1024));
EXPECT_STREQ("-1024 ", Format("%0-20i", -1024));
EXPECT_STREQ("1024 ", Format("%0-20u", 1024));
EXPECT_STREQ("4294966272 ", Format("%0-20u", 4294966272U));
EXPECT_STREQ("777 ", Format("%0-20o", 511));
EXPECT_STREQ("37777777001 ", Format("%0-20o", 4294966785U));
EXPECT_STREQ("1234abcd ", Format("%0-20x", 305441741));
EXPECT_STREQ("edcb5433 ", Format("%0-20x", 3989525555U));
EXPECT_STREQ("1234ABCD ", Format("%0-20X", 305441741));
EXPECT_STREQ("EDCB5433 ", Format("%0-20X", 3989525555U));
EXPECT_STREQ("x ", Format("%0-20c", 'x'));
}
TEST(sprintf, test_padding_20) {
EXPECT_STREQ("00000000000000001024", Format("%020d", 1024));
EXPECT_STREQ("-0000000000000001024", Format("%020d", -1024));
EXPECT_STREQ("00000000000000001024", Format("%020i", 1024));
EXPECT_STREQ("-0000000000000001024", Format("%020i", -1024));
EXPECT_STREQ("00000000000000001024", Format("%020u", 1024));
EXPECT_STREQ("00000000004294966272", Format("%020u", 4294966272U));
EXPECT_STREQ("00000000000000000777", Format("%020o", 511));
EXPECT_STREQ("00000000037777777001", Format("%020o", 4294966785U));
EXPECT_STREQ("0000000000001234abcd", Format("%020x", 305441741));
EXPECT_STREQ("000000000000edcb5433", Format("%020x", 3989525555U));
EXPECT_STREQ("0000000000001234ABCD", Format("%020X", 305441741));
EXPECT_STREQ("000000000000EDCB5433", Format("%020X", 3989525555U));
}
TEST(sprintf, test_padding_dot_20) {
EXPECT_STREQ("00000000000000001024", Format("%.20d", 1024));
EXPECT_STREQ("-00000000000000001024", Format("%.20d", -1024));
EXPECT_STREQ("00000000000000001024", Format("%.20i", 1024));
EXPECT_STREQ("-00000000000000001024", Format("%.20i", -1024));
EXPECT_STREQ("00000000000000001024", Format("%.20u", 1024));
EXPECT_STREQ("00000000004294966272", Format("%.20u", 4294966272U));
EXPECT_STREQ("00000000000000000777", Format("%.20o", 511));
EXPECT_STREQ("00000000037777777001", Format("%.20o", 4294966785U));
EXPECT_STREQ("0000000000001234abcd", Format("%.20x", 305441741));
EXPECT_STREQ("000000000000edcb5433", Format("%.20x", 3989525555U));
EXPECT_STREQ("0000000000001234ABCD", Format("%.20X", 305441741));
EXPECT_STREQ("000000000000EDCB5433", Format("%.20X", 3989525555U));
}
TEST(sprintf, test_padding_pound_020) {
EXPECT_STREQ("00000000000000001024", Format("%#020d", 1024));
EXPECT_STREQ("-0000000000000001024", Format("%#020d", -1024));
EXPECT_STREQ("00000000000000001024", Format("%#020i", 1024));
EXPECT_STREQ("-0000000000000001024", Format("%#020i", -1024));
EXPECT_STREQ("00000000000000001024", Format("%#020u", 1024));
EXPECT_STREQ("00000000004294966272", Format("%#020u", 4294966272U));
EXPECT_STREQ("00000000000000000777", Format("%#020o", 511));
EXPECT_STREQ("00000000037777777001", Format("%#020o", 4294966785U));
EXPECT_STREQ("0x00000000001234abcd", Format("%#020x", 305441741));
EXPECT_STREQ("0x0000000000edcb5433", Format("%#020x", 3989525555U));
EXPECT_STREQ("0x00000000001234ABCD", Format("%#020X", 305441741));
EXPECT_STREQ("0x0000000000EDCB5433", Format("%#020X", 3989525555U));
}
TEST(sprintf, test_padding_pound_20) {
EXPECT_STREQ(" 1024", Format("%#20d", 1024));
EXPECT_STREQ(" -1024", Format("%#20d", -1024));
EXPECT_STREQ(" 1024", Format("%#20i", 1024));
EXPECT_STREQ(" -1024", Format("%#20i", -1024));
EXPECT_STREQ(" 1024", Format("%#20u", 1024));
EXPECT_STREQ(" 4294966272", Format("%#20u", 4294966272U));
EXPECT_STREQ(" 0777", Format("%#20o", 511));
EXPECT_STREQ(" 037777777001", Format("%#20o", 4294966785U));
EXPECT_STREQ(" 0x1234abcd", Format("%#20x", 305441741));
EXPECT_STREQ(" 0xedcb5433", Format("%#20x", 3989525555U));
EXPECT_STREQ(" 0x1234ABCD", Format("%#20X", 305441741));
EXPECT_STREQ(" 0xEDCB5433", Format("%#20X", 3989525555U));
}
TEST(sprintf, test_padding_20_point_5) {
EXPECT_STREQ(" 01024", Format("%20.5d", 1024));
EXPECT_STREQ(" -01024", Format("%20.5d", -1024));
EXPECT_STREQ(" 01024", Format("%20.5i", 1024));
EXPECT_STREQ(" -01024", Format("%20.5i", -1024));
EXPECT_STREQ(" 01024", Format("%20.5u", 1024));
EXPECT_STREQ(" 4294966272", Format("%20.5u", 4294966272U));
EXPECT_STREQ(" 00777", Format("%20.5o", 511));
EXPECT_STREQ(" 37777777001", Format("%20.5o", 4294966785U));
EXPECT_STREQ(" 1234abcd", Format("%20.5x", 305441741));
EXPECT_STREQ(" 00edcb5433", Format("%20.10x", 3989525555U));
EXPECT_STREQ(" 1234ABCD", Format("%20.5X", 305441741));
EXPECT_STREQ(" 00EDCB5433", Format("%20.10X", 3989525555U));
}
TEST(sprintf, test_padding_neg_numbers) {
/* space padding */
EXPECT_STREQ("-5", Format("% 1d", -5));
EXPECT_STREQ("-5", Format("% 2d", -5));
EXPECT_STREQ(" -5", Format("% 3d", -5));
EXPECT_STREQ(" -5", Format("% 4d", -5));
/* zero padding */
EXPECT_STREQ("-5", Format("%01d", -5));
EXPECT_STREQ("-5", Format("%02d", -5));
EXPECT_STREQ("-05", Format("%03d", -5));
EXPECT_STREQ("-005", Format("%04d", -5));
}
TEST(sprintf, test_float_padding_neg_numbers) {
/* space padding */
EXPECT_STREQ("-5.0", Format("% 3.1f", -5.));
EXPECT_STREQ("-5.0", Format("% 4.1f", -5.));
EXPECT_STREQ(" -5.0", Format("% 5.1f", -5.));
/* zero padding */
EXPECT_STREQ("-5.0", Format("%03.1f", -5.));
EXPECT_STREQ("-5.0", Format("%04.1f", -5.));
EXPECT_STREQ("-05.0", Format("%05.1f", -5.));
/* zero padding no decimal point */
EXPECT_STREQ("-5", Format("%01.0f", -5.));
EXPECT_STREQ("-5", Format("%02.0f", -5.));
EXPECT_STREQ("-05", Format("%03.0f", -5.));
}
TEST(sprintf, test_length) {
EXPECT_STREQ("", Format("%.0s", "Hello testing"));
EXPECT_STREQ(" ", Format("%20.0s", "Hello testing"));
EXPECT_STREQ("", Format("%.s", "Hello testing"));
EXPECT_STREQ(" ", Format("%20.s", "Hello testing"));
EXPECT_STREQ(" 1024", Format("%20.0d", 1024));
EXPECT_STREQ(" -1024", Format("%20.0d", -1024));
EXPECT_STREQ(" ", Format("%20.d", 0));
EXPECT_STREQ(" 1024", Format("%20.0i", 1024));
EXPECT_STREQ(" -1024", Format("%20.i", -1024));
EXPECT_STREQ(" ", Format("%20.i", 0));
EXPECT_STREQ(" 1024", Format("%20.u", 1024));
EXPECT_STREQ(" 4294966272", Format("%20.0u", 4294966272U));
EXPECT_STREQ(" ", Format("%20.u", 0U));
EXPECT_STREQ(" 777", Format("%20.o", 511));
EXPECT_STREQ(" 37777777001", Format("%20.0o", 4294966785U));
EXPECT_STREQ(" ", Format("%20.o", 0U));
EXPECT_STREQ(" 1234abcd", Format("%20.x", 305441741));
EXPECT_STREQ(" 1234abcd",
Format("%50.x", 305441741));
EXPECT_STREQ(" 1234abcd 12345",
Format("%50.x%10.u", 305441741, 12345));
EXPECT_STREQ(" edcb5433", Format("%20.0x", 3989525555U));
EXPECT_STREQ(" ", Format("%20.x", 0U));
EXPECT_STREQ(" 1234ABCD", Format("%20.X", 305441741));
EXPECT_STREQ(" EDCB5433", Format("%20.0X", 3989525555U));
EXPECT_STREQ(" ", Format("%20.X", 0U));
EXPECT_STREQ(" ", Format("%02.0u", 0U));
EXPECT_STREQ(" ", Format("%02.0d", 0));
}
TEST(sprintf, test_float) {
#ifndef __FINITE_MATH_ONLY__
EXPECT_STREQ("nan", Format("%.4f", NAN));
#endif
EXPECT_STREQ("3.1415", Format("%.4f", 3.1415354));
EXPECT_STREQ("30343.142", Format("%.3f", 30343.1415354));
EXPECT_STREQ("34", Format("%.0f", 34.1415354));
EXPECT_STREQ("1", Format("%.0f", 1.3));
EXPECT_STREQ("2", Format("%.0f", 1.55));
EXPECT_STREQ("1.6", Format("%.1f", 1.64));
EXPECT_STREQ("42.90", Format("%.2f", 42.8952));
EXPECT_STREQ("42.895200000", Format("%.9f", 42.8952));
EXPECT_STREQ("42.8952230000", Format("%.10f", 42.895223));
/* this testcase checks, that the precision is truncated to 9 digits. */
/* a perfect working float should return the whole number */
EXPECT_STREQ("42.895223123000", Format("%.12f", 42.89522312345678));
/* this testcase checks, that the precision is truncated AND rounded to 9 */
/* digits. a perfect working float should return the whole number */
EXPECT_STREQ("42.895223877000", Format("%.12f", 42.89522387654321));
EXPECT_STREQ(" 42.90", Format("%6.2f", 42.8952));
EXPECT_STREQ("+42.90", Format("%+6.2f", 42.8952));
EXPECT_STREQ("+42.9", Format("%+5.1f", 42.9252));
EXPECT_STREQ("42.500000", Format("%f", 42.5));
EXPECT_STREQ("42.5", Format("%.1f", 42.5));
EXPECT_STREQ("42167.000000", Format("%f", 42167.0));
EXPECT_STREQ("-12345.987654321", Format("%.9f", -12345.987654321));
EXPECT_STREQ("4.0", Format("%.1f", 3.999));
EXPECT_STREQ("4", Format("%.0f", 3.5));
EXPECT_STREQ("4", Format("%.0f", 4.5));
EXPECT_STREQ("3", Format("%.0f", 3.49));
EXPECT_STREQ("3.5", Format("%.1f", 3.49));
EXPECT_STREQ("a0.5 ", Format("a%-5.1f", 0.5));
EXPECT_STREQ("a0.5 end", Format("a%-5.1fend", 0.5));
/* out of range in the moment, need to be fixed by someone */
EXPECT_STREQ("INFINITY", Format("%.1f", 1E20));
}
TEST(sprintf, test_types) {
EXPECT_STREQ("0", Format("%i", 0));
EXPECT_STREQ("1234", Format("%i", 1234));
EXPECT_STREQ("32767", Format("%i", 32767));
EXPECT_STREQ("-32767", Format("%i", -32767));
EXPECT_STREQ("30", Format("%li", 30L));
EXPECT_STREQ("-2147483647", Format("%li", -2147483647L));
EXPECT_STREQ("2147483647", Format("%li", 2147483647L));
EXPECT_STREQ("30", Format("%lli", 30LL));
EXPECT_STREQ("-9223372036854775807", Format("%lli", -9223372036854775807LL));
EXPECT_STREQ("9223372036854775807", Format("%lli", 9223372036854775807LL));
EXPECT_STREQ("100000", Format("%lu", 100000L));
EXPECT_STREQ("4294967295", Format("%lu", 0xFFFFFFFFL));
EXPECT_STREQ("281474976710656", Format("%llu", 281474976710656LLU));
EXPECT_STREQ("18446744073709551615", Format("%llu", 18446744073709551615LLU));
EXPECT_STREQ("2147483647", Format("%zu", 2147483647UL));
EXPECT_STREQ("2147483647", Format("%zd", 2147483647UL));
if (sizeof(size_t) == sizeof(long)) {
EXPECT_STREQ("-2147483647", Format("%zi", -2147483647L));
} else {
EXPECT_STREQ("-2147483647", Format("%zi", -2147483647LL));
}
EXPECT_STREQ("1110101001100000", Format("%b", 60000));
EXPECT_STREQ("101111000110000101001110", Format("%lb", 12345678L));
EXPECT_STREQ("165140", Format("%o", 60000));
EXPECT_STREQ("57060516", Format("%lo", 12345678L));
EXPECT_STREQ("12345678", Format("%lx", 0x12345678L));
EXPECT_STREQ("1234567891234567", Format("%llx", 0x1234567891234567LLU));
EXPECT_STREQ("abcdefab", Format("%lx", 0xabcdefabL));
EXPECT_STREQ("ABCDEFAB", Format("%lX", 0xabcdefabL));
EXPECT_STREQ("v", Format("%c", 'v'));
EXPECT_STREQ("wv", Format("%cv", 'w'));
EXPECT_STREQ("A Test", Format("%s", "A Test"));
EXPECT_STREQ("255", Format("%hhu", 0xFFFFUL));
EXPECT_STREQ("a", Format("%tx", &buffer[10] - &buffer[0]));
/* TBD */
EXPECT_STREQ("-2147483647", Format("%ji", (intmax_t)-2147483647L));
}
TEST(sprintf, testOverflow_truncationNotSaturation) {
errno = 0;
EXPECT_STREQ("13398", Format("%hu", 0x123456UL));
EXPECT_EQ(ERANGE, errno);
errno = 0;
EXPECT_STREQ("Test16 65535", Format("%s%hhi %hu", "Test", 10000, 0xFFFFFFFF));
EXPECT_EQ(ERANGE, errno);
}
TEST(sprintf, test_pointer) {
sprintf(buffer, "%p", (void *)0x1234U);
if (sizeof(void *) == 4U) {
EXPECT_STREQ("00001234", buffer);
} else {
EXPECT_STREQ("000000001234", buffer);
}
sprintf(buffer, "%p", (void *)0x12345678U);
if (sizeof(void *) == 4U) {
EXPECT_STREQ("12345678", buffer);
} else {
EXPECT_STREQ("000012345678", buffer);
}
sprintf(buffer, "%p-%p", (void *)0x12345678U, (void *)0x7EDCBA98U);
if (sizeof(void *) == 4U) {
EXPECT_STREQ("12345678-7edcba98", buffer);
} else {
EXPECT_STREQ("000012345678-00007edcba98", buffer);
}
if (sizeof(uintptr_t) == sizeof(uint64_t)) {
sprintf(buffer, "%p", (void *)(uintptr_t)0xFFFFFFFFU);
EXPECT_STREQ("0000ffffffff", buffer);
} else {
sprintf(buffer, "%p", (void *)(uintptr_t)0xFFFFFFFFU);
EXPECT_STREQ("ffffffff", buffer);
}
}
TEST(sprintf, test_unknown_flag) {
EXPECT_STREQ("kmarco", Format("%kmarco", 42, 37));
}
TEST(sprintf, test_buffer_length) {
int ret;
/* EXPECT_EQ(4, snprintf(pushpop(NULL), 10, "%s", "Test")); */
EXPECT_EQ(4, snprintf(pushpop(NULL), 0, "%s", "Test"));
buffer[0] = (char)0xA5;
ret = snprintf(buffer, 0, "%s", "Test");
EXPECT_TRUE(buffer[0] == (char)0xA5);
EXPECT_TRUE(ret == 4);
buffer[0] = (char)0xCC;
snprintf(buffer, 1, "%s", pushpop(&"Test"[0]));
EXPECT_TRUE(buffer[0] == '\0');
snprintf(buffer, 2, "%s", pushpop(&"Hello"[0]));
EXPECT_STREQ("H", buffer);
}
TEST(sprintf, test_ret_value) {
int ret;
ret = snprintf(buffer, 6, "0%s", "1234");
EXPECT_STREQ("01234", buffer);
EXPECT_TRUE(ret == 5);
ret = snprintf(buffer, 6, "0%s", pushpop(&"12345"[0]));
EXPECT_STREQ("01234", buffer);
EXPECT_TRUE(ret == 6); /* '5' is truncated */
ret = snprintf(buffer, 6, "0%s", pushpop(&"1234567"[0]));
EXPECT_STREQ("01234", buffer);
EXPECT_TRUE(ret == 8); /* '567' are truncated */
ret = snprintf(buffer, 10, pushpop(&"hello, world"[0]));
EXPECT_TRUE(ret == 12);
ret = snprintf(buffer, 3, "%d", pushpop(10000));
EXPECT_TRUE(ret == 5);
EXPECT_TRUE(strlen(buffer) == 2U);
EXPECT_TRUE(buffer[0] == '1');
EXPECT_TRUE(buffer[1] == '0');
EXPECT_TRUE(buffer[2] == '\0');
}
TEST(sprintf, test_misc) {
EXPECT_STREQ("53000atest-20 bit",
Format("%u%u%ctest%d %s", 5, 3000, 'a', -20, "bit"));
EXPECT_STREQ("0.33", Format("%.*f", 2, 0.33333333));
EXPECT_STREQ("1", Format("%.*d", -1, 1));
EXPECT_STREQ("foo", Format("%.3s", "foobar"));
EXPECT_STREQ(" ", Format("% .0d", 0));
EXPECT_STREQ(" 00004", Format("%10.5d", 4));
EXPECT_STREQ("hi x", Format("%*sx", -3, "hi"));
}
TEST(sprintf, test_snprintf) {
snprintf(buffer, 100U, "%d", -1000);
EXPECT_STREQ("-1000", buffer);
snprintf(buffer, 3U, "%d", pushpop(-1000));
EXPECT_STREQ("-1", buffer);
}
testonly void vsnprintf_builder_1(char *buf, ...) {
va_list args;
va_start(args, buf);
vsnprintf(buf, 100U, "%d", args);
va_end(args);
}
testonly void vsnprintf_builder_3(char *buf, ...) {
va_list args;
va_start(args, buf);
vsnprintf(buf, 100U, "%d %d %s", args);
va_end(args);
}
TEST(sprintf, test_vsnprintf) {
vsnprintf_builder_1(buffer, -1);
EXPECT_STREQ("-1", buffer);
vsnprintf_builder_3(buffer, 3, -1000, "test");
EXPECT_STREQ("3 -1000 test", buffer);
}
TEST(xasprintf, test) {
void *pp;
ASSERT_STREQ("hello 123", (pp = xasprintf("hello %d", 123)));
free(pp);
}
TEST(xasprintf, pointer_doesntShowNonCanonicalZeroes) {
ASSERT_STREQ("100000000010", gc(xasprintf("%p", 0x0000100000000010)));
ASSERT_STREQ("0x100000000010", gc(xasprintf("%#p", 0x0000100000000010)));
}
TEST(xasprintf, nonCanonicalPointer_discardsHighBits_ratherThanSaturate) {
ASSERT_STREQ("100000000010", gc(xasprintf("%p", 0x1000100000000010)));
ASSERT_STREQ("0x100000000010", gc(xasprintf("%#p", 0x1000100000000010)));
ASSERT_STREQ("7fffffffffff", gc(xasprintf("%p", 0x7fffffffffff)));
ASSERT_STREQ("0x7fffffffffff", gc(xasprintf("%#p", 0x7fffffffffff)));
}
TEST(snprintf, testFixedWidthString_wontOverrunInput) {
const int N = 2;
char *buf = tmalloc(N + 1);
char *inp = memcpy(tmalloc(N), "hi", N);
EXPECT_EQ(2, snprintf(buf, N + 1, "%.*s", N, inp));
EXPECT_BINEQ(u"hi ", buf);
tfree(inp);
tfree(buf);
}
TEST(snprintf, testFixedWidthStringIsNull_wontOverrunBuffer) {
int N = 3;
char *buf = tmalloc(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)));
EXPECT_BINEQ(u"(nu ", buf);
EXPECT_EQ(4, snprintf(buf, N + 1, "%`.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"NUL ", buf);
EXPECT_EQ(4, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"NUL ", buf);
tfree(buf);
}
TEST(snprintf, testFixedWidthStringIsNull_wontLeakMemory) {
int N = 16;
char *buf = tmalloc(N + 1);
memset(buf, 0, N + 1);
EXPECT_EQ(6, snprintf(buf, N + 1, "%.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"(null)           ", buf);
memset(buf, 0, N + 1);
EXPECT_EQ(6, snprintf(buf, N + 1, "%#.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"(null)           ", buf);
memset(buf, 0, N + 1);
EXPECT_EQ(4, snprintf(buf, N + 1, "%`.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"NULL             ", buf);
memset(buf, 0, N + 1);
EXPECT_EQ(4, snprintf(buf, N + 1, "%`#.*s", pushpop(N), pushpop(NULL)));
EXPECT_BINEQ(u"NULL             ", buf);
tfree(buf);
}

View File

@@ -0,0 +1,76 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
/* MODE=tiny makes these dependencies optional */
STATIC_YOINK("strnwidth");
STATIC_YOINK("strnwidth16");
STATIC_YOINK("wcsnwidth");
TEST(SUITE(sprintf), testStringLength) {
ASSERT_STREQ("This", Format(FORMAT("%.4"), STRING("This is a test")));
ASSERT_STREQ("test", Format(FORMAT("%.4"), STRING("test")));
ASSERT_STREQ("123", Format(FORMAT("%.7"), STRING("123")));
ASSERT_STREQ("", Format(FORMAT("%.7"), STRING("")));
ASSERT_STREQ("1234ab", Format(FORMAT("%.4") FORMAT("%.2"), STRING("123456"),
STRING("abcdef")));
ASSERT_STREQ(FORMAT(".2"), Format(FORMAT("%.4.2"), STRING("123456")));
ASSERT_STREQ("123", Format(FORMAT("%.*"), 3, STRING("123456")));
}
TEST(SUITE(sprintf), testCharacterCounting) {
ASSERT_STREQ(" ♥♦♣♠☺☻▲", Format(FORMAT("%16"), STRING("♥♦♣♠☺☻▲")));
}
TEST(SUITE(snprintf), testTableFlip) {
EXPECT_STREQ("Table flip ", Format("%-20ls", L"Table flip"));
EXPECT_STREQ("(╯°□°)╯︵ ┻━┻ ", Format("%-20ls", L"(╯°□°)╯︵ ┻━┻"));
EXPECT_STREQ("ちゃぶ台返し ", Format("%-20ls", L"ちゃぶ台返し"));
EXPECT_STREQ(" (╯°□°)╯︵ ┻━┻", Format("%20ls", L"(╯°□°)╯︵ ┻━┻"));
EXPECT_STREQ(" ちゃぶ台返し", Format("%20ls", L"ちゃぶ台返し"));
}
TEST(SUITE(snprintf), testCombiningWidth) {
EXPECT_STREQ("H̲E̲L̲L̲O̲ ",
Format("%-10ls", L"H\u0332E\u0332L\u0332L\u0332O\u0332"));
EXPECT_STREQ(" H̲E̲L̲L̲O̲",
Format("%10hs", u"H\u0332E\u0332L\u0332L\u0332O\u0332"));
}
TEST(SUITE(snprintf), testQuoting) {
EXPECT_STREQ("\\\"hi┻\\'━┻", Format("%'s", "\"hi┻'━┻"));
EXPECT_STREQ(STRINGIFY("\"hi┻\'━┻"), Format("%`'s", "\"hi┻'━┻"));
EXPECT_STREQ(STRINGIFY("\177\"hi┻\'━┻"), Format("%`'s", "\x7f\"hi┻'━┻"));
}
TEST(SUITE(snprintf), testBing_cString_stopsAtNulTerminator) {
EXPECT_STREQ("♥♦♣♠", Format("%#s", "\3\4\5\6\0\3\4\5\6"));
}
TEST(SUITE(snprintf), testBing_precisionString_showsTrueBinary) {
EXPECT_STREQ("♥♦♣♠ ♥♦♣♠", Format("%#.*s", 9, "\3\4\5\6\0\3\4\5\6"));
}
TEST(SUITE(snprintf), testStringPrecision_showsTrueBinary) {
EXPECT_STREQ("\3\4\0", Format("%.*s", 3, "\3\4\0"));
}
TEST(SUITE(snprintf), testPrecision_usesCodepointCount) {
EXPECT_STREQ("ちゃぶ台返し", Format("%.*s", 6, "ちゃぶ台返し"));
}

View File

@@ -0,0 +1,60 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/bits/progn.h"
#include "libc/bits/safemacros.h"
#include "libc/fmt/fmt.h"
#include "libc/testlib/testlib.h"
static char buffer[128];
#define Format(...) PROGN(snprintf(buffer, sizeof(buffer), __VA_ARGS__), buffer)
/**
* @fileoverview String formatting tests.
*
* We use textual includes here to test UTF-8, UTF-16, and UTF-32 at the
* same time, since Cosmopolitan is designed to support them all without
* conditions.
*/
#define SUITE(NAME) NAME##s
#define FORMAT(STR) STR "s"
#define STRING(STR) STR
#include "test/libc/fmt/sprintf_s.inc"
#undef SUITE
#undef FORMAT
#undef STRING
#define SUITE(NAME) NAME##hs
#define FORMAT(STR) STR "hs"
#define STRING(STR) u##STR
#include "test/libc/fmt/sprintf_s.inc"
#undef SUITE
#undef FORMAT
#undef STRING
#define SUITE(NAME) NAME##ls
#define FORMAT(STR) STR "ls"
#define STRING(STR) L##STR
#include "test/libc/fmt/sprintf_s.inc"
#undef SUITE
#undef FORMAT
#undef STRING

144
test/libc/fmt/sscanf_test.c Normal file
View File

@@ -0,0 +1,144 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/limits.h"
#include "libc/mem/mem.h"
#include "libc/testlib/testlib.h"
#define sscanf1(STR, FMT) \
({ \
errno = 0; \
intmax_t x = 0; \
EXPECT_EQ(1, sscanf(STR, FMT, &x)); \
x; \
})
TEST(sscanf, testMultiple) {
int a, b, c;
ASSERT_EQ(3, sscanf("123 123 123", "%d %x %o", &a, &b, &c));
EXPECT_EQ(123, a);
EXPECT_EQ(0x123, b);
EXPECT_EQ(0123, c);
}
TEST(sscanf, testDecimal) {
EXPECT_EQ(123, sscanf1("123", "%d"));
EXPECT_EQ(123, sscanf1("123", "%n"));
EXPECT_EQ(123, sscanf1("123", "%u"));
EXPECT_EQ((uint32_t)-123, sscanf1("-123", "%d"));
}
TEST(sscanf, testHex) {
EXPECT_EQ(0x123, sscanf1("123", "%x"));
EXPECT_EQ(0x123, sscanf1("0x123", "%x"));
EXPECT_EQ(0x123, sscanf1("0123", "%x"));
EXPECT_EQ(INTMAX_MAX,
sscanf1("170141183460469231731687303715884105727", "%jd"));
EXPECT_EQ(INTMAX_MIN,
sscanf1("-170141183460469231731687303715884105728", "%jd"));
EXPECT_EQ(UINTMAX_MAX, sscanf1("0xffffffffffffffffffffffffffffffff", "%jx"));
}
TEST(sscanf, testOctal) {
EXPECT_EQ(0123, sscanf1("123", "%o"));
EXPECT_EQ(0123, sscanf1("0123", "%o"));
}
TEST(sscanf, testNonDirectiveCharacterMatching) {
EXPECT_EQ(0, sscanf("", ""));
EXPECT_EQ(0, sscanf("%", "%%"));
}
TEST(sscanf, testCharacter) {
char c = 0;
EXPECT_EQ(1, sscanf("a", "%c", &c));
EXPECT_EQ('a', c);
}
TEST(sscanf, testStringBuffer) {
char s1[32], s2[32];
ASSERT_EQ(2, sscanf("abc xyz", "%s %s", s1, s2));
EXPECT_STREQ("abc", &s1[0]);
EXPECT_STREQ("xyz", &s2[0]);
}
TEST(sscanf, testStringBuffer_gothicUtf8ToUtf8_roundTrips) {
char s1[64], s2[64];
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63s %63s", s1, s2));
EXPECT_STREQ("𐌰𐌱𐌲𐌳", s1);
EXPECT_STREQ("𐌴𐌵𐌶𐌷", s2);
}
TEST(sscanf, testStringBuffer_gothicUtf8ToUtf16) {
char16_t s1[64], s2[64];
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63hs %63hs", s1, s2));
EXPECT_STREQ(u"𐌰𐌱𐌲𐌳", s1);
EXPECT_STREQ(u"𐌴𐌵𐌶𐌷", s2);
}
TEST(sscanf, testStringBuffer_gothicUtf8ToUtf32) {
wchar_t s1[64], s2[64];
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%63ls %63ls", s1, s2));
EXPECT_STREQ(L"𐌰𐌱𐌲𐌳", s1);
EXPECT_STREQ(L"𐌴𐌵𐌶𐌷", s2);
}
TEST(sscanf, testStringBuffer_allocatingBehavior) {
char *s1, *s2;
ASSERT_EQ(2, sscanf("𐌰𐌱𐌲𐌳 𐌴𐌵𐌶𐌷", "%ms %ms", &s1, &s2));
EXPECT_STREQ("𐌰𐌱𐌲𐌳", s1);
EXPECT_STREQ("𐌴𐌵𐌶𐌷", s2);
free(s1);
free(s2);
}
TEST(sscanf, testPracticalBusinessApplication) {
unsigned start, stop;
char width;
ASSERT_EQ(1, sscanf("0BF3..", "%x", &start));
EXPECT_EQ(0x0BF3, start);
ASSERT_EQ(3, sscanf("0BF3..0BF8;N # So [6] TAMIL DAY SIGN",
"%x..%x;%c", &start, &stop, &width));
EXPECT_EQ(0x0BF3, start);
EXPECT_EQ(0x0BF8, stop);
EXPECT_EQ('N', width);
}
TEST(sscanf, socketListenUri) {
char proto[4];
unsigned char ip4[4];
uint16_t port;
ASSERT_EQ(6, sscanf("tcp:127.0.0.1:31337", "%3s:%hhu.%hhu.%hhu.%hhu:%hu",
proto, &ip4[0], &ip4[1], &ip4[2], &ip4[3], &port));
ASSERT_STREQ("tcp", proto);
ASSERT_EQ(127, ip4[0]);
ASSERT_EQ(0, ip4[1]);
ASSERT_EQ(0, ip4[2]);
ASSERT_EQ(1, ip4[3]);
ASSERT_EQ(31337, port);
}
TEST(sscanf, testDiscard_notIncludedInCount) {
char buf[8];
ASSERT_EQ(1, sscanf("hello there", "%*s %8s", buf));
EXPECT_STREQ("there", buf);
}

View File

@@ -0,0 +1,54 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
/*
* If these tests break, it's probably because
* libc/sysv/consts.sh changed and
* libc/sysv/kErrnoNames.S needs updating.
*/
TEST(strerror, enosys) {
if (IsTiny()) return;
EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS));
}
TEST(strerror, symbolizingTheseNumbersAsErrorsIsHeresyInUnixStyle) {
EXPECT_STARTSWITH("E?/err=0/errno:0/GetLastError:0", strerror(0));
EXPECT_STARTSWITH("E?", strerror(-1));
}
TEST(strerror, enotconn_orLinkerIsntUsingLocaleC_orCodeIsOutOfSync) {
if (IsTiny()) return;
EXPECT_STARTSWITH("ENOTCONN", strerror(ENOTCONN));
}
TEST(strerror, exfull_orLinkerIsntUsingLocaleC_orCodeIsOutOfSync) {
if (IsLinux() && !IsTiny()) {
EXPECT_STARTSWITH("EXFULL", strerror(EXFULL));
} else {
EXPECT_STARTSWITH("E?", strerror(EXFULL));
}
}

55
test/libc/fmt/test.mk Normal file
View File

@@ -0,0 +1,55 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_FMT
TEST_LIBC_FMT_SRCS := $(wildcard test/libc/fmt/*.c)
TEST_LIBC_FMT_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_FMT_SRCS))
TEST_LIBC_FMT_COMS = $(TEST_LIBC_FMT_OBJS:%.o=%.com)
TEST_LIBC_FMT_BINS = $(TEST_LIBC_FMT_COMS) $(TEST_LIBC_FMT_COMS:%=%.dbg)
TEST_LIBC_FMT_TESTS = $(TEST_LIBC_FMT_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_FMT_OBJS = \
$(TEST_LIBC_FMT_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_FMT_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_FMT_CHECKS = \
$(TEST_LIBC_FMT_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_FMT_DIRECTDEPS = \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_UNICODE \
LIBC_X
TEST_LIBC_FMT_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_FMT_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/fmt/fmt.pkg: \
$(TEST_LIBC_FMT_OBJS) \
$(foreach x,$(TEST_LIBC_FMT_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/fmt/%.com.dbg: \
$(TEST_LIBC_FMT_DEPS) \
o/$(MODE)/test/libc/fmt/%.o \
o/$(MODE)/test/libc/fmt/fmt.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_FMT_OBJS): \
$(BUILD_FILES) \
test/libc/fmt/test.mk
.PHONY: o/$(MODE)/test/libc/fmt
o/$(MODE)/test/libc/fmt: \
$(TEST_LIBC_FMT_BINS) \
$(TEST_LIBC_FMT_CHECKS)

View File

@@ -0,0 +1,70 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/packsswb.h"
#include "libc/intrin/packuswb.h"
#include "libc/limits.h"
#include "libc/nexgen32e/kcpuids.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0};
TEST(packuswb, test) {
unsigned char B[16] = {0};
packuswb(B, S, S);
EXPECT_EQ(0, B[0]);
EXPECT_EQ(128, B[1]);
EXPECT_EQ(0, B[2]);
EXPECT_EQ(255, B[3]);
EXPECT_EQ(255, B[4]);
EXPECT_EQ(0, B[5]);
EXPECT_EQ(0, B[6]);
EXPECT_EQ(0, B[7]);
EXPECT_EQ(0, B[8]);
EXPECT_EQ(128, B[9]);
EXPECT_EQ(0, B[10]);
EXPECT_EQ(255, B[11]);
EXPECT_EQ(255, B[12]);
EXPECT_EQ(0, B[13]);
EXPECT_EQ(0, B[14]);
EXPECT_EQ(0, B[15]);
}
TEST(packsswb, test) {
const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0};
signed char B[16] = {0};
packsswb(B, S, S);
EXPECT_EQ(0, B[0]);
EXPECT_EQ(127, B[1]);
EXPECT_EQ(-128, B[2]);
EXPECT_EQ(127, B[3]);
EXPECT_EQ(127, B[4]);
EXPECT_EQ(-128, B[5]);
EXPECT_EQ(0, B[6]);
EXPECT_EQ(0, B[7]);
EXPECT_EQ(0, B[8]);
EXPECT_EQ(127, B[9]);
EXPECT_EQ(-128, B[10]);
EXPECT_EQ(127, B[11]);
EXPECT_EQ(127, B[12]);
EXPECT_EQ(-128, B[13]);
EXPECT_EQ(0, B[14]);
EXPECT_EQ(0, B[15]);
}

View File

@@ -0,0 +1,55 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/paddsw.h"
#include "libc/intrin/paddw.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(paddw, test) {
short A[8] = {7};
short B[8] = {11};
short C[8];
paddw(C, A, B);
EXPECT_EQ(18, C[0]);
}
TEST(paddsw, test) {
short A[8] = {7};
short B[8] = {11};
short C[8];
paddsw(C, A, B);
EXPECT_EQ(18, C[0]);
}
TEST(paddw, testOverflow_wrapsAround) {
short A[8] = {SHRT_MAX, SHRT_MIN};
short B[8] = {1, -1};
paddw(A, A, B);
EXPECT_EQ(SHRT_MIN, A[0]);
EXPECT_EQ(SHRT_MAX, A[1]);
}
TEST(paddsw, testOverflow_saturates) {
short A[8] = {SHRT_MAX, SHRT_MIN};
short B[8] = {1, -1};
paddsw(A, A, B);
EXPECT_EQ(SHRT_MAX, A[0]);
EXPECT_EQ(SHRT_MIN, A[1]);
}

View File

@@ -0,0 +1,87 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/palignr.h"
#include "libc/testlib/testlib.h"
const int A[4] = {1, 2, 3, 4};
const int B[4] = {5, 6, 7, 8};
TEST(palignr, testLeftpad) {
int C[4] = {0};
palignr(C, B, A, 12);
EXPECT_EQ(4, C[0]);
EXPECT_EQ(5, C[1]);
EXPECT_EQ(6, C[2]);
EXPECT_EQ(7, C[3]);
}
TEST(palignr, test0) {
int C[4];
palignr(C, B, A, 0);
EXPECT_EQ(1, C[0]);
EXPECT_EQ(2, C[1]);
EXPECT_EQ(3, C[2]);
EXPECT_EQ(4, C[3]);
}
TEST(palignr, test4) {
int C[4];
palignr(C, B, A, 4);
EXPECT_EQ(2, C[0]);
EXPECT_EQ(3, C[1]);
EXPECT_EQ(4, C[2]);
EXPECT_EQ(5, C[3]);
}
TEST(palignr, test12) {
int C[4];
palignr(C, B, A, 12);
EXPECT_EQ(4, C[0]);
EXPECT_EQ(5, C[1]);
EXPECT_EQ(6, C[2]);
EXPECT_EQ(7, C[3]);
}
TEST(palignr, test16) {
int C[4];
palignr(C, B, A, 16);
EXPECT_EQ(5, C[0]);
EXPECT_EQ(6, C[1]);
EXPECT_EQ(7, C[2]);
EXPECT_EQ(8, C[3]);
}
TEST(palignr, test20) {
int C[4] = {-1, -1, -1, -1};
palignr(C, B, A, 20);
EXPECT_EQ(6, C[0]);
EXPECT_EQ(7, C[1]);
EXPECT_EQ(8, C[2]);
EXPECT_EQ(0, C[3]);
}
TEST(palignr, test32) {
int C[4] = {-1, -1, -1, -1};
palignr(C, B, A, 32);
EXPECT_EQ(0, C[0]);
EXPECT_EQ(0, C[1]);
EXPECT_EQ(0, C[2]);
EXPECT_EQ(0, C[3]);
}

View File

@@ -0,0 +1,46 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/phaddsw.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
/* clang-format off */
FIXTURE(phaddsw, disableHardwareExtensions) {
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
}
TEST(phaddsw, testOverflow_saturates) {
short M[2][8] = {
{0x7fff, 0, 0x7fff, 1, 0x7fff, 0x7fff, 20777, -16389},
{-28040, 13318, -1336, -24798, -13876, 3599, -7346, -23575},
};
phaddsw(M[0], M[0], M[1]);
EXPECT_SHRTMATRIXEQ(2, 8, M, "\n\
32767 32767 32767 4388 -14722 -26134 -10277 -30921\n\
-28040 13318 -1336 -24798 -13876 3599 -7346 -23575");
}
TEST(phaddsw, testAliasing_isOk) {
short M[1][8] = {{0,1,2,3,4,5,6,7}};
phaddsw(M[0],M[0],M[0]);
EXPECT_SHRTMATRIXEQ(1, 8, M, "\n\
1 5 9 13 1 5 9 13");
}

View File

@@ -0,0 +1,48 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/phaddw.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
/* clang-format off */
FIXTURE(phaddw, disableHardwareExtensions) {
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
}
TEST(phaddw, testOverflow_wrapsAround) {
short M[2][8] = {
{0x7fff, 0, 0x7fff, 1, 13004, -30425, 20777, -16389},
{-28040, 13318, -1336, -24798, -13876, 3599, -7346, -23575},
};
phaddw(M[0], M[0], M[1]);
EXPECT_SHRTMATRIXEQ(2, 8, M, "\n\
32767 -32768 -17421 4388 -14722 -26134 -10277 -30921\n\
-28040 13318 -1336 -24798 -13876 3599 -7346 -23575");
}
TEST(phaddw, testAliasing_isOk) {
short M[1][8] = {
{0,1, 2,3, 4,5, 6,7},
};
phaddw(M[0],M[0],M[0]);
EXPECT_SHRTMATRIXEQ(1, 8, M, "\n\
1 5 9 13 1 5 9 13");
}

View File

@@ -0,0 +1,116 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "dsp/core/q.h"
#include "libc/intrin/pmulhrsw.h"
#include "libc/macros.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "tool/viz/lib/formatstringtable-testlib.h"
#define ACCURACY powf(10, -4)
#define FOR8(STMT) \
for (y = 0; y < 8; ++y) { \
STMT; \
}
#define FOR88(STMT) \
for (y = 0; y < 8; ++y) { \
for (x = 0; x < 8; ++x) { \
STMT; \
} \
}
FIXTURE(pmulhrsw, disableHardwareExtensions) {
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
}
TEST(pmulhrsw, testLimits) {
int i;
short A[8], B[8];
const short kPmulhrswTorture[][3] = {
{SHRT_MIN, SHRT_MIN, SHRT_MIN},
{SHRT_MIN, -1, 1},
{SHRT_MIN, 0, 0},
{SHRT_MIN, 1, -1},
{-1, SHRT_MIN, 1},
{-1, -1, 0},
{-1, 0, 0},
{-1, 1, 0},
{-1, SHRT_MAX, -1},
{0, SHRT_MIN, 0},
{0, -1, 0},
{0, 0, 0},
{0, 1, 0},
{0, SHRT_MAX, 0},
{1, SHRT_MIN, -1},
{1, -1, 0},
{1, 0, 0},
{1, 1, 0},
{1, SHRT_MAX, 1},
{SHRT_MAX, -1, -1},
{SHRT_MAX, 0, 0},
{SHRT_MAX, 1, 1},
};
memset(A, 0, sizeof(A));
memset(B, 0, sizeof(B));
for (i = 0; i < ARRAYLEN(kPmulhrswTorture); ++i) {
A[0] = kPmulhrswTorture[i][0];
B[0] = kPmulhrswTorture[i][1];
pmulhrsw(A, A, B);
EXPECT_EQ(kPmulhrswTorture[i][2], A[0], "pmulhrsw(%hd,%hd)→%hd",
kPmulhrswTorture[i][0], kPmulhrswTorture[i][1], A[0]);
}
}
TEST(pmulhrsw, testFakeFloat) {
int y, x;
float R[8][8];
float Q[8][8];
short QQ[8][8];
short QD[8][8];
short QM[8][8];
float D[8][8] = /* clang-format off */ {
{.929142, .147545, .17061, .765948, .874296, .925816, .073955, .10664},
{.986743, .311924, .550892, .789301, .873408, .743376, .434021, .143184},
{.405694, .080979, .894841, .625169, .465688, .877854, .97371, .264295},
{.781549, .20985, .599735, .943491, .059135, .045806, .770352, .081862},
{.584684, .701568, .022328, .177048, .412809, .185355, .992654, .252167},
{.327565, .693878, .722431, .84546, .060729, .383725, .589365, .435534},
{.942854, .62579, .177928, .809653, .143087, .624792, .851914, .072192},
{.750157, .968502, .270052, .087784, .406716, .510766, .959699, .416836},
};
float M[8][8] = {
{.009407, .882863, .000511, .565419, .69844, .035758, .817049, .249922},
{.072144, .703228, .479622, .121608, .288279, .55492, .387912, .140278},
{.047205, .748263, .683692, .805669, .137764, .858753, .787804, .059591},
{.682286, .787778, .503573, .473795, .437378, .573171, .135995, .341236},
{.588849, .723929, .624155, .710336, .480396, .462433, .865392, .071378},
{.598636, .575209, .758356, .518674, .043861, .542574, .355843, .02014},
{.359636, .95607, .698256, .492859, .149454, .795121, .790219, .357014},
{.401603, .928426, .416429, .11747, .643411, .907285, .074102, .411959},
} /* clang-format on */;
FOR88(QD[y][x] = F2Q(15, D[y][x]));
FOR88(QM[y][x] = F2Q(15, M[y][x]));
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]);
FOR88(EXPECT_TRUE(ACCURACY > Q[y][x] - R[y][x]));
}

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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/psraw.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(psraw, testPositive) {
short A[8] = {1, 2, SHRT_MAX};
psraw(A, A, 1);
EXPECT_EQ(0, A[0]);
EXPECT_EQ(1, A[1]);
EXPECT_EQ(SHRT_MAX / 2, A[2]);
}
TEST(psraw, testNegative) {
short A[8] = {-1, -2, SHRT_MIN};
psraw(A, A, 1);
EXPECT_EQ(-1, A[0]);
EXPECT_EQ(-1, A[1]);
EXPECT_EQ(SHRT_MIN / 2, A[2]);
}

51
test/libc/intrin/test.mk Normal file
View File

@@ -0,0 +1,51 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_INTRIN
TEST_LIBC_INTRIN_SRCS := $(wildcard test/libc/intrin/*.c)
TEST_LIBC_INTRIN_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_INTRIN_SRCS))
TEST_LIBC_INTRIN_COMS = $(TEST_LIBC_INTRIN_OBJS:%.o=%.com)
TEST_LIBC_INTRIN_OBJS = \
$(TEST_LIBC_INTRIN_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_INTRIN_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_INTRIN_BINS = \
$(TEST_LIBC_INTRIN_COMS) \
$(TEST_LIBC_INTRIN_COMS:%=%.dbg)
TEST_LIBC_INTRIN_TESTS = \
$(TEST_LIBC_INTRIN_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_INTRIN_CHECKS = \
$(TEST_LIBC_INTRIN_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_INTRIN_DIRECTDEPS = \
LIBC_INTRIN \
LIBC_NEXGEN32E \
LIBC_STUBS \
LIBC_TINYMATH \
TOOL_VIZ_LIB \
LIBC_TESTLIB
TEST_LIBC_INTRIN_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_INTRIN_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/intrin/intrin.pkg: \
$(TEST_LIBC_INTRIN_OBJS) \
$(foreach x,$(TEST_LIBC_INTRIN_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/intrin/%.com.dbg: \
$(TEST_LIBC_INTRIN_DEPS) \
o/$(MODE)/test/libc/intrin/%.o \
o/$(MODE)/test/libc/intrin/intrin.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
.PHONY: o/$(MODE)/test/libc/intrin
o/$(MODE)/test/libc/intrin: \
$(TEST_LIBC_INTRIN_BINS) \
$(TEST_LIBC_INTRIN_CHECKS)

30
test/libc/math/exp_test.c Normal file
View File

@@ -0,0 +1,30 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
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,39 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#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

@@ -0,0 +1,52 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/testlib/testlib.h"
long double x, y, z;
COMBO(x, pos1) { x = +1.3L; }
COMBO(x, pos2) { x = +2.3L; }
COMBO(y, pos1) { y = +1.3L; }
COMBO(y, pos2) { y = +2.3L; }
COMBO(z, pi) { z = M_PI; }
COMBO(z, e) { z = M_E; }
TEST(powl, lolgebra) {
/* EXPECT_LDBL_EQ(1, powl(x, 0)); */
/* EXPECT_LDBL_EQ(x, powl(x, 1)); */
/* EXPECT_LDBL_EQ(powl(x, -1), 1.0L / x); */
/* EXPECT_LDBL_EQ(powl(x, 0.5), sqrtl(x)); */
/* EXPECT_LDBL_EQ(powl(x, y) * powl(x, z), powl(x, y + z)); */
/* EXPECT_LDBL_EQ(powl(x, y) * powl(z, y), powl(x * z, y)); */
/* EXPECT_LDBL_EQ(powl(x, y) / x, powl(x, y - 1)); */
/* EXPECT_LDBL_EQ(x / powl(y, z), x * powl(y, -z)); */
/* EXPECT_LDBL_EQ(powi(x, 0), 1); */
/* EXPECT_LDBL_EQ(powi(x, 1), x); */
/* EXPECT_LDBL_EQ(powi(x, -1), 1 / x); */
/* EXPECT_LDBL_EQ(powi(1, x), 1); */
/* EXPECT_LDBL_EQ(powi(x, y) * powi(z, y), powi(x * z, y)); */
}
TEST(powl, testConstants) {
EXPECT_LDBL_EQ(16, powl(2, 4));
/* TODO(jart): We need a better AlmostEqual() */
/* EXPECT_LDBL_EQ(3.347061799072891e+62, powl(1337.31337, 20)); */
}

View File

@@ -0,0 +1,77 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/runtime/gc.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(round, test) {
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("1", gc(xdtoa(round(.5))));
EXPECT_STREQ("2", gc(xdtoa(round(1.5))));
EXPECT_STREQ("3", gc(xdtoa(round(2.5))));
}
TEST(round, testCornerCases) {
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(lround, test) {
EXPECT_EQ(-3, lround(-2.5));
EXPECT_EQ(-2, lround(-1.5));
EXPECT_EQ(-1, lround(-.5));
EXPECT_EQ(0, lround(-.0));
EXPECT_EQ(1, lround(.5));
EXPECT_EQ(2, lround(1.5));
EXPECT_EQ(3, lround(2.5));
}
TEST(roundf, test) {
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("1", gc(xdtoa(roundf(.5))));
EXPECT_STREQ("2", gc(xdtoa(roundf(1.5))));
EXPECT_STREQ("3", gc(xdtoa(roundf(2.5))));
}
TEST(roundf, testCornerCases) {
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, 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));
}

56
test/libc/math/test.mk Normal file
View File

@@ -0,0 +1,56 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_MATH
TEST_LIBC_MATH_SRCS := $(wildcard test/libc/math/*.c)
TEST_LIBC_MATH_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MATH_SRCS))
TEST_LIBC_MATH_COMS = $(TEST_LIBC_MATH_OBJS:%.o=%.com)
TEST_LIBC_MATH_OBJS = \
$(TEST_LIBC_MATH_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_MATH_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_MATH_BINS = \
$(TEST_LIBC_MATH_COMS) \
$(TEST_LIBC_MATH_COMS:%=%.dbg)
TEST_LIBC_MATH_TESTS = $(TEST_LIBC_MATH_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_MATH_CHECKS = \
$(TEST_LIBC_MATH_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_MATH_DIRECTDEPS = \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_TINYMATH \
LIBC_MEM \
LIBC_RUNTIME \
LIBC_STUBS \
LIBC_TESTLIB \
LIBC_X
TEST_LIBC_MATH_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_MATH_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/math/math.pkg: \
$(TEST_LIBC_MATH_OBJS) \
$(foreach x,$(TEST_LIBC_MATH_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/math/%.com.dbg: \
$(TEST_LIBC_MATH_DEPS) \
o/$(MODE)/test/libc/math/%.o \
o/$(MODE)/test/libc/math/math.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_MATH_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/math
o/$(MODE)/test/libc/math: \
$(TEST_LIBC_MATH_BINS) \
$(TEST_LIBC_MATH_CHECKS)

View File

@@ -0,0 +1,24 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/testlib/testlib.h"
TEST(malloc, test) { free(malloc(123)); }

View File

@@ -0,0 +1,41 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/testlib/testlib.h"
char *s2;
TEST(strdup, test) {
EXPECT_STREQ("hello", (s2 = strdup("hello")));
EXPECT_NE((intptr_t) "hello", (intptr_t)s2);
free(s2);
}
TEST(strndup, test) {
EXPECT_STREQ("hello", (s2 = strndup("hello", 8)));
EXPECT_NE((intptr_t) "hello", (intptr_t)s2);
free(s2);
}
TEST(strndup, tooLong_truncatesWithNul) {
EXPECT_STREQ("hell", (s2 = strndup("hello", 4)));
free(s2);
}

51
test/libc/mem/test.mk Normal file
View File

@@ -0,0 +1,51 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_MEM
TEST_LIBC_MEM_SRCS := $(wildcard test/libc/mem/*.c)
TEST_LIBC_MEM_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MEM_SRCS))
TEST_LIBC_MEM_COMS = $(TEST_LIBC_MEM_OBJS:%.o=%.com)
TEST_LIBC_MEM_OBJS = \
$(TEST_LIBC_MEM_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_MEM_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_MEM_BINS = \
$(TEST_LIBC_MEM_COMS) \
$(TEST_LIBC_MEM_COMS:%=%.dbg)
TEST_LIBC_MEM_TESTS = $(TEST_LIBC_MEM_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_MEM_CHECKS = \
$(TEST_LIBC_MEM_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_MEM_DIRECTDEPS = \
LIBC_MEM \
LIBC_STUBS \
LIBC_TESTLIB
TEST_LIBC_MEM_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_MEM_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/mem/mem.pkg: \
$(TEST_LIBC_MEM_OBJS) \
$(foreach x,$(TEST_LIBC_MEM_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/mem/%.com.dbg: \
$(TEST_LIBC_MEM_DEPS) \
o/$(MODE)/test/libc/mem/%.o \
o/$(MODE)/test/libc/mem/mem.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_MEM_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/mem
o/$(MODE)/test/libc/mem: \
$(TEST_LIBC_MEM_BINS) \
$(TEST_LIBC_MEM_CHECKS)

View File

@@ -0,0 +1,42 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/macros.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/str/str.h"
#include "libc/testlib/hyperion.h"
#include "libc/testlib/testlib.h"
uint32_t crc32(uint32_t, const void *, int);
uint32_t crc32$pclmul(uint32_t, const void *, size_t);
uint32_t crc32$pclmul2(uint32_t, const void *, size_t);
TEST(crc32, testBigText) {
size_t size;
size = kHyperionSize;
EXPECT_EQ(0xe9ded8e6, crc32(0, kHyperion, size));
EXPECT_EQ(0xe9ded8e6, crc32_z(0, kHyperion, size));
if (X86_HAVE(PCLMUL)) {
size = ROUNDDOWN(size, 64);
EXPECT_EQ(0xc7adc04f, crc32(0, kHyperion, size));
EXPECT_EQ(0xc7adc04f, crc32_z(0, kHyperion, size));
EXPECT_EQ(0xc7adc04f,
0xffffffffu ^ crc32$pclmul(0 ^ 0xffffffffu, kHyperion, size));
}
}

View File

@@ -0,0 +1,96 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/log/check.h"
#include "libc/nexgen32e/kompressor.h"
#include "libc/nexgen32e/lz4.h"
#include "libc/runtime/ezmap.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
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);
*dst = 'z';
ASSERT_EQ(dst, lz4decode(dst, src));
ASSERT_EQ('z', *dst);
tfree(dst);
tfree(src);
}
TEST(lz4, decompress_oneLetterWithoutChecksum) {
/* printf a >oneletter */
/* lz4 -9 --content-size --no-frame-crc oneletter /dev/stdout | hexdump -C */
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);
ASSERT_EQ(dst + 1, lz4decode(dst, src));
ASSERT_EQ('a', *dst);
tfree(dst);
tfree(src);
}
TEST(lz4, decompress_runLengthDecode) {
/* printf aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >/tmp/a */
/* lz4 -9 --content-size --no-frame-crc /tmp/a - | hexdump -vC */
static char kLz4Data[] = {
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));
const char *want = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
char *dst = tmalloc(strlen(want));
ASSERT_EQ(dst + strlen(want), lz4decode(dst, src));
ASSERT_STREQN(want, dst, strlen(want));
tfree(dst);
tfree(src);
}
TEST(lz4, zoneFileGmt) {
if (!fileexists("usr/share/zoneinfo.dict.lz4")) return;
struct MappedFile dict, gmt;
CHECK_NE(-1, mapfileread("usr/share/zoneinfo.dict.lz4", &dict));
CHECK_NE(-1, mapfileread("usr/share/zoneinfo/GMT.lz4", &gmt));
size_t mapsize, gmtsize;
char *mapping, *gmtdata;
lz4decode((gmtdata = lz4decode(
(mapping = mapanon(
(mapsize = roundup(
LZ4_FRAME_BLOCKCONTENTSIZE(lz4check(dict.addr)) +
(gmtsize = LZ4_FRAME_BLOCKCONTENTSIZE(
lz4check(gmt.addr))),
FRAMESIZE)))),
dict.addr)),
gmt.addr);
ASSERT_BINEQ(
u"TZif2                                         GMT   TZif2   "
u"                               ♦°              GMT   ◙GMT0◙",
gmtdata);
munmap(mapping, mapsize);
unmapfile(&dict);
unmapfile(&gmt);
}

View File

@@ -0,0 +1,103 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/runtime/buffer.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/mappings.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
#define ALIGN 128
#define BUFSIZE (8 * 32)
#define MASKSIZE (BUFSIZE / CHAR_BIT)
const char kX[] = "aaaaaaaaeeeeeeeeeeeeeeeeeeeeeeee"
"e e"
"e e"
"e e"
"e e"
"e e"
"e e"
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeee-e";
const char kY[] = "aaaaaaaaefffffffffffeffffffffff-"
"f z-"
"f f"
"f f"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"f f"
"f f"
"ffffffffffffffffffffffffffffff-f";
const char kM[] = "11111111100000000000100000000000"
"01111111111111111111111111111100"
"01111111111111111111111111111110"
"01111111111111111111111111111110"
"00000000000000000000000000000000"
"01111111111111111111111111111110"
"01111111111111111111111111111110"
"00000000000000000000000000000010";
nodiscard char *binify(uint8_t *data, size_t size) {
uint8_t b;
size_t i, j;
char *s, *p;
p = s = xmalloc(size * CHAR_BIT + 1);
for (i = 0; i < size; ++i) {
b = data[i];
for (j = 0; j < CHAR_BIT; ++j) {
*p++ = "01"[b & 1];
b >>= 1;
}
}
*p = '\0';
return s;
}
TEST(memeqmask, test) {
struct GuardedBuffer x = {}, y = {}, m = {};
memcpy(balloc(&x, ALIGN, BUFSIZE), kX, BUFSIZE);
memcpy(balloc(&y, ALIGN, BUFSIZE), kY, BUFSIZE);
balloc(&m, ALIGN, MASKSIZE);
EXPECT_EQ((intptr_t)m.p, (intptr_t)memeqmask(m.p, x.p, y.p, BUFSIZE));
EXPECT_STREQ(kM, gc(binify(m.p, MASKSIZE)));
bfree(&m);
bfree(&x);
bfree(&y);
}
#if 0
#include "libc/rand/rand.h"
#include "libc/testlib/ezbench.h"
TEST(memeqmask, bench) {
size_t len = 64 * 1024;
char *m = xmemalign(64, DIMMASK(len));
char *x = xmemalign(64, len);
char *y = xmemalign(64, len);
EZBENCH(
{
rngset(x, len, rand64, -1);
rngset(y, len, rand64, -1);
},
memeqmask(m, x, y, len));
}
#endif

View File

@@ -0,0 +1,28 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/nexgen32e/nexgen32e.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(strsak32, test) {
EXPECT_EQ(0, wcslen(L""));
EXPECT_EQ(1, wcslen(L"1"));
EXPECT_EQ(5, wcslen(L"hello"));
}

View File

@@ -0,0 +1,58 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/nexgen32e/nexgen32e.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(strtolower, testAligned) {
char s[128] = "AZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd";
EXPECT_STREQ("azcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", strtolower(s));
}
TEST(strtolower, testUnaligned) {
char s[128] = "AZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd";
strtolower(s + 1);
EXPECT_STREQ("Azcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", s);
}
TEST(strtoupper, testAligned) {
char s[128] = "AZCDabcdABCDabcdA0CDabcdABCDabcdABCDabcd";
EXPECT_STREQ("AZCDABCDABCDABCDA0CDABCDABCDABCDABCDABCD", strtoupper(s));
}
TEST(strtoupper, testUnaligned) {
char s[128] = "aZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd";
strtoupper(s + 1);
EXPECT_STREQ("aZCDABCDABCDABCDABCDABCDABCDABCDABCDABCD", s);
}
BENCH(strtolower, bench) {
size_t size = FRAMESIZE;
char *data = tgc(tmalloc(size));
EZBENCH2(
"strtolower",
{
rngset(data, size, rand64, -1);
data[size - 1] = 0;
},
strtolower(data));
}

View File

@@ -0,0 +1,68 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_NEXGEN32E
TEST_LIBC_NEXGEN32E_SRCS := \
$(wildcard test/libc/nexgen32e/*.c)
TEST_LIBC_NEXGEN32E_SRCS_TEST = \
$(filter %_test.c,$(TEST_LIBC_NEXGEN32E_SRCS))
TEST_LIBC_NEXGEN32E_OBJS = \
$(TEST_LIBC_NEXGEN32E_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_NEXGEN32E_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_NEXGEN32E_COMS = \
$(TEST_LIBC_NEXGEN32E_OBJS:%.o=%.com)
TEST_LIBC_NEXGEN32E_BINS = \
$(TEST_LIBC_NEXGEN32E_COMS) \
$(TEST_LIBC_NEXGEN32E_COMS:%=%.dbg)
TEST_LIBC_NEXGEN32E_TESTS = \
$(TEST_LIBC_NEXGEN32E_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_NEXGEN32E_CHECKS = \
$(TEST_LIBC_NEXGEN32E_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_NEXGEN32E_DIRECTDEPS = \
LIBC_ALG \
LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_LOG \
LIBC_STDIO \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RAND \
LIBC_RUNTIME \
LIBC_STUBS \
LIBC_STR \
LIBC_TESTLIB \
LIBC_X \
TOOL_VIZ_LIB
TEST_LIBC_NEXGEN32E_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_NEXGEN32E_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/nexgen32e/nexgen32e.pkg: \
$(TEST_LIBC_NEXGEN32E_OBJS) \
$(foreach x,$(TEST_LIBC_NEXGEN32E_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/nexgen32e/%.com.dbg: \
$(TEST_LIBC_NEXGEN32E_DEPS) \
o/$(MODE)/test/libc/nexgen32e/%.o \
o/$(MODE)/test/libc/nexgen32e/nexgen32e.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_NEXGEN32E_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/nexgen32e
o/$(MODE)/test/libc/nexgen32e: \
$(TEST_LIBC_NEXGEN32E_BINS) \
$(TEST_LIBC_NEXGEN32E_CHECKS)

View File

@@ -0,0 +1,39 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/rand/rand.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(devrand, test) {
if (IsWindows()) return;
const size_t kSize = 8;
void *A = tmalloc(kSize);
void *B = tmalloc(kSize);
memset(A, 0, kSize);
memset(B, 0, kSize);
EXPECT_EQ(0, devrand(A, kSize));
EXPECT_EQ(0, devrand(B, kSize));
EXPECT_BINNE(u"        ", A);
EXPECT_BINNE(u"        ", B);
EXPECT_NE(0, memcmp(A, B, kSize));
tfree(B);
tfree(A);
}

View File

@@ -0,0 +1,45 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/rand/rand.h"
#include "libc/testlib/testlib.h"
TEST(rand002, alwaysReturnsPositiveNumbers) {
for (unsigned i = 0; i < 100; ++i) {
ASSERT_GT(rand(), 0);
}
}
TEST(rand003, srandSmokeTest) {
srand(1);
ASSERT_EQ(908834774, rand());
srand(1);
ASSERT_EQ(908834774, rand());
srand(7);
ASSERT_EQ(1059165278, rand());
}
TEST(rand004, rand32SmokeTest) {
ASSERT_TRUE(rand32() != rand32() || rand32() != rand32() ||
rand32() != rand32() || rand32() != rand32());
}
TEST(rand005, rand64SmokeTest) {
ASSERT_TRUE(rand64() != rand64() || rand64() != rand64());
}

59
test/libc/rand/test.mk Normal file
View File

@@ -0,0 +1,59 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_RAND
TEST_LIBC_RAND_SRCS := $(wildcard test/libc/rand/*.c)
TEST_LIBC_RAND_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_RAND_SRCS))
TEST_LIBC_RAND_COMS = $(TEST_LIBC_RAND_OBJS:%.o=%.com)
TEST_LIBC_RAND_BINS = $(TEST_LIBC_RAND_COMS) $(TEST_LIBC_RAND_COMS:%=%.dbg)
TEST_LIBC_RAND_OBJS = \
$(TEST_LIBC_RAND_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_RAND_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_RAND_TESTS = $(TEST_LIBC_RAND_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_RAND_CHECKS = \
$(TEST_LIBC_RAND_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_RAND_DIRECTDEPS = \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_NEXGEN32E \
LIBC_RAND \
LIBC_RUNTIME \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X
TEST_LIBC_RAND_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_RAND_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/rand/rand.pkg: \
$(TEST_LIBC_RAND_OBJS) \
$(foreach x,$(TEST_LIBC_RAND_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/rand/%.com.dbg: \
$(TEST_LIBC_RAND_DEPS) \
o/$(MODE)/test/libc/rand/%.o \
o/$(MODE)/test/libc/rand/rand.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_RAND_OBJS): \
$(BUILD_FILES) \
test/libc/rand/test.mk
$(TEST_LIBC_RAND_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
.PHONY: o/$(MODE)/test/libc/rand
o/$(MODE)/test/libc/rand: \
$(TEST_LIBC_RAND_BINS) \
$(TEST_LIBC_RAND_CHECKS)

View File

@@ -0,0 +1,72 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/calls/calls.h"
#include "libc/testlib/testlib.h"
TEST(arch_prctl, fs) {
if (IsLinux() || IsOpenbsd()) {
uint64_t n, x;
x = 0xdeadbeef;
arch_prctl(ARCH_SET_FS, &x);
ASSERT_NE(-1, arch_prctl(ARCH_GET_FS, (intptr_t)&n));
ASSERT_EQ((intptr_t)&x, n);
ASSERT_EQ(0xdeadbeef, fs((int64_t *)0));
}
}
TEST(arch_prctl, pointerRebasingFs) {
if (IsLinux() || IsOpenbsd()) {
unsigned long s[] = {0x0706050403020100, 0x0f0e0d0c0b0a0908};
ASSERT_EQ(0x0706050403020100, s[0]);
ASSERT_EQ(0, arch_prctl(ARCH_SET_FS, 1));
ASSERT_EQ(0x0807060504030201, fs(&s[0]));
ASSERT_EQ(0, arch_prctl(ARCH_SET_FS, 2));
ASSERT_EQ(0x0908070605040302, fs(&s[0]));
intptr_t fs;
ASSERT_EQ(0, arch_prctl(ARCH_GET_FS, &fs));
ASSERT_EQ(2, fs);
}
}
TEST(arch_prctl, gs) {
if (IsLinux()) {
uint64_t n, x;
x = 0xdeadbeef;
arch_prctl(ARCH_SET_GS, &x);
ASSERT_NE(-1, arch_prctl(ARCH_GET_GS, (intptr_t)&n));
ASSERT_EQ((intptr_t)&x, n);
ASSERT_EQ(0xdeadbeef, gs((int64_t *)0));
}
}
TEST(arch_prctl, pointerRebasing) {
if (IsLinux()) {
unsigned long s[] = {0x0706050403020100, 0x0f0e0d0c0b0a0908};
ASSERT_EQ(0x0706050403020100, s[0]);
ASSERT_EQ(0, arch_prctl(ARCH_SET_GS, 1));
ASSERT_EQ(0x0807060504030201, gs(&s[0]));
ASSERT_EQ(0, arch_prctl(ARCH_SET_GS, 2));
ASSERT_EQ(0x0908070605040302, gs(&s[0]));
intptr_t gs;
ASSERT_EQ(0, arch_prctl(ARCH_GET_GS, &gs));
ASSERT_EQ(2, gs);
}
}

View File

@@ -0,0 +1,105 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/calls/calls.h"
#include "libc/calls/struct/sigaction.h"
#include "libc/calls/ucontext.h"
#include "libc/runtime/buffer.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
#include "third_party/xed/x86.h"
char *p;
bool segfaulted_;
struct GuardedBuffer b_;
struct sigaction oldsegv_;
struct XedDecodedInst xedd_;
void RestrictPage(void *addr, unsigned flags) {
addr = (void *)rounddown((intptr_t)addr, PAGESIZE);
EXPECT_NE(-1, mprotect(addr, PAGESIZE, flags));
}
void OnSegLol(int sig, struct siginfo *si, struct ucontext *uc) {
size_t i;
uint8_t *rip;
segfaulted_ = true;
rip = (uint8_t *)uc->uc_mcontext.rip;
RestrictPage(rip, PROT_READ | PROT_WRITE | PROT_EXEC);
ASSERT_EQ(XED_ERROR_NONE,
xed_instruction_length_decode(xed_decoded_inst_zero_set_mode(
&xedd_, XED_MACHINE_MODE_LONG_64),
rip, XED_MAX_INSTRUCTION_BYTES));
for (i = 0; i < xedd_.decoded_length; ++i) rip[i] = 0x90; /* NOP */
RestrictPage(rip, PROT_READ | PROT_EXEC);
}
void SetUp(void) {
segfaulted_ = false;
memset(&b_, 0, sizeof(b_));
ASSERT_NE(-1, xsigaction(SIGSEGV, OnSegLol, SA_RESETHAND | SA_RESTART, 0,
&oldsegv_));
}
void TearDown(void) {
EXPECT_NE(-1, sigaction(SIGSEGV, &oldsegv_, NULL));
bfree(&b_);
EXPECT_EQ(NULL, b_.p);
}
TEST(balloc, createsGuardPage) {
ASSERT_NE(NULL, (p = balloc(&b_, 1, 1)));
EXPECT_EQ(p, b_.p);
p[0] = '.';
ASSERT_FALSE(segfaulted_);
/* TODO(jart): fix me!!! */
/* p[1 + __BIGGEST_ALIGNMENT__] = '!'; */
/* EXPECT_TRUE(segfaulted_); */
}
TEST(balloc, aligned_roundsUp) {
ASSERT_NE(NULL, (p = balloc(&b_, 128, 1)));
EXPECT_EQ(0, (intptr_t)b_.p & 127);
p[127] = '.';
ASSERT_FALSE(segfaulted_);
/* TODO(jart): fix me!!! */
/* p[128 + __BIGGEST_ALIGNMENT__] = '!'; */
/* EXPECT_TRUE(segfaulted_); */
}
TEST(balloc, multipleCalls_avoidsNeedlessSyscalls) {
size_t c;
c = g_syscount;
ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337)));
EXPECT_GT(g_syscount, c);
c = g_syscount;
ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337 / 2)));
EXPECT_EQ(g_syscount, c);
c = g_syscount;
ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337 * 2)));
EXPECT_GT(g_syscount, c);
}

View File

@@ -0,0 +1,81 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/mem/mem.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/o.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);
}

View File

@@ -0,0 +1,171 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#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 *));
EXPECT_EQ(0, getdosargv(u"", buf, size, argv, max));
EXPECT_EQ(NULL, argv[0]);
tfree(argv);
tfree(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 *));
EXPECT_EQ(0, getdosargv(u" ", buf, size, argv, max));
EXPECT_EQ(NULL, argv[0]);
tfree(argv);
tfree(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 *));
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);
}
TEST(getdosargv, advancedUsage) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(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);
}
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 *));
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);
}
TEST(getdosargv, realWorldUsage) {
size_t max = 512;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(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]);
EXPECT_STREQ("oh", argv[1]);
EXPECT_STREQ("yes", argv[2]);
EXPECT_STREQ("yes", argv[3]);
EXPECT_STREQ("yes", argv[4]);
EXPECT_EQ(NULL, argv[5]);
tfree(argv);
tfree(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 *));
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);
}
TEST(getdosargv, pureScanningMode) {
size_t max = 0;
size_t size = 0;
char *buf = NULL;
char **argv = NULL;
EXPECT_EQ(3, getdosargv(u"a b c", buf, size, argv, max));
}
TEST(getdosargv, justSlashQuote) {
size_t max = 4, size = 16;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(max * sizeof(char *));
EXPECT_EQ(1, getdosargv(u"\"\\\\\\\"\"", buf, size, argv, max));
EXPECT_STREQ("\\\"", argv[0]);
tfree(argv);
tfree(buf);
}
TEST(getdosargv, quoteInMiddleOfArg_wontSplitArg) {
size_t max = 4, size = 16;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(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);
}
TEST(getdosargv, waqQuoting1) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(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);
}
TEST(getdosargv, waqQuoting2) {
size_t max = 4;
size_t size = ARG_MAX;
char *buf = tmalloc(size * sizeof(char));
char **argv = tmalloc(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);
}

View File

@@ -0,0 +1,103 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/getdosenviron.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
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 *));
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);
#undef kEnv
}
TEST(getdosenviron, testTwoVariables) {
#define kEnv \
(u"𐌰𐌱𐌲𐌳=Und wird die Welt auch in Flammen stehen\0" \
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 *));
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);
#undef kEnv
}
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 *));
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);
#undef kEnv
}
TEST(getdosenviron, testEmpty_doesntTouchMemory) {
EXPECT_EQ(0, getdosenviron(u"", NULL, 0, NULL, 0));
}
TEST(getdosenviron, testEmpty_zeroTerminatesWheneverPossible_1) {
size_t max = 1;
char **envp = tmalloc(max * sizeof(char *));
EXPECT_EQ(0, getdosenviron(u"", NULL, 0, envp, max));
EXPECT_EQ(NULL, envp[0]);
tfree(envp);
}
TEST(getdosenviron, testEmpty_zeroTerminatesWheneverPossible_2) {
size_t size = 1;
char *block = tmalloc(size);
EXPECT_EQ(0, getdosenviron(u"", block, size, NULL, 0));
EXPECT_BINEQ(u" ", block);
tfree(block);
}
TEST(getdosenviron, testEmpty_zeroTerminatesWheneverPossible_3) {
size_t size = 2;
char *block = tmalloc(size);
EXPECT_EQ(0, getdosenviron(u"", block, size, NULL, 0));
EXPECT_BINEQ(u"  ", block);
tfree(block);
}

View File

@@ -0,0 +1,98 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/pushpop.h"
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/runtime/mappings.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(grow, testNull_hasAllocatingBehavior) {
void *p = NULL;
size_t capacity = 0;
EXPECT_TRUE(grow(&p, &capacity, 1, 0));
EXPECT_NE(NULL, p);
EXPECT_EQ(32, capacity);
free_s(&p);
}
TEST(grow, testCapacity_isInUnits_withTerminatorGuarantee) {
void *p = NULL;
size_t capacity = 0;
EXPECT_TRUE(grow(&p, &capacity, 8, 0));
EXPECT_NE(NULL, p);
EXPECT_EQ(32 / 8 + 1, capacity);
free_s(&p);
}
TEST(grow, testStackMemory_convertsToDynamic) {
int A[] = {1, 2, 3};
int *p = A;
size_t capacity = ARRAYLEN(A);
EXPECT_FALSE(isheap(p));
EXPECT_TRUE(grow(&p, &capacity, sizeof(int), 0));
EXPECT_TRUE(isheap(p));
EXPECT_GT(capacity, ARRAYLEN(A));
EXPECT_EQ(1, p[0]);
EXPECT_EQ(2, p[1]);
EXPECT_EQ(3, p[2]);
p[0] = 7;
EXPECT_EQ(1, A[0]);
free(p);
}
TEST(grow, testGrowth_clearsNewMemory) {
size_t i, capacity = 123;
char *p = malloc(capacity);
memset(p, 'a', capacity);
EXPECT_TRUE(grow(&p, &capacity, 1, 0));
EXPECT_GT(capacity, 123);
for (i = 0; i < 123; ++i) ASSERT_EQ('a', p[i]);
for (i = 123; i < capacity; ++i) ASSERT_EQ(0, p[i]);
free_s(&p);
}
TEST(grow, testBonusParam_willGoAboveAndBeyond) {
size_t capacity = 32;
char *p = malloc(capacity);
EXPECT_TRUE(grow(&p, &capacity, 1, 0));
EXPECT_LT(capacity, 1024);
free_s(&p);
p = malloc((capacity = 32));
EXPECT_TRUE(grow(&p, &capacity, 1, 1024));
EXPECT_GT(capacity, 1024);
free_s(&p);
}
TEST(grow, testOverflow_returnsFalseAndDoesNotFree) {
int A[] = {1, 2, 3};
int *p = A;
size_t capacity = ARRAYLEN(A);
EXPECT_FALSE(isheap(p));
EXPECT_FALSE(grow(&p, &capacity, pushpop(SIZE_MAX), 0));
EXPECT_FALSE(isheap(p));
EXPECT_EQ(capacity, ARRAYLEN(A));
EXPECT_EQ(1, p[0]);
EXPECT_EQ(2, p[1]);
EXPECT_EQ(3, p[2]);
free_s(&p);
}

View File

@@ -0,0 +1,35 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(heapsortcar, test) {
int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'}, {0, 'e'},
{99, 'f'}, {2, 'g'}, {83, 'h'}, {782, 'i'}, {1, 'j'}};
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'}};
unsigned n = ARRAYLEN(A);
heapsortcar(A, n);
ASSERT_EQ(0, memcmp(&A[0], &B[0], sizeof(A)));
}

View File

@@ -0,0 +1,248 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/limits.h"
#include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h"
/**
* @fileoverview Tests for arithmetic overflow traps.
*
* This module assumes -ftrapv, but not -fsanitize=undefined; since
* Ubsan provides a superset trapping functionality, and therefore
* overrides the prior. The nice thing about -ftrapv is that it doesn't
* leak huge amounts of information into the binary. So it's appropriate
* to enable in a release build.
*
* @note LLVM's implementation of the runtime for this crashes due to
* relying on undefined behavior lool, the very thing the flag was
* meant to help prevent, so we don't get punked by the compiler
* @see __addvsi3, __mulvsi3, etc.
*/
bool overflowed_;
void __on_arithmetic_overflow(void) {
overflowed_ = true;
}
void SetUp(void) {
overflowed_ = false;
}
/* 32-BIT SIGNED NEGATION */
TEST(__negvsi2, testMax) {
EXPECT_EQ(-INT_MAX, -VEIL("r", INT_MAX));
EXPECT_FALSE(overflowed_);
}
TEST(__negvsi2, testMin0) {
EXPROPRIATE(-VEIL("r", INT_MIN));
EXPECT_TRUE(overflowed_);
}
/* 64-BIT SIGNED NEGATION */
TEST(__negvdi2, testMax) {
EXPECT_EQ(-LONG_MAX, -VEIL("r", LONG_MAX));
EXPECT_FALSE(overflowed_);
}
TEST(__negvdi2, testMin0) {
EXPROPRIATE(-VEIL("r", LONG_MIN));
EXPECT_TRUE(overflowed_);
}
/* 32-BIT SIGNED MULTIPLICATION */
TEST(__mulvsi3, testMin0) {
EXPECT_EQ(0, 0 * VEIL("r", INT_MIN));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvsi3, testMin1) {
EXPECT_EQ(INT_MIN, 1 * VEIL("r", INT_MIN));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvsi3, testMin2) {
EXPROPRIATE(2 * VEIL("r", INT_MIN));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvsi3, testMax0) {
EXPECT_EQ(0, 0 * VEIL("r", INT_MAX));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvsi3, testMax1) {
EXPECT_EQ(INT_MAX, 1 * VEIL("r", INT_MAX));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvsi3, testMax2) {
EXPROPRIATE(2 * VEIL("r", INT_MAX));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvsi3, test7) {
EXPECT_EQ(0x70000000, 7 * VEIL("r", 0x10000000));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvsi3, test8) {
EXPROPRIATE(8 * VEIL("r", 0x10000000));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvsi3, test31337) {
EXPROPRIATE(0x31337 * VEIL("r", 0x31337));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvsi3, standAndDeliver_aNegativeTimesANegativeEqualsAPositive) {
EXPECT_EQ(25, -5 * VEIL("r", -5));
EXPECT_FALSE(overflowed_);
}
/* 64-BIT SIGNED MULTIPLICATION */
TEST(__mulvdi3, testMin0) {
EXPECT_EQ(0, 0 * VEIL("r", LONG_MIN));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvdi3, testMin1) {
EXPECT_EQ(LONG_MIN, 1 * VEIL("r", LONG_MIN));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvdi3, testMin2) {
EXPROPRIATE(2 * VEIL("r", LONG_MIN));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvdi3, testMax0) {
EXPECT_EQ(0, 0 * VEIL("r", LONG_MAX));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvdi3, testMax1) {
EXPECT_EQ(LONG_MAX, 1 * VEIL("r", LONG_MAX));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvdi3, testMax2) {
EXPROPRIATE(2 * VEIL("r", LONG_MAX));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvdi3, test7) {
EXPECT_EQ(0x7000000000000000l, 7 * VEIL("r", 0x1000000000000000l));
EXPECT_FALSE(overflowed_);
}
TEST(__mulvdi3, test8) {
EXPROPRIATE(8 * VEIL("r", 0x1000000000000000l));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvdi3, test31337) {
EXPROPRIATE(0x3133700000000l * VEIL("r", 0x3133700000000l));
EXPECT_TRUE(overflowed_);
}
TEST(__mulvdi3, standAndDeliver_aNegativeTimesANegativeEqualsAPositive) {
EXPECT_EQ(25l, -5l * VEIL("r", -5l));
EXPECT_FALSE(overflowed_);
}
/* 32-BIT SIGNED ADDITION */
TEST(__addvsi3, testMin1) {
EXPECT_EQ(INT_MIN + 1, 1 + VEIL("r", INT_MIN));
EXPECT_FALSE(overflowed_);
}
TEST(__addvsi3, testMax1) {
EXPROPRIATE(1 + VEIL("r", INT_MAX));
EXPECT_TRUE(overflowed_);
}
TEST(__addvsi3, testNegPos) {
EXPECT_EQ(2, -2 + VEIL("r", 4));
EXPECT_FALSE(overflowed_);
}
TEST(__addvsi3, testPosNeg) {
EXPECT_EQ(-2, 2 + VEIL("r", -4));
EXPECT_FALSE(overflowed_);
}
/* 64-BIT SIGNED ADDITION */
TEST(__addvdi3, testMin1) {
EXPECT_EQ(LONG_MIN + 1, 1 + VEIL("r", LONG_MIN));
EXPECT_FALSE(overflowed_);
}
TEST(__addvdi3, testMax1) {
EXPROPRIATE(1 + VEIL("r", LONG_MAX));
EXPECT_TRUE(overflowed_);
}
TEST(__addvdi3, testNegPos) {
EXPECT_EQ(2l, -2l + VEIL("r", 4l));
EXPECT_FALSE(overflowed_);
}
TEST(__addvdi3, testPosNeg) {
EXPECT_EQ(-2l, 2l + VEIL("r", -4l));
EXPECT_FALSE(overflowed_);
}
/* 32-BIT SIGNED SUBTRACTION */
TEST(__subvsi3, testMin1) {
EXPROPRIATE(VEIL("r", INT_MIN) - 1);
EXPECT_TRUE(overflowed_);
}
TEST(__subvsi3, testMax1) {
EXPECT_EQ(INT_MAX - 1, VEIL("r", INT_MAX) - 1);
EXPECT_FALSE(overflowed_);
}
TEST(__subvsi3, testPosNeg) {
EXPECT_EQ(-2, 2 - VEIL("r", 4));
EXPECT_FALSE(overflowed_);
}
/* 64-BIT SIGNED SUBTRACTION */
TEST(__subvdi3, testMin1) {
EXPROPRIATE(VEIL("r", LONG_MIN) - 1);
EXPECT_TRUE(overflowed_);
}
TEST(__subvdi3, testMax1) {
EXPECT_EQ(LONG_MAX - 1, VEIL("r", LONG_MAX) - 1);
EXPECT_FALSE(overflowed_);
}

View File

@@ -0,0 +1,58 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/runtime/mappings.h"
#include "libc/testlib/testlib.h"
#define ADDR
struct MemoryCoord stack = ADDRSIZE_TO_COORD(0x7fffffff0000L, 0x00010000);
struct MemoryCoord heap3 = ADDRSIZE_TO_COORD(0x200000020000L, 0x00010000);
struct MemoryCoord heap2 = ADDRSIZE_TO_COORD(0x200000010000L, 0x00010000);
struct MemoryCoord heap1 = ADDRSIZE_TO_COORD(0x200000000000L, 0x00010000);
struct MemoryCoord heapa = ADDRSIZE_TO_COORD(0x200000000000L, 0x00030000);
struct MemoryCoord progg = ADDRSIZE_TO_COORD(0x000000400000L, 0x00010000);
struct MemoryCoord bane = ADDRSIZE_TO_COORD(0xffff800000080000L, 0x00010000);
TEST(isoverlapping, test) {
EXPECT_FALSE(ISOVERLAPPING(stack, heap3));
EXPECT_FALSE(ISOVERLAPPING(heap1, heap2));
EXPECT_FALSE(ISOVERLAPPING(heap2, heap3));
EXPECT_FALSE(ISOVERLAPPING(heap1, heap3));
EXPECT_TRUE(ISOVERLAPPING(heapa, heap1));
EXPECT_TRUE(ISOVERLAPPING(heapa, heap3));
}
TEST(findmapping, limits) {
ASSERT_EQ(INT_MAX, ADDR_TO_COORD(0x7fffffff0000L));
ASSERT_EQ(INT_MIN, ADDR_TO_COORD(-0x800000000000L));
}
TEST(findmapping, test) {
struct MemoryCoord c[] = {bane, progg, heap1, heap2, heap3, stack};
EXPECT_EQ(6, ARRAYLEN(c));
EXPECT_EQ(0, findmapping_(ADDR_TO_COORD(-0x800000000000UL), c, 6));
EXPECT_EQ(1, findmapping_(ADDR_TO_COORD(-42), c, 6));
EXPECT_EQ(1, findmapping_(ADDR_TO_COORD(0x000000300000L), c, 6));
EXPECT_EQ(2, findmapping_(ADDR_TO_COORD(0x000000400000L), c, 6));
EXPECT_EQ(6, findmapping_(ADDR_TO_COORD(0x7fffffffffffL), c, 6));
}

View File

@@ -0,0 +1,146 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/bits/xchg.h"
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/mappings.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/msync.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
unsigned m1;
TEST(mmap, testMapUnmapAnonAnyAddr) {
void *p;
m1 = _mm.i;
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_EQ(m1 + 1, _mm.i);
EXPECT_NE(-1, munmap(p, FRAMESIZE));
EXPECT_EQ(m1 + 0, _mm.i);
}
TEST(mmap, testMunmapUnmapsMultiple) {
void *p1, *p2;
m1 = _mm.i;
EXPECT_NE(MAP_FAILED, (p1 = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_NE(MAP_FAILED, (p2 = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
if ((intptr_t)p1 > (intptr_t)p2) xchg(&p1, &p2);
EXPECT_EQ(m1 + 2, _mm.i);
EXPECT_NE(-1, munmap(p1, (intptr_t)p2 + (intptr_t)FRAMESIZE - (intptr_t)p1));
EXPECT_EQ(m1 + 0, _mm.i);
}
TEST(mmap, testPartialUnmapRight) {
if (1) return; /* naaah */
char *p;
m1 = _mm.i;
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE * 2, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_EQ(m1 + 1, _mm.i);
EXPECT_NE(-1, munmap(p + FRAMESIZE, FRAMESIZE));
EXPECT_EQ(m1 + 1, _mm.i);
EXPECT_NE(-1, munmap(p, FRAMESIZE));
EXPECT_EQ(m1 + 0, _mm.i);
}
TEST(mmap, testPartialUnmapLeft) {
if (1) return; /* naaah */
char *p;
m1 = _mm.i;
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE * 2, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
EXPECT_EQ(m1 + 1, _mm.i);
EXPECT_NE(-1, munmap(p, FRAMESIZE));
EXPECT_EQ(m1 + 1, _mm.i);
EXPECT_NE(-1, munmap(p + FRAMESIZE, FRAMESIZE));
EXPECT_EQ(m1 + 0, _mm.i);
}
TEST(mmap, testMapFile) {
int fd;
char *p;
char path[PATH_MAX];
sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid());
m1 = _mm.i;
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
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_EQ(m1 + 1, _mm.i);
EXPECT_STREQ("hello", p);
EXPECT_NE(-1, munmap(p, 5));
EXPECT_EQ(m1 + 0, _mm.i);
EXPECT_NE(-1, close(fd));
EXPECT_NE(-1, unlink(path));
}
TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
int fd;
char *p, buf[16], path[PATH_MAX];
sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid());
m1 = _mm.i;
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
EXPECT_EQ(5, write(fd, "hello", 5));
EXPECT_NE(-1, fdatasync(fd));
EXPECT_NE(MAP_FAILED,
(p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
EXPECT_NE(-1, close(fd));
EXPECT_EQ(m1 + 1, _mm.i);
EXPECT_STREQ("hello", p);
p[1] = 'a';
EXPECT_NE(-1, msync(p, PAGESIZE, MS_SYNC));
ASSERT_NE(-1, (fd = open(path, O_RDONLY)));
EXPECT_EQ(5, read(fd, buf, 5));
EXPECT_STREQN("hallo", buf, 5);
EXPECT_NE(-1, close(fd));
EXPECT_NE(-1, munmap(p, 5));
EXPECT_EQ(m1 + 0, _mm.i);
EXPECT_NE(-1, unlink(path));
}
TEST(mmap, testMapFixed_destroysEverythingInItsPath) {
m1 = _mm.i;
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 0),
FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 1),
FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 2),
FRAMESIZE, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
ASSERT_EQ(m1 + 3, _mm.i);
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 0),
FRAMESIZE * 3, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
ASSERT_EQ(m1 + 1, _mm.i);
EXPECT_NE(-1, munmap((void *)kFixedMappingsStart, FRAMESIZE * 3));
}

View File

@@ -0,0 +1,48 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/ring.h"
#include "libc/testlib/testlib.h"
TEST(ringalloc, testMagic) {
char *p;
size_t n;
struct RingBuffer ring = {};
n = FRAMESIZE * 2;
EXPECT_NE(NULL, ringalloc(&ring, n));
if ((p = ring.p)) {
EXPECT_EQ(0, p[0]);
EXPECT_EQ(0, p[7]);
EXPECT_EQ(0, p[n + 0]);
EXPECT_EQ(0, p[n + 7]);
p[0] = 23;
p[7] = 123;
EXPECT_EQ(23, p[0]);
EXPECT_EQ(123, p[7]);
EXPECT_EQ(23, p[n + 0]);
EXPECT_EQ(123, p[n + 7]);
}
EXPECT_NE(-1, ringfree(&ring));
}
TEST(ringalloc, testFrameSized) {
struct RingBuffer ring = {};
EXPECT_NE(NULL, ringalloc(&ring, FRAMESIZE));
EXPECT_NE(-1, ringfree(&ring));
}

71
test/libc/runtime/test.mk Normal file
View File

@@ -0,0 +1,71 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_RUNTIME
TEST_LIBC_RUNTIME_SRCS := $(wildcard test/libc/runtime/*.c)
TEST_LIBC_RUNTIME_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_RUNTIME_SRCS))
TEST_LIBC_RUNTIME_COMS = $(TEST_LIBC_RUNTIME_OBJS:%.o=%.com)
TEST_LIBC_RUNTIME_OBJS = \
$(TEST_LIBC_RUNTIME_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_RUNTIME_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_RUNTIME_BINS = \
$(TEST_LIBC_RUNTIME_COMS) \
$(TEST_LIBC_RUNTIME_COMS:%=%.dbg)
TEST_LIBC_RUNTIME_TESTS = \
$(TEST_LIBC_RUNTIME_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_RUNTIME_CHECKS = \
$(TEST_LIBC_RUNTIME_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_RUNTIME_DIRECTDEPS = \
LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_FMT \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_STDIO \
LIBC_STR \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X \
THIRD_PARTY_XED
TEST_LIBC_RUNTIME_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_RUNTIME_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/runtime/runtime.pkg: \
$(TEST_LIBC_RUNTIME_OBJS) \
$(foreach x,$(TEST_LIBC_RUNTIME_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/runtime/%.com.dbg: \
$(TEST_LIBC_RUNTIME_DEPS) \
o/$(MODE)/test/libc/runtime/%.o \
o/$(MODE)/test/libc/runtime/runtime.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_RUNTIME_OBJS): \
DEFAULT_CCFLAGS += \
-fno-builtin
o/$(MODE)/test/libc/runtime/getenv_test.com.runs: \
o/$(MODE)/test/libc/runtime/getenv_test.com
@HELLO=THERE build/runit $@ $<
o/$(MODE)/test/libc/runtime/itsatrap_test.o: \
OVERRIDE_CFLAGS += \
-fno-sanitize=all \
-ftrapv
.PHONY: o/$(MODE)/test/libc/runtime
o/$(MODE)/test/libc/runtime: \
$(TEST_LIBC_RUNTIME_BINS) \
$(TEST_LIBC_RUNTIME_CHECKS)

View File

@@ -0,0 +1,63 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/errno.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
#include "libc/testlib/testlib.h"
TEST(inet_ntop, test) {
char buf[16];
uint8_t localhost[4] = {127, 0, 0, 1};
EXPECT_STREQ("127.0.0.1", inet_ntop(AF_INET, localhost, buf, sizeof(buf)));
}
TEST(inet_ntop, testMax) {
char buf[16];
uint8_t localhost[4] = {255, 255, 255, 255};
EXPECT_STREQ("255.255.255.255",
inet_ntop(AF_INET, localhost, buf, sizeof(buf)));
}
TEST(inet_ntop, testBadFamily) {
char buf[16] = "hi";
uint8_t localhost[4] = {127, 0, 0, 1};
ASSERT_EQ(NULL, inet_ntop(666, localhost, buf, sizeof(buf)));
EXPECT_EQ(EAFNOSUPPORT, errno);
ASSERT_STREQ("", buf);
}
TEST(inet_ntop, testNoSpace) {
char *buf = memcpy(tmalloc(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);
}
TEST(inet_ntop, testSqueeze) {
char *buf = memcpy(tmalloc(8), "hi", 3);
uint8_t localhost[4] = {0, 0, 0, 0};
ASSERT_STREQ("0.0.0.0", inet_ntop(AF_INET, localhost, buf, 8));
tfree(buf);
}

View File

@@ -0,0 +1,42 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/progn.h"
#include "libc/bits/safemacros.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/inaddr.h"
#include "libc/testlib/testlib.h"
TEST(inet_pton, testLocalhost) {
uint32_t addr;
EXPECT_EQ(htonl(INADDR_LOOPBACK),
PROGN(ASSERT_EQ(1, inet_pton(AF_INET, "127.0.0.1", &addr)), addr));
}
TEST(inet_pton, testBadAddresses) {
uint32_t addr;
ASSERT_EQ(0, inet_pton(AF_INET, "127.0.0", &addr));
ASSERT_EQ(0, inet_pton(AF_INET, "256.0.0.1", &addr));
}
TEST(inet_pton, testBadFamily) {
uint32_t addr = 666;
ASSERT_EQ(-1, inet_pton(666, "127.0.0.1", &addr));
}

View File

@@ -0,0 +1,80 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/macros.h"
#include "libc/runtime/gc.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/limits.h"
#include "libc/sysv/consts/poll.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
#include "tool/decode/lib/flagger.h"
#include "tool/decode/lib/pollnames.h"
#if 0 /* todo(jart): fix me */
#define POLL(FDS, TIMEOUT) \
poll(((struct pollfd[])FDS), ARRAYLEN(((struct pollfd[])FDS)), TIMOUT)
nodiscard char *FormatPollFd(struct pollfd *pol) {
return xasprintf("fd:%d revents:%s", pol->fd,
gc(recreateflags(kPollNames, pol->revents)));
}
TEST(poll, testNegativeOneFd_completelyIgnored) {
struct pollfd fds[] = {{-1}};
EXPECT_EQ(0, poll(fds, ARRAYLEN(fds), 0));
EXPECT_STREQ("fd:-1 revents:0", gc(FormatPollFd(&fds[0])));
}
TEST(poll, demo) {
int rw[2];
char buf[2] = "hi";
ASSERT_NE(-1, pipe(rw));
ASSERT_EQ(2, write(rw[1], buf, sizeof(buf))); /* produce */
{
struct pollfd fds[] = {{rw[0], POLLIN}, {rw[1], POLLOUT}};
EXPECT_EQ(2, poll(fds, ARRAYLEN(fds), 0));
system(gc(xasprintf("ls -l /proc/%d/fd", getpid())));
EXPECT_STREQ("fd:3 revents:POLLIN", gc(FormatPollFd(fds + 0)));
EXPECT_STREQ("fd:4 revents:POLLOUT", gc(FormatPollFd(&fds[1])));
}
ASSERT_EQ(2, read(rw[0], buf, sizeof(buf))); /* consume */
{
struct pollfd fds[] = {{rw[0], POLLIN}, {rw[1], POLLOUT}};
EXPECT_EQ(1, poll(fds, ARRAYLEN(fds), 0));
EXPECT_STREQ("fd:3 revents:0", gc(FormatPollFd(&fds[0])));
EXPECT_STREQ("fd:4 revents:POLLOUT", gc(FormatPollFd(&fds[1])));
}
ASSERT_NE(-1, close(rw[1])); /* close producer */
{
struct pollfd fds[] = {{rw[0], POLLIN}, {rw[1], POLLOUT}};
EXPECT_EQ(2, poll(fds, ARRAYLEN(fds), 0));
EXPECT_STREQ("fd:3 revents:POLLHUP", gc(FormatPollFd(&fds[0])));
EXPECT_STREQ("fd:4 revents:POLLNVAL", gc(FormatPollFd(&fds[1])));
}
ASSERT_NE(-1, close(rw[0])); /* close consumer */
}
#endif

61
test/libc/sock/test.mk Normal file
View File

@@ -0,0 +1,61 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_LIBC_SOCK
TEST_LIBC_SOCK_SRCS := $(wildcard test/libc/sock/*.c)
TEST_LIBC_SOCK_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_SOCK_SRCS))
TEST_LIBC_SOCK_COMS = $(TEST_LIBC_SOCK_OBJS:%.o=%.com)
TEST_LIBC_SOCK_OBJS = \
$(TEST_LIBC_SOCK_SRCS:%=o/$(MODE)/%.zip.o) \
$(TEST_LIBC_SOCK_SRCS:%.c=o/$(MODE)/%.o)
TEST_LIBC_SOCK_BINS = \
$(TEST_LIBC_SOCK_COMS) \
$(TEST_LIBC_SOCK_COMS:%=%.dbg)
TEST_LIBC_SOCK_TESTS = \
$(TEST_LIBC_SOCK_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
TEST_LIBC_SOCK_CHECKS = \
$(TEST_LIBC_SOCK_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
TEST_LIBC_SOCK_DIRECTDEPS = \
LIBC_CALLS \
LIBC_CALLS_HEFTY \
LIBC_STDIO \
LIBC_FMT \
LIBC_NEXGEN32E \
LIBC_RUNTIME \
LIBC_SOCK \
LIBC_STUBS \
LIBC_SYSV \
LIBC_TESTLIB \
LIBC_X \
TOOL_DECODE_LIB
TEST_LIBC_SOCK_DEPS := \
$(call uniq,$(foreach x,$(TEST_LIBC_SOCK_DIRECTDEPS),$($(x))))
o/$(MODE)/test/libc/sock/sock.pkg: \
$(TEST_LIBC_SOCK_OBJS) \
$(foreach x,$(TEST_LIBC_SOCK_DIRECTDEPS),$($(x)_A).pkg)
o/$(MODE)/test/libc/sock/%.com.dbg: \
$(TEST_LIBC_SOCK_DEPS) \
o/$(MODE)/test/libc/sock/%.o \
o/$(MODE)/test/libc/sock/sock.pkg \
$(LIBC_TESTMAIN) \
$(CRT) \
$(APE)
@$(APELINK)
$(TEST_LIBC_SOCK_OBJS): \
$(BUILD_FILES) \
test/libc/sock/test.mk
.PHONY: o/$(MODE)/test/libc/sock
o/$(MODE)/test/libc/sock: \
$(TEST_LIBC_SOCK_BINS) \
$(TEST_LIBC_SOCK_CHECKS)

View File

@@ -0,0 +1,70 @@
/*-*- 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 │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/calls/calls.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
int pipefd[2];
FILE *f, *reader, *writer;
TEST(fgetc, testEnd) {
f = fmemopen(NULL, BUFSIZ, "r+");
EXPECT_EQ(EOF, fgetc(f));
EXPECT_TRUE(feof(f));
EXPECT_FALSE(ferror(f));
EXPECT_EQ(0, fclose(f));
}
TEST(fgetwc, testEnd) {
f = fmemopen(NULL, BUFSIZ, "r+");
EXPECT_EQ(WEOF, fgetwc(f));
EXPECT_TRUE(feof(f));
EXPECT_FALSE(ferror(f));
EXPECT_EQ(0, fclose(f));
}
TEST(fgetwc, testMultibyte) {
f = fmemopen(NULL, BUFSIZ, "r+");
EXPECT_EQ(L'𝑥', fputwc(L'𝑥', f));
EXPECT_EQ(L'𝑦', fputwc(L'𝑦', f));
EXPECT_EQ(L'𝑧', fputwc(L'𝑧', f));
EXPECT_EQ(L'𝑥', fgetwc(f));
EXPECT_EQ(L'𝑦', fgetwc(f));
EXPECT_EQ(L'𝑧', fgetwc(f));
EXPECT_EQ(WEOF, fgetwc(f));
EXPECT_TRUE(feof(f));
fclose(f);
}
TEST(fgetc, testPipe) {
ASSERT_NE(-1, pipe(pipefd));
writer = fdopen(pipefd[1], "w");
reader = fdopen(pipefd[0], "r");
EXPECT_EQ('a', fputc('a', writer));
EXPECT_EQ('b', fputc('b', writer));
EXPECT_EQ('c', fputc('c', writer));
EXPECT_EQ(3, fflush(writer));
EXPECT_EQ('a', fgetc(reader));
EXPECT_EQ('b', fgetc(reader));
EXPECT_EQ('c', fgetc(reader));
EXPECT_EQ(0, fclose(reader));
EXPECT_EQ(0, fclose(writer));
}

Some files were not shown because too many files have changed in this diff Show More