mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 22:02:27 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
97
test/libc/alg/arraylist_test.c
Normal file
97
test/libc/alg/arraylist_test.c
Normal 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);
|
||||
}
|
58
test/libc/alg/bisectcarleft_test.c
Normal file
58
test/libc/alg/bisectcarleft_test.c
Normal 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));
|
||||
}
|
110
test/libc/alg/comparator_test.c
Normal file
110
test/libc/alg/comparator_test.c
Normal 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);
|
||||
}
|
125
test/libc/alg/critbit0_test.c
Normal file
125
test/libc/alg/critbit0_test.c
Normal 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);
|
||||
}
|
87
test/libc/alg/djbsort_test.c
Normal file
87
test/libc/alg/djbsort_test.c
Normal 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
116
test/libc/alg/memmem_test.c
Normal 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);
|
||||
}
|
38
test/libc/alg/qsort_test.c
Normal file
38
test/libc/alg/qsort_test.c
Normal 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);
|
||||
}
|
40
test/libc/alg/replacestr_test.c
Normal file
40
test/libc/alg/replacestr_test.c
Normal 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 */
|
38
test/libc/alg/replacestr_test.inc
Normal file
38
test/libc/alg/replacestr_test.inc
Normal 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")));
|
||||
}
|
40
test/libc/alg/reverse_test.c
Normal file
40
test/libc/alg/reverse_test.c
Normal 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]);
|
||||
}
|
84
test/libc/alg/strstr_test.c
Normal file
84
test/libc/alg/strstr_test.c
Normal 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
126
test/libc/alg/tarjan_test.c
Normal 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
63
test/libc/alg/test.mk
Normal 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)
|
Loading…
Add table
Add a link
Reference in a new issue