mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +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)
|
46
test/libc/bits/bitreverse_test.c
Normal file
46
test/libc/bits/bitreverse_test.c
Normal 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
66
test/libc/bits/bt_test.c
Normal 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));
|
||||
}
|
50
test/libc/bits/integralarithmetic_test.c
Normal file
50
test/libc/bits/integralarithmetic_test.c
Normal 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));
|
||||
}
|
60
test/libc/bits/morton_test.c
Normal file
60
test/libc/bits/morton_test.c
Normal 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))));
|
||||
}
|
39
test/libc/bits/rounddown2pow_test.c
Normal file
39
test/libc/bits/rounddown2pow_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 │
|
||||
│ │
|
||||
│ 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));
|
||||
}
|
35
test/libc/bits/roundup2log_test.c
Normal file
35
test/libc/bits/roundup2log_test.c
Normal 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));
|
||||
}
|
39
test/libc/bits/roundup2pow_test.c
Normal file
39
test/libc/bits/roundup2pow_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 │
|
||||
│ │
|
||||
│ 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
54
test/libc/bits/test.mk
Normal 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)
|
31
test/libc/bits/unsignedsubtract_test.c
Normal file
31
test/libc/bits/unsignedsubtract_test.c
Normal 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));
|
||||
}
|
40
test/libc/calls/access_test.c
Normal file
40
test/libc/calls/access_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/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));
|
||||
}
|
90
test/libc/calls/fallocate_test.c
Normal file
90
test/libc/calls/fallocate_test.c
Normal 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);
|
||||
}
|
49
test/libc/calls/ftruncate_test.c
Normal file
49
test/libc/calls/ftruncate_test.c
Normal 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);
|
||||
}
|
77
test/libc/calls/hefty/commandv_test.c
Normal file
77
test/libc/calls/hefty/commandv_test.c
Normal 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);
|
||||
}
|
54
test/libc/calls/hefty/dirstream_test.c
Normal file
54
test/libc/calls/hefty/dirstream_test.c
Normal 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));
|
||||
}
|
77
test/libc/calls/hefty/mkntcmdline_test.c
Normal file
77
test/libc/calls/hefty/mkntcmdline_test.c
Normal 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)))));
|
||||
}
|
39
test/libc/calls/hefty/mkntenvblock_test.c
Normal file
39
test/libc/calls/hefty/mkntenvblock_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 │
|
||||
│ │
|
||||
│ 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)));
|
||||
}
|
33
test/libc/calls/hefty/sortenvp_test.c
Normal file
33
test/libc/calls/hefty/sortenvp_test.c
Normal 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]);
|
||||
}
|
74
test/libc/calls/hefty/spawnve_test.c
Normal file
74
test/libc/calls/hefty/spawnve_test.c
Normal 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};
|
45
test/libc/calls/mkntpath_test.c
Normal file
45
test/libc/calls/mkntpath_test.c
Normal 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);
|
||||
}
|
34
test/libc/calls/signal_test.c
Normal file
34
test/libc/calls/signal_test.c
Normal 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();
|
||||
}
|
43
test/libc/calls/stat_test.c
Normal file
43
test/libc/calls/stat_test.c
Normal 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
60
test/libc/calls/test.mk
Normal 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)
|
44
test/libc/conv/basename_test.c
Normal file
44
test/libc/conv/basename_test.c
Normal 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"));
|
||||
}
|
36
test/libc/conv/llog10_test.c
Normal file
36
test/libc/conv/llog10_test.c
Normal 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));
|
||||
}
|
50
test/libc/conv/sizemultiply_test.c
Normal file
50
test/libc/conv/sizemultiply_test.c
Normal 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);
|
||||
}
|
38
test/libc/conv/strtoimax_test.c
Normal file
38
test/libc/conv/strtoimax_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/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));
|
||||
}
|
35
test/libc/conv/strtoumax_test.c
Normal file
35
test/libc/conv/strtoumax_test.c
Normal 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
57
test/libc/conv/test.mk
Normal 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)
|
33
test/libc/conv/timevaltofiletime_test.c
Normal file
33
test/libc/conv/timevaltofiletime_test.c
Normal 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);
|
||||
}
|
333
test/libc/crypto/rijndael_test.c
Normal file
333
test/libc/crypto/rijndael_test.c
Normal 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
49
test/libc/crypto/test.mk
Normal 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)
|
48
test/libc/dns/dnsheader_test.c
Normal file
48
test/libc/dns/dnsheader_test.c
Normal 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);
|
||||
}
|
101
test/libc/dns/dnsnamecmp_test.c
Normal file
101
test/libc/dns/dnsnamecmp_test.c
Normal 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);
|
||||
}
|
50
test/libc/dns/dnsquestion_test.c
Normal file
50
test/libc/dns/dnsquestion_test.c
Normal 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);
|
||||
}
|
84
test/libc/dns/parsehoststxt_test.c
Normal file
84
test/libc/dns/parsehoststxt_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/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);
|
||||
}
|
76
test/libc/dns/parseresolvconf_test.c
Normal file
76
test/libc/dns/parseresolvconf_test.c
Normal 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);
|
||||
}
|
79
test/libc/dns/pascalifydnsname_test.c
Normal file
79
test/libc/dns/pascalifydnsname_test.c
Normal 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);
|
||||
}
|
83
test/libc/dns/resolvehoststxt_test.c
Normal file
83
test/libc/dns/resolvehoststxt_test.c
Normal 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
59
test/libc/dns/test.mk
Normal 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)
|
653
test/libc/fmt/palandprintf_test.c
Normal file
653
test/libc/fmt/palandprintf_test.c
Normal 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);
|
||||
}
|
76
test/libc/fmt/sprintf_s.inc
Normal file
76
test/libc/fmt/sprintf_s.inc
Normal 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, "ちゃぶ台返し"));
|
||||
}
|
60
test/libc/fmt/sprintf_s_test.c
Normal file
60
test/libc/fmt/sprintf_s_test.c
Normal 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
144
test/libc/fmt/sscanf_test.c
Normal 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);
|
||||
}
|
54
test/libc/fmt/strerror_test.c
Normal file
54
test/libc/fmt/strerror_test.c
Normal 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
55
test/libc/fmt/test.mk
Normal 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)
|
70
test/libc/intrin/packuswb_test.c
Normal file
70
test/libc/intrin/packuswb_test.c
Normal 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]);
|
||||
}
|
55
test/libc/intrin/paddw_test.c
Normal file
55
test/libc/intrin/paddw_test.c
Normal 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]);
|
||||
}
|
87
test/libc/intrin/palignr_test.c
Normal file
87
test/libc/intrin/palignr_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/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]);
|
||||
}
|
46
test/libc/intrin/phaddsw_test.c
Normal file
46
test/libc/intrin/phaddsw_test.c
Normal 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");
|
||||
}
|
48
test/libc/intrin/phaddw_test.c
Normal file
48
test/libc/intrin/phaddw_test.c
Normal 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");
|
||||
}
|
116
test/libc/intrin/pmulhrsw_test.c
Normal file
116
test/libc/intrin/pmulhrsw_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 "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]));
|
||||
}
|
38
test/libc/intrin/psraw_test.c
Normal file
38
test/libc/intrin/psraw_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/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
51
test/libc/intrin/test.mk
Normal 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
30
test/libc/math/exp_test.c
Normal 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)));
|
||||
}
|
39
test/libc/math/pow10_test.c
Normal file
39
test/libc/math/pow10_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 │
|
||||
│ │
|
||||
│ 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));
|
||||
}
|
52
test/libc/math/powl_test.c
Normal file
52
test/libc/math/powl_test.c
Normal 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)); */
|
||||
}
|
77
test/libc/math/round_test.c
Normal file
77
test/libc/math/round_test.c
Normal 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
56
test/libc/math/test.mk
Normal 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)
|
24
test/libc/mem/malloc_test.c
Normal file
24
test/libc/mem/malloc_test.c
Normal 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)); }
|
41
test/libc/mem/strdup_test.c
Normal file
41
test/libc/mem/strdup_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 │
|
||||
│ │
|
||||
│ 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
51
test/libc/mem/test.mk
Normal 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)
|
42
test/libc/nexgen32e/crc32_test.c
Normal file
42
test/libc/nexgen32e/crc32_test.c
Normal 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));
|
||||
}
|
||||
}
|
96
test/libc/nexgen32e/lz4decode_test.c
Normal file
96
test/libc/nexgen32e/lz4decode_test.c
Normal 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);
|
||||
}
|
103
test/libc/nexgen32e/memeqmask_test.c
Normal file
103
test/libc/nexgen32e/memeqmask_test.c
Normal 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
|
28
test/libc/nexgen32e/strsak32_test.c
Normal file
28
test/libc/nexgen32e/strsak32_test.c
Normal 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"));
|
||||
}
|
58
test/libc/nexgen32e/strtolower_test.c
Normal file
58
test/libc/nexgen32e/strtolower_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/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));
|
||||
}
|
68
test/libc/nexgen32e/test.mk
Normal file
68
test/libc/nexgen32e/test.mk
Normal 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)
|
39
test/libc/rand/devrand_test.c
Normal file
39
test/libc/rand/devrand_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 │
|
||||
│ │
|
||||
│ 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);
|
||||
}
|
45
test/libc/rand/rand_test.c
Normal file
45
test/libc/rand/rand_test.c
Normal 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
59
test/libc/rand/test.mk
Normal 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)
|
72
test/libc/runtime/arch_prctl_test.c
Normal file
72
test/libc/runtime/arch_prctl_test.c
Normal 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);
|
||||
}
|
||||
}
|
105
test/libc/runtime/balloc_test.c
Normal file
105
test/libc/runtime/balloc_test.c
Normal 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);
|
||||
}
|
81
test/libc/runtime/gc_test.c
Normal file
81
test/libc/runtime/gc_test.c
Normal 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);
|
||||
}
|
171
test/libc/runtime/getdosargv_test.c
Normal file
171
test/libc/runtime/getdosargv_test.c
Normal 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);
|
||||
}
|
103
test/libc/runtime/getdosenviron_test.c
Normal file
103
test/libc/runtime/getdosenviron_test.c
Normal 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);
|
||||
}
|
98
test/libc/runtime/grow_test.c
Normal file
98
test/libc/runtime/grow_test.c
Normal 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);
|
||||
}
|
35
test/libc/runtime/heapsortcar_test.c
Normal file
35
test/libc/runtime/heapsortcar_test.c
Normal 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)));
|
||||
}
|
248
test/libc/runtime/itsatrap_test.c
Normal file
248
test/libc/runtime/itsatrap_test.c
Normal 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_);
|
||||
}
|
58
test/libc/runtime/mappings_test.c
Normal file
58
test/libc/runtime/mappings_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/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));
|
||||
}
|
146
test/libc/runtime/mmap_test.c
Normal file
146
test/libc/runtime/mmap_test.c
Normal 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));
|
||||
}
|
48
test/libc/runtime/ringalloc_test.c
Normal file
48
test/libc/runtime/ringalloc_test.c
Normal 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
71
test/libc/runtime/test.mk
Normal 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)
|
63
test/libc/sock/inet_ntop_test.c
Normal file
63
test/libc/sock/inet_ntop_test.c
Normal 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);
|
||||
}
|
42
test/libc/sock/inet_pton_test.c
Normal file
42
test/libc/sock/inet_pton_test.c
Normal 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));
|
||||
}
|
80
test/libc/sock/poll_test.c
Normal file
80
test/libc/sock/poll_test.c
Normal 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
61
test/libc/sock/test.mk
Normal 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)
|
70
test/libc/stdio/fgetc_test.c
Normal file
70
test/libc/stdio/fgetc_test.c
Normal 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
Loading…
Add table
Add a link
Reference in a new issue