mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 16:28:30 +00:00
Fold LIBC_ALG into LIBC_MEM
This commit is contained in:
parent
7cf66bc161
commit
17aea99bb3
162 changed files with 265 additions and 430 deletions
99
test/libc/mem/arraylist_test.c
Normal file
99
test/libc/mem/arraylist_test.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/arraylist.internal.h"
|
||||
#include "libc/log/libfatal.internal.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);
|
||||
}
|
57
test/libc/mem/bisectcarleft_test.c
Normal file
57
test/libc/mem/bisectcarleft_test.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/bisectcarleft.internal.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/macros.internal.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/mem/comparator_test.c
Normal file
110
test/libc/mem/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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(comparator, testByteCompare) {
|
||||
char *b1 = malloc(1);
|
||||
char *b2 = malloc(1);
|
||||
/* sign doesn't matter */
|
||||
EXPECT_EQ(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0);
|
||||
EXPECT_LT(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0);
|
||||
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);
|
||||
free(b2);
|
||||
free(b1);
|
||||
}
|
||||
|
||||
TEST(comparator, testWordCompare) {
|
||||
char *b1 = malloc(2);
|
||||
char *b2 = malloc(2);
|
||||
EXPECT_EQ(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0);
|
||||
EXPECT_GT(cmpsw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0);
|
||||
EXPECT_LT(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0);
|
||||
EXPECT_EQ(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0);
|
||||
EXPECT_LT(cmpuw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0);
|
||||
EXPECT_GT(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0);
|
||||
free(b2);
|
||||
free(b1);
|
||||
}
|
||||
|
||||
TEST(comparator, testDoublewordCompare) {
|
||||
char *b1 = malloc(4);
|
||||
char *b2 = malloc(4);
|
||||
EXPECT_EQ(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4),
|
||||
memcpy(b2, "\x00\x00\x00\x80", 4)),
|
||||
0);
|
||||
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);
|
||||
free(b2);
|
||||
free(b1);
|
||||
}
|
||||
|
||||
TEST(comparator, testQuadwordCompare) {
|
||||
char *b1 = malloc(8);
|
||||
char *b2 = malloc(8);
|
||||
EXPECT_EQ(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
|
||||
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
|
||||
0);
|
||||
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);
|
||||
free(b2);
|
||||
free(b1);
|
||||
}
|
130
test/libc/mem/critbit0_test.c
Normal file
130
test/libc/mem/critbit0_test.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/critbit0.h"
|
||||
#include "libc/intrin/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 dontdiscard 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);
|
||||
}
|
86
test/libc/mem/djbsort_test.c
Normal file
86
test/libc/mem/djbsort_test.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/gc.internal.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(gc(malloc(n * 4)), kA, n * 4);
|
||||
b = memcpy(gc(malloc(n * 4)), kA, n * 4);
|
||||
c = memcpy(gc(malloc(n * 4)), kA, n * 4);
|
||||
insertionsort(a, n);
|
||||
djbsort_avx2(b, n);
|
||||
djbsort(c, n);
|
||||
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(gc(malloc(n * 4)), kA, n * 4);
|
||||
b = memcpy(gc(malloc(n * 4)), kA, n * 4);
|
||||
c = memcpy(gc(malloc(n * 4)), kA, n * 4);
|
||||
insertionsort(a, n);
|
||||
djbsort(c, n);
|
||||
ASSERT_EQ(0, memcmp(a, c, n * 4));
|
||||
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(a, n));
|
||||
EZBENCH2("djbsort[255]", rngset(a, n * 4, rand64, -1), djbsort(a, n));
|
||||
}
|
41
test/libc/mem/replacestr_test.c
Normal file
41
test/libc/mem/replacestr_test.c
Normal 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(replacestr, demo) {
|
||||
EXPECT_STREQ("hello friends",
|
||||
gc(replacestr("hello world", "world", "friends")));
|
||||
EXPECT_STREQ("bbbbbbbb", gc(replacestr("aaaa", "a", "bb")));
|
||||
}
|
||||
|
||||
TEST(replacestr, emptyString) {
|
||||
EXPECT_STREQ("", gc(replacestr("", "x", "y")));
|
||||
}
|
||||
|
||||
TEST(replacestr, emptyNeedle) {
|
||||
EXPECT_EQ(NULL, gc(replacestr("a", "", "a")));
|
||||
EXPECT_EQ(EINVAL, errno);
|
||||
}
|
||||
|
||||
TEST(replacestr, needleInReplacement_doesntExplode) {
|
||||
EXPECT_STREQ("xxxxxxx", gc(replacestr("x", "x", "xxxxxxx")));
|
||||
}
|
37
test/libc/mem/replacestr_test.inc
Normal file
37
test/libc/mem/replacestr_test.inc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
|
||||
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")));
|
||||
}
|
39
test/libc/mem/reverse_test.c
Normal file
39
test/libc/mem/reverse_test.c
Normal 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/reverse.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.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]);
|
||||
}
|
123
test/libc/mem/tarjan_test.c
Normal file
123
test/libc/mem/tarjan_test.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
STATIC_YOINK("realloc");
|
||||
|
||||
TEST(tarjan, empty_doesNothing) {
|
||||
int sorted_vertices[1] = {-1};
|
||||
int edges[][2] = {{0, 0}};
|
||||
int vertex_count = 0;
|
||||
int edge_count = 0;
|
||||
tarjan(vertex_count, (void *)edges, edge_count, sorted_vertices, NULL, NULL);
|
||||
ASSERT_EQ(-1, 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"};
|
||||
int 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
|
||||
*/
|
||||
int 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─┘ */
|
||||
int 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 */}};
|
||||
int 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/intrin/bits.h",
|
||||
[LIBC_INTEGRAL] = "libc/integral.h",
|
||||
[LIBC_KEYWORDS] = "libc/keywords.h",
|
||||
[LIBC_DCE] = "libc/dce.h",
|
||||
[LIBC_MACROS] = "libc/macros.internal.h",
|
||||
[LIBC_MACROS_CPP] = "libc/macros-cpp.inc",
|
||||
};
|
||||
int 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},
|
||||
};
|
||||
int sorted[ARRAYLEN(vertices)];
|
||||
int components[ARRAYLEN(vertices)];
|
||||
int 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.internal.h", vertices[sorted[4]]);
|
||||
EXPECT_STREQ("libc/intrin/bits.h", vertices[sorted[5]]);
|
||||
EXPECT_STREQ("libc/str/str.h", vertices[sorted[6]]);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue