mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-29 08:42:28 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
25
test/ape/lib/flattenhighmemory_test.c
Normal file
25
test/ape/lib/flattenhighmemory_test.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*-*- 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/testlib/testlib.h"
|
||||
|
||||
TEST(flattenhighmemory, test) {
|
||||
/* EXPECT_EQ(0, flattenhighmemory()); */
|
||||
/* EXPECT_STREQ("", flattenhighmemory()); */
|
||||
}
|
66
test/ape/lib/getpagetableentry_test.c
Normal file
66
test/ape/lib/getpagetableentry_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 "ape/lib/pc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(getpagetableentry, testLowestAddress) {
|
||||
static struct PageTable pml4t;
|
||||
static struct PageTable stack[3];
|
||||
uint64_t ptsp = (uintptr_t)&stack + sizeof(stack);
|
||||
memset(&pml4t, 0, sizeof(pml4t));
|
||||
memset(&stack, 0, sizeof(stack));
|
||||
uint64_t vaddr = 0;
|
||||
uint64_t paddr = 0x31337000;
|
||||
*getpagetableentry(vaddr, 3, &pml4t, &ptsp) = paddr | PAGE_V;
|
||||
EXPECT_EQ(&stack[2].p[0], pml4t.p[0] & PAGE_TA); /* pml4t → pdpt */
|
||||
EXPECT_EQ(&stack[1].p[0], stack[2].p[0] & PAGE_TA); /* pdpt → pdt */
|
||||
EXPECT_EQ(&stack[0].p[0], stack[1].p[0] & PAGE_TA); /* pdt → pd */
|
||||
EXPECT_EQ(stack[0].p[0] & PAGE_TA, paddr); /* page */
|
||||
EXPECT_EQ(&stack, ptsp);
|
||||
EXPECT_TRUE(pml4t.p[0] & PAGE_V);
|
||||
EXPECT_TRUE(stack[2].p[0] & PAGE_V);
|
||||
EXPECT_TRUE(stack[1].p[0] & PAGE_V);
|
||||
EXPECT_TRUE(stack[0].p[0] & PAGE_V);
|
||||
EXPECT_FALSE(stack[0].p[1] & PAGE_V);
|
||||
}
|
||||
|
||||
TEST(getpagetableentry, testHigherAddress) {
|
||||
static struct PageTable pml4t;
|
||||
static struct PageTable stack[3];
|
||||
uint64_t ptsp = (uintptr_t)&stack + sizeof(stack);
|
||||
memset(&pml4t, 0, sizeof(pml4t));
|
||||
memset(&stack, 0, sizeof(stack));
|
||||
uint64_t vaddr = 0x133731337000;
|
||||
uint64_t paddr = 0x123000;
|
||||
*getpagetableentry(vaddr, 3, &pml4t, &ptsp) = paddr | PAGE_V;
|
||||
EXPECT_EQ(&stack[2].p[0], pml4t.p[38] & PAGE_TA); /* pml4t → pdpt */
|
||||
EXPECT_EQ(&stack[1].p[0], stack[2].p[220] & PAGE_TA); /* pdpt → pdt */
|
||||
EXPECT_EQ(&stack[0].p[0], stack[1].p[393] & PAGE_TA); /* pdt → pd */
|
||||
EXPECT_EQ(stack[0].p[311] & PAGE_TA, paddr); /* page */
|
||||
EXPECT_EQ(&stack, ptsp);
|
||||
EXPECT_TRUE(pml4t.p[38] & PAGE_V);
|
||||
EXPECT_TRUE(stack[2].p[220] & PAGE_V);
|
||||
EXPECT_TRUE(stack[1].p[393] & PAGE_V);
|
||||
EXPECT_TRUE(stack[0].p[311] & PAGE_V);
|
||||
EXPECT_FALSE(stack[0].p[0] & PAGE_V);
|
||||
}
|
81
test/ape/lib/smapsort_test.c
Normal file
81
test/ape/lib/smapsort_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 "ape/lib/pc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(smapsort, testEmpty_doesntOverrunBuffer) {
|
||||
struct SmapEntry *smap = tmalloc(sizeof(struct SmapEntry));
|
||||
memset(smap, 0, sizeof(struct SmapEntry));
|
||||
smapsort(smap);
|
||||
EXPECT_EQ(0, smap[0].addr);
|
||||
EXPECT_EQ(0, smap[0].size);
|
||||
tfree(smap);
|
||||
}
|
||||
|
||||
/* TEST(smapsort, testSorted_doesNothing) { */
|
||||
/* struct SmapEntry *smap = tmalloc(4 * sizeof(struct SmapEntry)); */
|
||||
/* memset(smap, 0, 4 * sizeof(struct SmapEntry)); */
|
||||
/* smap[0].addr = 0; */
|
||||
/* smap[0].size = 0x7000; */
|
||||
/* smap[0].type = kMemoryUsable; */
|
||||
/* smap[1].addr = 0x7000; */
|
||||
/* smap[1].size = 0x1000; */
|
||||
/* smap[1].type = kMemoryUnusable; */
|
||||
/* smap[2].addr = 0x14000; */
|
||||
/* smap[2].size = 0x1000; */
|
||||
/* smap[2].type = kMemoryBad; */
|
||||
/* smapsort(smap); */
|
||||
/* EXPECT_EQ(0, smap[0].addr); */
|
||||
/* EXPECT_EQ(0x7000, smap[0].size); */
|
||||
/* EXPECT_EQ(kMemoryUsable, smap[0].type); */
|
||||
/* EXPECT_EQ(0x7000, smap[1].addr); */
|
||||
/* EXPECT_EQ(0x1000, smap[1].size); */
|
||||
/* EXPECT_EQ(kMemoryUnusable, smap[1].type); */
|
||||
/* EXPECT_EQ(0x14000, smap[2].addr); */
|
||||
/* EXPECT_EQ(0x1000, smap[2].size); */
|
||||
/* EXPECT_EQ(kMemoryBad, smap[2].type); */
|
||||
/* tfree(smap); */
|
||||
/* } */
|
||||
|
||||
/* TEST(smapsort, testUnsorted_sortsByAddress) { */
|
||||
/* struct SmapEntry *smap = tmalloc(4 * sizeof(struct SmapEntry)); */
|
||||
/* memset(smap, 0, 4 * sizeof(struct SmapEntry)); */
|
||||
/* smap[2].addr = 0; */
|
||||
/* smap[2].size = 0x7000; */
|
||||
/* smap[2].type = kMemoryUsable; */
|
||||
/* smap[0].addr = 0x7000; */
|
||||
/* smap[0].size = 0x1000; */
|
||||
/* smap[0].type = kMemoryUnusable; */
|
||||
/* smap[1].addr = 0x14000; */
|
||||
/* smap[1].size = 0x1000; */
|
||||
/* smap[1].type = kMemoryBad; */
|
||||
/* smapsort(smap); */
|
||||
/* EXPECT_EQ(0, smap[0].addr); */
|
||||
/* EXPECT_EQ(0x7000, smap[0].size); */
|
||||
/* EXPECT_EQ(kMemoryUsable, smap[0].type); */
|
||||
/* EXPECT_EQ(0x7000, smap[1].addr); */
|
||||
/* EXPECT_EQ(0x1000, smap[1].size); */
|
||||
/* EXPECT_EQ(kMemoryUnusable, smap[1].type); */
|
||||
/* EXPECT_EQ(0x14000, smap[2].addr); */
|
||||
/* EXPECT_EQ(0x1000, smap[2].size); */
|
||||
/* EXPECT_EQ(kMemoryBad, smap[2].type); */
|
||||
/* tfree(smap); */
|
||||
/* } */
|
52
test/ape/lib/test.mk
Normal file
52
test/ape/lib/test.mk
Normal file
|
@ -0,0 +1,52 @@
|
|||
#-*-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_APE_LIB
|
||||
|
||||
TEST_APE_LIB_SRCS := $(wildcard test/ape/lib/*.c)
|
||||
TEST_APE_LIB_SRCS_TEST = $(filter %_test.c,$(TEST_APE_LIB_SRCS))
|
||||
TEST_APE_LIB_COMS = $(TEST_APE_LIB_OBJS:%.o=%.com)
|
||||
|
||||
TEST_APE_LIB_OBJS = \
|
||||
$(TEST_APE_LIB_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_APE_LIB_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_APE_LIB_BINS = \
|
||||
$(TEST_APE_LIB_COMS) \
|
||||
$(TEST_APE_LIB_COMS:%=%.dbg)
|
||||
|
||||
TEST_APE_LIB_TESTS = \
|
||||
$(TEST_APE_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_APE_LIB_CHECKS = \
|
||||
$(TEST_APE_LIB_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_APE_LIB_DIRECTDEPS = \
|
||||
APE_LIB \
|
||||
LIBC_CALLS_HEFTY \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_X
|
||||
|
||||
TEST_APE_LIB_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_APE_LIB_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/test/ape/lib.pkg: \
|
||||
$(TEST_APE_LIB_OBJS) \
|
||||
$(foreach x,$(TEST_APE_LIB_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/test/ape/lib/%.com.dbg: \
|
||||
$(TEST_APE_LIB_DEPS) \
|
||||
o/$(MODE)/test/ape/lib/%.o \
|
||||
o/$(MODE)/test/ape/lib.pkg \
|
||||
$(LIBC_TESTMAIN) \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/test/ape/lib
|
||||
o/$(MODE)/test/ape/lib: $(TEST_APE_LIB_BINS) \
|
||||
$(TEST_APE_LIB_CHECKS)
|
5
test/ape/test.mk
Normal file
5
test/ape/test.mk
Normal file
|
@ -0,0 +1,5 @@
|
|||
#-*-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───────────────────────┘
|
||||
|
||||
.PHONY: o/$(MODE)/test/ape
|
||||
o/$(MODE)/test/ape: o/$(MODE)/test/ape/lib
|
88
test/dsp/core/dct_test.c
Normal file
88
test/dsp/core/dct_test.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*-*- 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/core.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
TEST(dct, test) {
|
||||
float M[8][8] /* clang-format off */ = {
|
||||
{.509804, .513725, .094118, .219608, .027451, .294118, .172549, .658824},
|
||||
{.019608, .070588, .196078, .015686, .172549, .458824, .713725, .294118},
|
||||
{.380392, .341176, .235294, .737255, .741176, .968627, .607843, .12549},
|
||||
{.560784, .843137, .639216, .929412, .756863, .113725, .643137, .435294},
|
||||
{.878431, .576471, .737255, .356863, .8, .878431, .682353, .866667},
|
||||
{.780392, .070588, .866667, .607843, .792157, .47451, .427451, .043137},
|
||||
{.133333, .976471, .698039, .662745, .035294, .207843, .831373, .627451},
|
||||
{.313725, .580392, .858824, .631373, .784314, .972549, .27451, .94902},
|
||||
} /* clang-format on */;
|
||||
dctjpeg(M);
|
||||
EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\
|
||||
32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\
|
||||
-9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\
|
||||
-6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\
|
||||
-2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\
|
||||
4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\
|
||||
-.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\
|
||||
.64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\
|
||||
.61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237");
|
||||
}
|
||||
|
||||
/* TEST(dct, test2) { */
|
||||
/* float M[8][8] /\* clang-format off *\/ = { */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* {.5,.5,.5,.5,.5,.5,.5,.5}, */
|
||||
/* } /\* clang-format on *\/; */
|
||||
/* dctjpeg(M); */
|
||||
/* EXPECT_FLTMATRIXEQ(5, rint, 8, 8, M, "\n\ */
|
||||
/* 32.86666 -1.46274 -1.4456 -.43895 -1.17255 .19084 .05736 .01672\n\ */
|
||||
/* -9.41551 -2.72135 3.7228 5.47448 .74604 .91144 -1.22542 -.41829\n\ */
|
||||
/* -6.32875 -4.21755 4.42546 -3.86307 -1.93691 -2.1173 1.00377 -1.0752\n\ */
|
||||
/* -2.58232 3.67887 5.65331 -.25753 .89732 1.09837 .93163 .61133\n\ */
|
||||
/* 4.23922 1.36747 3.29469 -1.63407 2.78039 -3.0021 .7602 -.21367\n\ */
|
||||
/* -.11643 3.93022 .80678 -3.70514 .13347 .54381 -2.15087 -.52343\n\ */
|
||||
/* .64248 1.19093 -2.94494 2.66037 1.6624 .04414 .99807 .00514\n\ */
|
||||
/* .61622 -.76318 .75918 .41939 -.38075 -.30623 .09867 -.19237"); */
|
||||
/* } */
|
||||
|
||||
BENCH(dct, bench) {
|
||||
float M[8][8] /* clang-format off */ = {
|
||||
{.101961, .486275, .082353, .082353, .937255, .321569, .14902, .270588},
|
||||
{.384314, .062745, .152941, .003922, .921569, .015686, .247059, 0},
|
||||
{.760784, .023529, .411765, .443137, .862745, .85098, .435294, .631373},
|
||||
{.309804, .141176, .54902, .984314, .478431, .6, .364706, .643137},
|
||||
{.780392, .811765, .458824, .964706, .439216, .941176, .321569, .313725},
|
||||
{.596078, .207843, .133333, .345098, .278431, .192157, .52549, .627451},
|
||||
{.952941, .090196, .290196, .717647, .686275, .713725, .54902, .411765},
|
||||
{.109804, .121569, .403922, .27451, .470588, .007843, .168627, .105882},
|
||||
} /* clang-format on */;
|
||||
void *data = tgc(tmalloc(sizeof(M)));
|
||||
EZBENCH2("dct", memcpy(data, M, sizeof(M)), EXPROPRIATE(dctjpeg(data)));
|
||||
}
|
65
test/dsp/core/dgemm_test.c
Normal file
65
test/dsp/core/dgemm_test.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- 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/xmmintrin.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "third_party/blas/blas.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
TEST(dgemm, test) {
|
||||
double alpha, beta;
|
||||
long m, n, k, lda, ldb, ldc;
|
||||
double A[3][3] = {{1 / 8.}, {6 / 8.}, {1 / 8.}};
|
||||
double B[1][3] = {{1 / 8., 6 / 8., 1 / 8.}};
|
||||
double C[3][3] = {0};
|
||||
m = 3;
|
||||
n = 3;
|
||||
k = 1;
|
||||
lda = 3;
|
||||
ldb = 3;
|
||||
ldc = 3;
|
||||
beta = 1;
|
||||
alpha = 1;
|
||||
dgemm_("T", "T", &m, &n, &k, &alpha, &A[0][0], &lda, &B[0][0], &ldb, &beta,
|
||||
&C[0][0], &ldc);
|
||||
EXPECT_DBLMATRIXEQ(6, rint, 3, 3, C, "\n\
|
||||
.015625 .09375 .015625\n\
|
||||
.09375 .5625 .09375\n\
|
||||
.015625 .09375 .015625");
|
||||
}
|
||||
|
||||
void dgemmer(long m, long n, long k, void *A, long lda, void *B, long ldb,
|
||||
void *C, long ldc) {
|
||||
double alpha, beta;
|
||||
beta = 1;
|
||||
alpha = 1;
|
||||
dgemm_("N", "N", &m, &n, &k, &alpha, A, &lda, B, &ldb, &beta, C, &ldc);
|
||||
}
|
||||
|
||||
BENCH(dgemm, bench) {
|
||||
double(*A)[128][128] = tgc(tmalloc(128 * 128 * 8));
|
||||
double(*B)[128][128] = tgc(tmalloc(128 * 128 * 8));
|
||||
double(*C)[128][128] = tgc(tmalloc(128 * 128 * 8));
|
||||
EZBENCH2("dgemm_", donothing, dgemmer(128, 128, 128, A, 128, B, 128, C, 128));
|
||||
}
|
84
test/dsp/core/float2short_test.c
Normal file
84
test/dsp/core/float2short_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 "dsp/core/core.h"
|
||||
#include "dsp/mpeg/mpeg.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/buffer.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
short pcm[8][8];
|
||||
float binary32[8][8];
|
||||
struct GuardedBuffer b1, b2;
|
||||
|
||||
TEST(float2short, test) {
|
||||
binary32[0][0] = -0.5;
|
||||
binary32[0][1] = 0.0;
|
||||
binary32[0][2] = 0.5;
|
||||
float2short(8, pcm, binary32);
|
||||
EXPECT_EQ(-16384, pcm[0][0]);
|
||||
EXPECT_EQ(0, pcm[0][1]);
|
||||
EXPECT_EQ(16384, pcm[0][2]);
|
||||
}
|
||||
|
||||
TEST(float2short, testOverflow) {
|
||||
binary32[0][0] = -1.1;
|
||||
binary32[0][1] = -1.0;
|
||||
binary32[0][2] = 1.0;
|
||||
binary32[0][3] = 1.1;
|
||||
float2short(8, pcm, binary32);
|
||||
EXPECT_EQ(-32768, pcm[0][0]);
|
||||
EXPECT_EQ(-32768, pcm[0][1]);
|
||||
EXPECT_EQ(32767, pcm[0][2]);
|
||||
EXPECT_EQ(32767, pcm[0][3]);
|
||||
}
|
||||
|
||||
void unclamped(size_t n, short pcm16[n][8], const float binary32[n][8]) {
|
||||
size_t i, j;
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
pcm16[i][j] = binary32[i][j] * 32768;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plm_samples_t samps;
|
||||
|
||||
void randomizeaudio(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAYLEN(samps.interleaved); ++i) {
|
||||
samps.interleaved[i] = randf();
|
||||
}
|
||||
}
|
||||
|
||||
void float2short_pure(void) {
|
||||
float2short(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved);
|
||||
}
|
||||
|
||||
void float2short_unclamped(void) {
|
||||
unclamped(ARRAYLEN(samps.interleaved) / 8, pcm, (void *)samps.interleaved);
|
||||
}
|
||||
|
||||
BENCH(float2short, audioframe) {
|
||||
EZBENCH(randomizeaudio(), float2short_pure());
|
||||
EZBENCH(randomizeaudio(), float2short_unclamped());
|
||||
}
|
35
test/dsp/core/gamma_test.c
Normal file
35
test/dsp/core/gamma_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 "dsp/core/core.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(gamma, test) {
|
||||
int i;
|
||||
double g, x, a, b;
|
||||
g = 2.4;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
x = i;
|
||||
x /= 255;
|
||||
a = rgb2stdpc(x, g);
|
||||
b = tv2pcgamma(rgb2stdtv(x), g);
|
||||
ASSERT_EQ(true, fabs(a - b) < .000000001, "%d %f %f %f", i, x, a, b);
|
||||
}
|
||||
}
|
62
test/dsp/core/getintegercoefficients8_test.c
Normal file
62
test/dsp/core/getintegercoefficients8_test.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*-*- 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/core.h"
|
||||
#include "dsp/core/q.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
long I[8];
|
||||
|
||||
TEST(GetIntegerCoefficients8, testBt601Vectors) {
|
||||
const struct {
|
||||
int m, L, H;
|
||||
double r[8];
|
||||
long n[8];
|
||||
} V[] = {
|
||||
{8, 16, 235, {.299, .587, .114}, {77, 150, 29}},
|
||||
{9, 16, 235, {.299, .587, .114}, {153, 301, 58}},
|
||||
{10, 16, 235, {.299, .587, .114}, {306, 601, 117}},
|
||||
{11,
|
||||
16,
|
||||
235,
|
||||
{.299, .587, .114, 1, 1, 1},
|
||||
{612, 1202, 234, 2048, 2048, 2048}},
|
||||
{12, 16, 235, {.299, .587, .114}, {1225, 2404, 467}},
|
||||
{13, 16, 235, {.299, .587, .114}, {2449, 4809, 934}},
|
||||
{14, 16, 235, {.299, .587, .114}, {4899, 9617, 1868}},
|
||||
{15, 16, 235, {.299, .587, .114}, {9798, 19235, 3735}},
|
||||
{16, 16, 235, {.299, .587, .114}, {19595, 38470, 7471}},
|
||||
};
|
||||
long i, got[8];
|
||||
for (i = 0; i < ARRAYLEN(V); ++i) {
|
||||
GetIntegerCoefficients8(got, V[i].r, V[i].m, V[i].L, V[i].H);
|
||||
EXPECT_EQ(0, memcmp(V[i].n, got, sizeof(got)),
|
||||
"got={%ld,%ld,%ld,%ld,%ld,%ld}, want={%ld,%ld,%ld,%ld,%ld,%ld}",
|
||||
got[0], got[1], got[2], got[3], got[4], got[5], V[i].n[0],
|
||||
V[i].n[1], V[i].n[2], V[i].n[3], V[i].n[4], V[i].n[5]);
|
||||
}
|
||||
}
|
||||
|
||||
BENCH(GetIntegerCoefficients8, bench) {
|
||||
double C[8] = {.299, .587, .114, .299, .587, .114, .114, .114};
|
||||
EZBENCH2("GetIntegerCoefficients8", donothing,
|
||||
GetIntegerCoefficients8(I, C, 11, 16, 232));
|
||||
}
|
89
test/dsp/core/getintegercoefficients_test.c
Normal file
89
test/dsp/core/getintegercoefficients_test.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*-*- 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/core.h"
|
||||
#include "dsp/core/q.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
long I[6];
|
||||
|
||||
TEST(GetIntegerCoefficients, testBt601Vectors) {
|
||||
const struct {
|
||||
int m, L, H;
|
||||
double r[6];
|
||||
long n[6];
|
||||
} V[] = {
|
||||
{8, 16, 235, {.299, .587, .114}, {77, 150, 29}},
|
||||
{9, 16, 235, {.299, .587, .114}, {153, 301, 58}},
|
||||
{10, 16, 235, {.299, .587, .114}, {306, 601, 117}},
|
||||
{11,
|
||||
16,
|
||||
235,
|
||||
{.299, .587, .114, 1, 1, 1},
|
||||
{612, 1202, IsTiny() ? 233 : 234, 2048, 2048, 2048}},
|
||||
{12, 16, 235, {.299, .587, .114}, {1225, 2404, 467}},
|
||||
{13, 16, 235, {.299, .587, .114}, {2449, 4809, 934}},
|
||||
{14, 16, 235, {.299, .587, .114}, {4899, 9617, 1868}},
|
||||
{15, 16, 235, {.299, .587, .114}, {9798, 19235, IsTiny() ? 3736 : 3735}},
|
||||
{16, 16, 235, {.299, .587, .114}, {19595, 38470, 7471}},
|
||||
};
|
||||
long i, got[6];
|
||||
for (i = 0; i < ARRAYLEN(V); ++i) {
|
||||
GetIntegerCoefficients(got, V[i].r, V[i].m, V[i].L, V[i].H);
|
||||
EXPECT_EQ(0, memcmp(V[i].n, got, sizeof(got)),
|
||||
"got={%ld,%ld,%ld,%ld,%ld,%ld}, want={%ld,%ld,%ld,%ld,%ld,%ld}",
|
||||
got[0], got[1], got[2], got[3], got[4], got[5], V[i].n[0],
|
||||
V[i].n[1], V[i].n[2], V[i].n[3], V[i].n[4], V[i].n[5]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(GetIntegerCoefficients, testForYCbCr2Rgb) {
|
||||
double C[6] = {.299, .587, .114};
|
||||
GetIntegerCoefficients(I, C, 11, 16, 232);
|
||||
EXPECT_EQ(612, I[0]);
|
||||
EXPECT_EQ(1202, I[1]);
|
||||
EXPECT_EQ(IsTiny() ? 233 : 234, I[2]);
|
||||
}
|
||||
|
||||
TEST(GetIntegerCoefficients, testForGaussian) {
|
||||
#define G(A, B, C, D, E) lrint((A + 4 * B + 6 * C + 4 * D + E) / 16.)
|
||||
double C[6] = {1 / 16., 4 / 16., 6 / 16., 4 / 16., 1 / 16.};
|
||||
long M = 22, N[6], B[6] = {12, 191, 174, 205, 35};
|
||||
GetIntegerCoefficients(N, C, M, 0, 255);
|
||||
EXPECT_EQ(262144, N[0]);
|
||||
EXPECT_EQ(1048576, N[1]);
|
||||
EXPECT_EQ(1572864, N[2]);
|
||||
EXPECT_EQ(1048576, N[3]);
|
||||
EXPECT_EQ(262144, N[4]);
|
||||
EXPECT_EQ(G(B[0], B[1], B[2], B[3], B[4]),
|
||||
(N[0] * B[0] + N[1] * B[1] + N[2] * B[2] + N[3] * B[3] +
|
||||
N[4] * B[4] + N[5] * B[5] + (1l << (M - 1))) >>
|
||||
M);
|
||||
}
|
||||
|
||||
BENCH(GetIntegerCoefficients, bench) {
|
||||
double C[6] = {.299, .587, .114};
|
||||
EZBENCH2("getintegercoefficients", donothing,
|
||||
GetIntegerCoefficients(I, C, 11, 16, 232));
|
||||
}
|
50
test/dsp/core/illumination_test.c
Normal file
50
test/dsp/core/illumination_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 "dsp/core/core.h"
|
||||
#include "dsp/core/illumination.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
TEST(GetChromaticAdaptationMatrix, testSuperiorIlluminationBannedInCalifornia) {
|
||||
double M[3][3];
|
||||
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA);
|
||||
EXPECT_DBLMATRIXEQ(5, rint, 3, 3, M, "\n\
|
||||
1.21646 .11099 -.15493\n\
|
||||
.15333 .91523 -.056\n\
|
||||
-.02395 .0359 .31475");
|
||||
}
|
||||
|
||||
TEST(GetChromaticAdaptationMatrix, testD65ToD50_soWeCanCieLab) {
|
||||
double M[3][3];
|
||||
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantD50);
|
||||
EXPECT_DBLMATRIXEQ(6, rint, 3, 3, M, "\n\
|
||||
1.047811 .022887 -.050127\n\
|
||||
.029542 .990484 -.017049\n\
|
||||
-.009234 .015044 .752132");
|
||||
}
|
||||
|
||||
BENCH(GetChromaticAdaptationMatrix, bench) {
|
||||
double M[3][3];
|
||||
EZBENCH2("GetChromaticAdaptationMatrix", donothing,
|
||||
GetChromaticAdaptationMatrix(M, kIlluminantD65, kIlluminantA));
|
||||
}
|
40
test/dsp/core/inv3_test.c
Normal file
40
test/dsp/core/inv3_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 "dsp/core/core.h"
|
||||
#include "dsp/core/illumination.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
TEST(inv3, test) {
|
||||
double M[3][3];
|
||||
inv3(M, kBradford, det3(kBradford));
|
||||
EXPECT_DBLMATRIXEQ(7, rint, 3, 3, M, "\n\
|
||||
.9869929 -.1470543 .1599627\n\
|
||||
.4323053 .5183603 .0492912\n\
|
||||
-.0085287 .0400428 .9684867");
|
||||
}
|
||||
|
||||
BENCH(inv3, bench) {
|
||||
double M[3][3], d;
|
||||
EZBENCH2("det3", donothing, EXPROPRIATE((d = det3(kBradford))));
|
||||
EZBENCH2("inv3", donothing, EXPROPRIATE(inv3(M, kBradford, d)));
|
||||
}
|
108
test/dsp/core/sad16x8n_test.c
Normal file
108
test/dsp/core/sad16x8n_test.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*-*- 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/core.h"
|
||||
#include "dsp/mpeg/mpeg.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/buffer.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
void addsw$pure(size_t n, short x[n][8], const short y[n][8]) {
|
||||
size_t i, j;
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < 8; ++j) {
|
||||
x[i][j] = MIN(MAX(x[i][j] + y[i][j], INT16_MIN), INT16_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
short *pcm1;
|
||||
short *pcm2;
|
||||
struct GuardedBuffer b1, b2;
|
||||
|
||||
TEST(sad16x8n, test) {
|
||||
CHECK_NOTNULL((pcm1 = balloc(&b1, 32, 128 * 2)));
|
||||
CHECK_NOTNULL((pcm2 = balloc(&b2, 32, 128 * 2)));
|
||||
pcm1[0] = 0;
|
||||
pcm2[0] = 0;
|
||||
pcm1[1] = 23;
|
||||
pcm2[1] = 10;
|
||||
pcm1[2] = 23;
|
||||
pcm2[2] = -10;
|
||||
pcm1[3] = 23;
|
||||
pcm2[3] = -46;
|
||||
pcm1[120 + 0] = 0;
|
||||
pcm2[120 + 0] = 0;
|
||||
pcm1[120 + 1] = 23;
|
||||
pcm2[120 + 1] = 10;
|
||||
pcm1[120 + 2] = 23;
|
||||
pcm2[120 + 2] = -10;
|
||||
pcm1[120 + 3] = 23;
|
||||
pcm2[120 + 3] = -46;
|
||||
sad16x8n(128 / 8, (void *)pcm1, (void *)pcm2);
|
||||
EXPECT_EQ(0, pcm1[0]);
|
||||
EXPECT_EQ(33, pcm1[1]);
|
||||
EXPECT_EQ(13, pcm1[2]);
|
||||
EXPECT_EQ(-23, pcm1[3]);
|
||||
EXPECT_EQ(0, pcm1[120 + 0]);
|
||||
EXPECT_EQ(33, pcm1[120 + 1]);
|
||||
EXPECT_EQ(13, pcm1[120 + 2]);
|
||||
EXPECT_EQ(-23, pcm1[120 + 3]);
|
||||
bfree(&b1);
|
||||
bfree(&b2);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// audio frame mixing latency: ~60ns (sse2 10x faster than pure)
|
||||
//
|
||||
// 1f ~= 14ms (cd quality)
|
||||
// (1.0 / 41000) * (1.0 / 2) * (1152 / 1.0)
|
||||
//
|
||||
// 1f ~= 845µs (dolby truehd)
|
||||
// (1.0 / 192000) * (1.0 / 7.1) * (1152 / 1.0)
|
||||
//
|
||||
// @note plm frame always has exactly 1152 floats
|
||||
|
||||
void randomizeaudio(void) {
|
||||
size_t i;
|
||||
for (i = 0; i < PLM_AUDIO_SAMPLES_PER_FRAME; ++i) {
|
||||
pcm1[i] = (rand() - INT_MAX / 2) % INT16_MAX;
|
||||
pcm2[i] = (rand() - INT_MAX / 2) % INT16_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void sad16x8n_sse2(void) {
|
||||
sad16x8n(PLM_AUDIO_SAMPLES_PER_FRAME / 8, (void *)pcm1, (void *)pcm2);
|
||||
}
|
||||
void sad16x8n_pure(void) {
|
||||
addsw$pure(PLM_AUDIO_SAMPLES_PER_FRAME / 8, (void *)pcm1, (void *)pcm2);
|
||||
}
|
||||
|
||||
BENCH(sad16x8n, audioframe) {
|
||||
CHECK_NOTNULL((pcm1 = balloc(&b1, 32, PLM_AUDIO_SAMPLES_PER_FRAME * 2)));
|
||||
CHECK_NOTNULL((pcm2 = balloc(&b2, 32, PLM_AUDIO_SAMPLES_PER_FRAME * 2)));
|
||||
EZBENCH(randomizeaudio(), sad16x8n_pure());
|
||||
EZBENCH(randomizeaudio(), sad16x8n_sse2());
|
||||
bfree(&b1);
|
||||
bfree(&b2);
|
||||
}
|
161
test/dsp/core/scalevolume_test.c
Normal file
161
test/dsp/core/scalevolume_test.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*-*- 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/core.h"
|
||||
#include "dsp/mpeg/mpeg.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/buffer.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
short pcm[8][8];
|
||||
|
||||
TEST(scalevolume, testIncreaseVolumeByOneIncrement) {
|
||||
pcm[0][0] = INT16_MIN;
|
||||
pcm[0][1] = INT16_MIN / 2;
|
||||
pcm[0][2] = -2;
|
||||
pcm[0][3] = -1;
|
||||
pcm[0][4] = 0;
|
||||
pcm[0][5] = 1;
|
||||
pcm[0][6] = 2;
|
||||
pcm[0][7] = INT16_MAX / 2;
|
||||
pcm[1][0] = INT16_MAX;
|
||||
scalevolume(ARRAYLEN(pcm), pcm, 1);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][0]);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][1]);
|
||||
EXPECT_EQ(-4, pcm[0][2]);
|
||||
EXPECT_EQ(-2, pcm[0][3]);
|
||||
EXPECT_EQ(0, pcm[0][4]);
|
||||
EXPECT_EQ(2, pcm[0][5]);
|
||||
EXPECT_EQ(4, pcm[0][6]);
|
||||
EXPECT_EQ(INT16_MAX - 1, pcm[0][7]);
|
||||
EXPECT_EQ(INT16_MAX, pcm[1][0]);
|
||||
}
|
||||
|
||||
TEST(scalevolume, testDecreaseVolumeByOneIncrement) {
|
||||
pcm[0][0] = INT16_MIN;
|
||||
pcm[0][1] = INT16_MIN / 2;
|
||||
pcm[0][2] = -2;
|
||||
pcm[0][3] = -1;
|
||||
pcm[0][4] = 0;
|
||||
pcm[0][5] = 1;
|
||||
pcm[0][6] = 2;
|
||||
pcm[0][7] = INT16_MAX / 2;
|
||||
pcm[1][0] = INT16_MAX;
|
||||
scalevolume(ARRAYLEN(pcm), pcm, -1);
|
||||
EXPECT_EQ(INT16_MIN / 2, pcm[0][0]);
|
||||
EXPECT_EQ(INT16_MIN / 4, pcm[0][1]);
|
||||
EXPECT_EQ(-1, pcm[0][2]);
|
||||
EXPECT_EQ(-1, pcm[0][3]);
|
||||
EXPECT_EQ(0, pcm[0][4]);
|
||||
EXPECT_EQ(0, pcm[0][5]);
|
||||
EXPECT_EQ(1, pcm[0][6]);
|
||||
EXPECT_EQ(INT16_MAX / 4, pcm[0][7]);
|
||||
EXPECT_EQ(INT16_MAX / 2, pcm[1][0]);
|
||||
}
|
||||
|
||||
TEST(scalevolume, testScaleByZero_doesNothing) {
|
||||
pcm[0][0] = INT16_MIN;
|
||||
pcm[0][1] = INT16_MIN / 2;
|
||||
pcm[0][2] = -2;
|
||||
pcm[0][3] = -1;
|
||||
pcm[0][4] = 0;
|
||||
pcm[0][5] = 1;
|
||||
pcm[0][6] = 2;
|
||||
pcm[0][7] = INT16_MAX / 2;
|
||||
pcm[1][0] = INT16_MAX;
|
||||
scalevolume(ARRAYLEN(pcm), pcm, 0);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][0]);
|
||||
EXPECT_EQ(INT16_MIN / 2, pcm[0][1]);
|
||||
EXPECT_EQ(-2, pcm[0][2]);
|
||||
EXPECT_EQ(-1, pcm[0][3]);
|
||||
EXPECT_EQ(0, pcm[0][4]);
|
||||
EXPECT_EQ(1, pcm[0][5]);
|
||||
EXPECT_EQ(2, pcm[0][6]);
|
||||
EXPECT_EQ(INT16_MAX / 2, pcm[0][7]);
|
||||
EXPECT_EQ(INT16_MAX, pcm[1][0]);
|
||||
}
|
||||
|
||||
TEST(scalevolume, testBiggestScale_justSaturates) {
|
||||
pcm[0][0] = INT16_MIN;
|
||||
pcm[0][1] = INT16_MIN / 2;
|
||||
pcm[0][2] = -2;
|
||||
pcm[0][3] = -1;
|
||||
pcm[0][4] = 0;
|
||||
pcm[0][5] = 1;
|
||||
pcm[0][6] = 2;
|
||||
pcm[0][7] = INT16_MAX / 2;
|
||||
pcm[1][0] = INT16_MAX;
|
||||
scalevolume(ARRAYLEN(pcm), pcm, 123);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][0]);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][1]);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][2]);
|
||||
EXPECT_EQ(INT16_MIN, pcm[0][3]);
|
||||
EXPECT_EQ(0, pcm[0][4]);
|
||||
EXPECT_EQ(INT16_MAX, pcm[0][5]);
|
||||
EXPECT_EQ(INT16_MAX, pcm[0][6]);
|
||||
EXPECT_EQ(INT16_MAX, pcm[0][7]);
|
||||
EXPECT_EQ(INT16_MAX, pcm[1][0]);
|
||||
}
|
||||
|
||||
TEST(scalevolume, testSmallestScale_justSaturates) {
|
||||
pcm[0][0] = INT16_MIN;
|
||||
pcm[0][1] = INT16_MIN / 2;
|
||||
pcm[0][2] = -2;
|
||||
pcm[0][3] = -1;
|
||||
pcm[0][4] = 0;
|
||||
pcm[0][5] = 1;
|
||||
pcm[0][6] = 2;
|
||||
pcm[0][7] = INT16_MAX / 2;
|
||||
pcm[1][0] = INT16_MAX;
|
||||
scalevolume(ARRAYLEN(pcm), pcm, -123);
|
||||
EXPECT_EQ(-1, pcm[0][0]);
|
||||
EXPECT_EQ(-1, pcm[0][1]);
|
||||
EXPECT_EQ(-1, pcm[0][2]);
|
||||
EXPECT_EQ(-1, pcm[0][3]);
|
||||
EXPECT_EQ(0, pcm[0][4]);
|
||||
EXPECT_EQ(0, pcm[0][5]);
|
||||
EXPECT_EQ(0, pcm[0][6]);
|
||||
EXPECT_EQ(0, pcm[0][7]);
|
||||
EXPECT_EQ(0, pcm[1][0]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// audio volume adjustment latency:
|
||||
// - ~1µs w/ -Os
|
||||
// - ~500ns w/ -O3
|
||||
// - ~200ns w/ -O3 -march=skylake MODE=rel
|
||||
|
||||
void randomizeaudio(void) {
|
||||
rngset(pcm, sizeof(pcm), rand64, -1);
|
||||
}
|
||||
|
||||
void scalevolume_pure(int amt) {
|
||||
scalevolume(ARRAYLEN(pcm), pcm, amt);
|
||||
}
|
||||
|
||||
BENCH(scalevolume, audioframe) {
|
||||
EZBENCH(randomizeaudio(), scalevolume_pure(0));
|
||||
EZBENCH(randomizeaudio(), scalevolume_pure(1));
|
||||
EZBENCH(randomizeaudio(), scalevolume_pure(15));
|
||||
}
|
51
test/dsp/core/test.mk
Normal file
51
test/dsp/core/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_DSP_CORE
|
||||
|
||||
TEST_DSP_CORE_SRCS := $(wildcard test/dsp/core/*.c)
|
||||
TEST_DSP_CORE_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_CORE_SRCS))
|
||||
TEST_DSP_CORE_COMS = $(TEST_DSP_CORE_OBJS:%.o=%.com)
|
||||
TEST_DSP_CORE_BINS = $(TEST_DSP_CORE_COMS) $(TEST_DSP_CORE_COMS:%=%.dbg)
|
||||
|
||||
TEST_DSP_CORE_OBJS = \
|
||||
$(TEST_DSP_CORE_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_DSP_CORE_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_DSP_CORE_TESTS = \
|
||||
$(TEST_DSP_CORE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_DSP_CORE_CHECKS = \
|
||||
$(TEST_DSP_CORE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_DSP_CORE_DIRECTDEPS = \
|
||||
DSP_CORE \
|
||||
DSP_MPEG \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_LOG \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_RAND \
|
||||
LIBC_TESTLIB \
|
||||
TOOL_VIZ_LIB \
|
||||
THIRD_PARTY_BLAS \
|
||||
THIRD_PARTY_COMPILER_RT
|
||||
|
||||
TEST_DSP_CORE_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_DSP_CORE_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/test/dsp/core/core.pkg: \
|
||||
$(TEST_DSP_CORE_OBJS) \
|
||||
$(foreach x,$(TEST_DSP_CORE_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/test/dsp/core/%.com.dbg: \
|
||||
$(TEST_DSP_CORE_DEPS) \
|
||||
o/$(MODE)/test/dsp/core/%.o \
|
||||
$(LIBC_TESTMAIN) \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/test/dsp/core
|
||||
o/$(MODE)/test/dsp/core: \
|
||||
$(TEST_DSP_CORE_BINS) \
|
||||
$(TEST_DSP_CORE_CHECKS)
|
155
test/dsp/scale/magikarp_test.c
Normal file
155
test/dsp/scale/magikarp_test.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*-*- 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/scale/scale.h"
|
||||
#include "libc/fmt/bing.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
TEST(magikarp, testConvolve) {
|
||||
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
|
||||
EXPECT_BINEQ(
|
||||
u"λλ λλ λλ λλ "
|
||||
u"λλ λλ λλ λλ "
|
||||
u"λλ λλ λλ λλ ",
|
||||
cDecimate2xUint8x8(32 * 3,
|
||||
tgc(tunbing(u"λλλλ λλλλ λλλλ λλλλ "
|
||||
u"λλλλ λλλλ λλλλ λλλλ "
|
||||
u"λλλλ λλλλ λλλλ λλλλ ")),
|
||||
K));
|
||||
}
|
||||
|
||||
TEST(magikarp, testConvolveMin1) {
|
||||
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
|
||||
EXPECT_BINEQ(
|
||||
u"λλ λλ λλ λλ "
|
||||
u"λλ λλ λλ λλ "
|
||||
u"λλ λλ λλ λλ ",
|
||||
cDecimate2xUint8x8(32 * 3 - 1,
|
||||
tgc(tunbing(u"λλλλ λλλλ λλλλ λλλλ "
|
||||
u"λλλλ λλλλ λλλλ λλλλ "
|
||||
u"λλλλ λλλλ λλλλ λλλλ ")),
|
||||
K));
|
||||
}
|
||||
|
||||
TEST(magikarp, testConvolve2) {
|
||||
signed char K[8] = {-1, -3, 3, 17, 17, 3, -3, -1};
|
||||
EXPECT_BINEQ(
|
||||
u" ☻♣•○♂♪☼◄‼§↨↓←↔▼"
|
||||
u"!#%‘)+-/13579;=⁇"
|
||||
u"ACEGIKMOQSUWY[]_"
|
||||
u"acegikmoqsuwy{}⌂"
|
||||
u"üâàçëïìÅæôòùÖ¢¥ƒ"
|
||||
u"íúѺ⌐½¡»▒│╡╖╣╗╜┐"
|
||||
u"┴├┼╟╔╦═╧╤╙╒╫┘█▌▀"
|
||||
u"ßπστΘδφ∩±≤⌡≈∙√²λ",
|
||||
cDecimate2xUint8x8(256,
|
||||
tgc(tunbing(u" ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼"
|
||||
u" !“#$%&‘()*+,-./0123456789:;<=>⁇"
|
||||
u"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[╲]^_"
|
||||
u"`abcdefghijklmnopqrstuvwxyz{|}~⌂"
|
||||
u"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥€ƒ"
|
||||
u"áíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐"
|
||||
u"└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀"
|
||||
u"αßΓπΣσμτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■λ")),
|
||||
K));
|
||||
}
|
||||
|
||||
const char kDieWelle[] = "\
|
||||
nnooooooppppppppppqqqqqqqqqqqqqqqqqqqqqqqqqppppppppppoooooonn\
|
||||
ooooooppppppppqqqqqqqqqqpppppppppppppqqqqqqqqqqppppppppoooooo\
|
||||
oooopppppppqqqqqqqpppppppppppppppppppppppppqqqqqqqpppppppoooo\
|
||||
oopppppppqqqqqqppppppppppoooooooooooppppppppppqqqqqqpppppppoo\
|
||||
pppppppqqqqqpppppppoooooooonnnnnnnoooooooopppppppqqqqqppppppp\
|
||||
pppppqqqqqppppppooooonnnnnnnmmmmmnnnnnnnoooooppppppqqqqqppppp\
|
||||
ppppqqqqppppppooonnnnnmmmmmmmmmmmmmmmmmnnnnnoooppppppqqqqpppp\
|
||||
ppqqqqqpppppooonnnmmmmmlllllllllllllllmmmmmnnnooopppppqqqqqpp\
|
||||
pqqqqqppppooonnnmmmmlllllllllllllllllllllmmmmnnnoooppppqqqqqp\
|
||||
qqqqpppppooonnmmmlllllllllllllllllllllllllllmmmnnooopppppqqqq\
|
||||
qqqqppppooonnmmmllllllllllllmmmmmllllllllllllmmmnnoooppppqqqq\
|
||||
qqqppppooonnmmmlllllllllmmmnnnnnnnmmmlllllllllmmmnnoooppppqqq\
|
||||
qqpppppoonnmmmllllllllmmnoopqqqqqpoonmmllllllllmmmnnoopppppqq\
|
||||
qqppppooonnmmllllllllmnnpqrsuvvvusrqpnnmllllllllmmnnoooppppqq\
|
||||
qqppppoonnmmmlllllllmmnpqsuxyyyyyxusqpnmmlllllllmmmnnooppppqq\
|
||||
qqppppoonnmmmlllllllmnoprtxyyyyyyyxtrponmlllllllmmmnnooppppqq\
|
||||
qqppppoonnmmmlllllllmnoprtwyyyyyyywtrponmlllllllmmmnnooppppqq\
|
||||
qqppppoonnnmmlllllllmmnoprtvxyyyxvtrponmmlllllllmmnnnooppppqq\
|
||||
qqppppooonnmmllllllllmmnopqrsssssrqponmmllllllllmmnnoooppppqq\
|
||||
qqqppppoonnnmmlllllllllmmnnoopppoonnmmlllllllllmmnnnooppppqqq\
|
||||
qqqpppppoonnmmmllllllllllmmmmmmmmmmmllllllllllmmmnnoopppppqqq\
|
||||
qqqqppppooonnnmmmlllllllllllllllllllllllllllmmmnnnoooppppqqqq\
|
||||
pqqqqpppppoonnnmmmlllllllllllllllllllllllllmmmnnnoopppppqqqqp\
|
||||
ppqqqqpppppooonnnmmmmlllllllllllllllllllmmmmnnnooopppppqqqqpp\
|
||||
pppqqqqppppppooonnnnmmmmmlllllllllllmmmmmnnnnoooppppppqqqqppp\
|
||||
ppppqqqqqppppppoooonnnnnmmmmmmmmmmmmmnnnnnooooppppppqqqqqpppp\
|
||||
ppppppqqqqqpppppppooooonnnnnnnnnnnnnnnooooopppppppqqqqqpppppp\
|
||||
opppppppqqqqqppppppppoooooooooooooooooooppppppppqqqqqpppppppo\
|
||||
ooopppppppqqqqqqpppppppppppppppppppppppppppppqqqqqqpppppppooo\
|
||||
ooooopppppppqqqqqqqqqpppppppppppppppppppqqqqqqqqqpppppppooooo\
|
||||
noooooopppppppppqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpppppppppoooooon\
|
||||
nnnooooooopppppppppppqqqqqqqqqqqqqqqqqqqpppppppppppooooooonnn";
|
||||
|
||||
TEST(magikarp, testHalfYX) {
|
||||
static unsigned char M[32][61];
|
||||
memcpy(M, kDieWelle, sizeof(M));
|
||||
Magikarp2xY(32, 61, M, 32, 61);
|
||||
Magikarp2xX(32, 61, M, 16, 61);
|
||||
EXPECT_STREQ(u"\n\
|
||||
nooppppqqqqqqqqqqqqqqqqqpppooon\n\
|
||||
opppqqqqqppppoppoppppqqqqqppppo\n\
|
||||
ppqqqqpppooooommmoooopppqqqqppp\n\
|
||||
pqqqppponmmllllllllmmmnpppqqqqp\n\
|
||||
qqqppoomllllllllllllllmnoppqqqq\n\
|
||||
qqppoomlllllllmmmllllllmnoppqqq\n\
|
||||
qppponlllllmoqttspnlllllmnoppqq\n\
|
||||
qpponmllllmosyzz{vqnllllmmoppqq\n\
|
||||
qpponmllllmorwzzyupnllllmmoppqq\n\
|
||||
qqpponlllllloprrqomlllllmnoppqq\n\
|
||||
qqpponnmlllllllllllllllmnnppqqq\n\
|
||||
qqqppponmlllllllllllllnooppqqqp\n\
|
||||
pqqqqpppoommmlllllmmmoopppqqqpp\n\
|
||||
pppqqqqpppooooooooooppppqqqqppp\n\
|
||||
oopppqqqqqqpppppppppqqqqqqpppoo\n\
|
||||
noopopppqqqqqqqqqqqqqqqppoooonn",
|
||||
gc(bingblit(32, 61, M, 16, 31)));
|
||||
}
|
||||
|
||||
#define HDX (1920 / 4)
|
||||
#define HDY (1080 / 4)
|
||||
|
||||
BENCH(magikarp, bench) { /* 30ms */
|
||||
unsigned char kMagkern[16] = {4, 12, 12, 4};
|
||||
signed char kMagikarp[16] = {-1, -3, 3, 17, 17, 3, -3, -1};
|
||||
unsigned char(*Me)[HDY][HDX] = tgc(tmalloc((HDX + 1) * (HDY + 1)));
|
||||
unsigned char(*Mo)[HDY][HDX] = tgc(tmalloc((HDX + 1) * (HDY + 1)));
|
||||
if (X86_HAVE(AVX)) {
|
||||
EZBENCH2("Decimate2xUint8x8", donothing,
|
||||
cDecimate2xUint8x8((HDX * HDY - 16 - 8) / 2 / 8 * 8, (void *)Me,
|
||||
kMagikarp));
|
||||
}
|
||||
EZBENCH2("cDecimate2xUint8x8", donothing,
|
||||
cDecimate2xUint8x8((HDX * HDY - 16 - 8) / 2 / 8 * 8, (void *)Me,
|
||||
kMagikarp));
|
||||
EZBENCH2("Magikarp2xY", donothing, Magikarp2xY(HDY, HDX, *Me, HDY, HDX));
|
||||
EZBENCH2("Magikarp2xX", donothing, Magikarp2xX(HDY, HDX, *Mo, HDY, HDX));
|
||||
}
|
423
test/dsp/scale/scale_test.c
Normal file
423
test/dsp/scale/scale_test.c
Normal file
|
@ -0,0 +1,423 @@
|
|||
/*-*- 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/c1331.h"
|
||||
#include "dsp/core/c161.h"
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/core/half.h"
|
||||
#include "dsp/scale/scale.h"
|
||||
#include "libc/fmt/bing.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
|
||||
void *AbsoluteDifference(int yn, int xn, unsigned char C[yn][xn], int ays,
|
||||
int axs, const unsigned char A[ays][axs], int bys,
|
||||
int bxs, const unsigned char B[bys][bxs]) {
|
||||
int y, x;
|
||||
for (y = 0; y < yn; ++y) {
|
||||
for (x = 0; x < xn; ++x) {
|
||||
C[y][x] = ABS(A[y][x] - B[y][x]);
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
const char kDieWelle[] = "\
|
||||
pppppppppppppppppoooooooooooooooooooooooooooppppppppppppppppp\
|
||||
pmpppppppppppooooooonnnnnnnnnnnnnnnnnnnnnooooooopppppppppppsp\
|
||||
ppppppppppoooooonnnnnnnnmmmmmmmmmmmmmnnnnnnnnoooooopppppppppp\
|
||||
ppppppppooooonnnnnnmmmmmmmmmmmmmmmmmmmmmmmnnnnnnooooopppppppp\
|
||||
ppppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooopppppp\
|
||||
ppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooopppp\
|
||||
pppoooonnnnmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmnnnnooooppp\
|
||||
ppooonnnnmmmmmmmmmmmmnnnnnnooooooonnnnnnmmmmmmmmmmmmnnnnooopp\
|
||||
pooonnnnmmmmmmmmmmnnnnoooopppppppppoooonnnnmmmmmmmmmmnnnnooop\
|
||||
ooonnnnmmmmmmmmmnnnooopppqqqqrrrqqqqpppooonnnmmmmmmmmmnnnnooo\
|
||||
oonnnnmmmmmmmmmnnnooppqqrrsssssssssrrqqppoonnnmmmmmmmmmnnnnoo\
|
||||
oonnnmmmmmmmmmnnooppqrrssttuuuuuuuttssrrqppoonnmmmmmmmmmnnnoo\
|
||||
onnnnmmmmmmmmnnoopqqrsstuuvvvvvvvvvuutssrqqpoonnmmmmmmmmnnnno\
|
||||
onnnmmmmmmmmnnnoppqrsttuvvwwwxxxwwwvvuttsrqpponnnmmmmmmmmnnno\
|
||||
onnnmmmmmmmmnnoopqrrstuvvwxxxyyyxxxwvvutsrrqpoonnmmmmmmmmnnno\
|
||||
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\
|
||||
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\
|
||||
onnnmmmmmmmmnnoopqqrstuuvwwxxxxxxxwwvuutsrqqpoonnmmmmmmmmnnno\
|
||||
onnnmmmmmmmmmnnoopqrrstuuvvwwwwwwwvvuutsrrqpoonnmmmmmmmmmnnno\
|
||||
oonnnmmmmmmmmnnnoppqqrssttuuvvvvvuuttssrqqpponnnmmmmmmmmnnnoo\
|
||||
oonnnmmmmmmmmmnnnooppqrrssstttttttsssrrqppoonnnmmmmmmmmmnnnoo\
|
||||
ooonnnmmmmmmmmmmnnoooppqqrrrrrrrrrrrqqppooonnmmmmmmmmmmnnnooo\
|
||||
oooonnnmmmmmmmmmmnnnnoooppppqqqqqppppooonnnnmmmmmmmmmmnnnoooo\
|
||||
poooonnnnmmmmmmmmmmmnnnnooooooooooooonnnnmmmmmmmmmmmnnnnoooop\
|
||||
ppoooonnnnmmmmmmmmmmmmmnnnnnnnnnnnnnnnmmmmmmmmmmmmmnnnnoooopp\
|
||||
ppppoooonnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnoooopppp\
|
||||
pppppoooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnooooppppp\
|
||||
pppppppooooonnnnnmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnnnoooooppppppp\
|
||||
pppppppppooooonnnnnnnmmmmmmmmmmmmmmmmmmmnnnnnnnoooooppppppppp\
|
||||
pppppppppppooooooonnnnnnnnnnnnnnnnnnnnnnnnnoooooooppppppppppp\
|
||||
prpppppppppppppoooooooonnnnnnnnnnnnnnnooooooooppppppppppppptp\
|
||||
pppppppppppppppppppoooooooooooooooooooooooppppppppppppppppppp";
|
||||
|
||||
TEST(gyarados, testIdentityDifference) {
|
||||
unsigned char A[1][32][62];
|
||||
unsigned char B[1][32][62];
|
||||
memcpy(A, kDieWelle, sizeof(A));
|
||||
EzGyarados(1, 32, 61, B, 1, 32, 61, A, 0, 1, 32, 61, 32, 61, 1, 1, 0, 0);
|
||||
AbsoluteDifference(32, 62, B[0], 32, 62, B[0], 32, 62, A[0]);
|
||||
EXPECT_STREQ(u"\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
☺ \n\
|
||||
",
|
||||
gc(bingblit(32, 61, B[0], 32, 61)));
|
||||
}
|
||||
|
||||
TEST(gyarados, testHalfYX) {
|
||||
static unsigned char M[1][32][61];
|
||||
memcpy(M, kDieWelle, sizeof(M));
|
||||
EzGyarados(1, 32, 61, M, 1, 32, 61, M, 0, 1, 16, 31, 32, 61, 2, 2, 0, 0);
|
||||
EXPECT_STREQ(u"\n\
|
||||
ppppppppoooooooooooooopppppppqp\n\
|
||||
pppppoonnnmmmmmmmmmmmnnoooppppp\n\
|
||||
ppponnnmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
poonnmmmmmmmmnnnnnmmmmmmmmnnopp\n\
|
||||
oonnmmmmmnnoppqqppoonnmmmmmnnop\n\
|
||||
onnmmmmnooqrsttttsrqponmmmmmnno\n\
|
||||
onmmmmnopqstvwwwwvutrqonmmmmnno\n\
|
||||
onmmmmnoqrtvwxyyyxwusrpommmmmno\n\
|
||||
onmmmmnoprtvwxyyyxvusqpnmmmmmno\n\
|
||||
onmmmmmnpqrtuvwwvutsrponmmmmnno\n\
|
||||
onnmmmmmnopqrssssrrqoonmmmmmnoo\n\
|
||||
oonnmmmmmmnnoopppponnmmmmmmnoop\n\
|
||||
pponnmmmmmmmmmmmmmmmmmmmmnnoopp\n\
|
||||
pppoonnmmmmmmmmmmmmmmmmnnoopppp\n\
|
||||
pppppooonnnmmmmmmmmnnnooopppppp\n\
|
||||
pppppppppooooooooooooppppppppqp",
|
||||
gc(bingblit(32, 61, M[0], 16, 31)));
|
||||
}
|
||||
|
||||
TEST(gyarados, testHalfY) {
|
||||
static unsigned char M[1][32][61];
|
||||
memcpy(M, kDieWelle, sizeof(M));
|
||||
EzGyarados(1, 32, 61, M, 1, 32, 61, M, 0, 1, 16, 61, 32, 61, 2, 1, 0, 0);
|
||||
EXPECT_STREQ(u"\n\
|
||||
popppppppppppppppooooooooooooooooooooooooooopppppppppppppppqp\n\
|
||||
ppppppppppooononnnnnmmmmmmmmmmmmmmmmmmmmmnnnnnonooopppppppppp\n\
|
||||
ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\
|
||||
pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\
|
||||
poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\
|
||||
oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\
|
||||
onnnnmmmmmmmnnnoppqqsttuvvwwwwwwwwwvvuttsqqpponnnmmmmmmmnnnno\n\
|
||||
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\
|
||||
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\
|
||||
oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\
|
||||
ooonnmmmmmmmmmmmnooooqqqrrrsssssssrrrqqqoooonmmmmmmmmmmmnnooo\n\
|
||||
pooonnnmmmmmmmmmmmmmnnnnopoopppppooponnnnmmmmmmmmmmmmmnnnooop\n\
|
||||
ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\
|
||||
pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\
|
||||
pppppppppppoooooonnnnnnmmmmmmmmmmmmmmmnnnnnnoooooopppppppppqp\n\
|
||||
pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp",
|
||||
gc(bingblit(32, 61, M[0], 16, 61)));
|
||||
}
|
||||
|
||||
TEST(Magikarp2xY, testDecimateY) {
|
||||
static unsigned char M[1][32][61], G[1][16][61], D[1][16][61];
|
||||
memcpy(M, kDieWelle, sizeof(M));
|
||||
EzGyarados(1, 32, 61, G, 1, 32, 61, M, 0, 1, 16, 61, 32, 61, 2, 1, 0, 0);
|
||||
EXPECT_STREQ(u"\n\
|
||||
popppppppppppppppooooooooooooooooooooooooooopppppppppppppppqp\n\
|
||||
ppppppppppooononnnnnmmmmmmmmmmmmmmmmmmmmmnnnnnonooopppppppppp\n\
|
||||
ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\
|
||||
pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\
|
||||
poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\
|
||||
oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\
|
||||
onnnnmmmmmmmnnnoppqqsttuvvwwwwwwwwwvvuttsqqpponnnmmmmmmmnnnno\n\
|
||||
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\
|
||||
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\
|
||||
oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\
|
||||
ooonnmmmmmmmmmmmnooooqqqrrrsssssssrrrqqqoooonmmmmmmmmmmmnnooo\n\
|
||||
pooonnnmmmmmmmmmmmmmnnnnopoopppppooponnnnmmmmmmmmmmmmmnnnooop\n\
|
||||
ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\
|
||||
pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\
|
||||
pppppppppppoooooonnnnnnmmmmmmmmmmmmmmmnnnnnnoooooopppppppppqp\n\
|
||||
pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp",
|
||||
gc(bingblit(16, 61, G[0], 16, 61)));
|
||||
Magikarp2xY(32, 61, M[0], 32, 61);
|
||||
AbsoluteDifference(16, 61, D[0], 16, 61, G[0], 16, 61, M[0]);
|
||||
EXPECT_STREQ(u"\n\
|
||||
pnpppppppppppppppoooooooooooooooooooooooooooppppppppppppppprp\n\
|
||||
ppppppppppooooonnnnmmmmmmmmmmmmmmmmmmmmmmmnnnnooooopppppppppp\n\
|
||||
ppppppoononnnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnnonoopppppp\n\
|
||||
pppoononnmmmmmmmmmmmmmmmmmnnnnnnnnnmmmmmmmmmmmmmmmmmnnonooppp\n\
|
||||
poonnnnmmmmmmmmmmmnnnnoooppppqqqppppooonnnnmmmmmmmmmmmnnnnoop\n\
|
||||
oonnnnmmmmmmmmmnooppqqrrsstttttttttssrrqqppoonmmmmmmmmmnnnnoo\n\
|
||||
onnnnmmmmmmmnnnoppqrsttuvvwwwwwwwwwvvuttsrqpponnnmmmmmmmnnnno\n\
|
||||
onnnmmmmmmmmnnoopqrsttuvwwxxyyyyyxxwwvuttsrqpoonnmmmmmmmmnnno\n\
|
||||
onnnmmmmmmmmnnoopqrsstuvwwxxyyyyyxxwwvutssrqpoonnmmmmmmmmnnno\n\
|
||||
oonnnmmmmmmmmnnoopprrsttuuvvwwwwwvvuuttsrrppoonnmmmmmmmmnnnoo\n\
|
||||
ooonnmmmmmmmmmmmnoopoqqqrrsssssssssrrqqqopoonmmmmmmmmmmmnnooo\n\
|
||||
pooonnnmmmmmmmmmmmmmnnnnoooopppppoooonnnnmmmmmmmmmmmmmnnnooop\n\
|
||||
ppppoononnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnonoopppp\n\
|
||||
pppppppoonoonnmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmnnoonooppppppp\n\
|
||||
pppppppppppoooooonnnnmmmmmmmmmmmmmmmmmmmnnnnooooooppppppppppp\n\
|
||||
pqpppppppppppppppppoooooooooooooooooooooooppppppppppppppppprp",
|
||||
gc(bingblit(16, 61, M[0], 16, 61)));
|
||||
EXPECT_STREQ(u"\n\
|
||||
☺ ☺ \n\
|
||||
☺ ☺ ☺ ☺ \n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
☺ ☺ \n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
☺ ☺ ☺ ☺ \n\
|
||||
☺ ☺ \n\
|
||||
\n\
|
||||
\n\
|
||||
☺☺ ☺☺ ☺ \n\
|
||||
",
|
||||
gc(bingblit(16, 61, D[0], 16, 61)));
|
||||
}
|
||||
|
||||
TEST(Magikarp2xX, testDecimateX) {
|
||||
static unsigned char M[1][32][61], G[1][32][31], D[32][31];
|
||||
memcpy(M, kDieWelle, sizeof(M));
|
||||
EzGyarados(1, 32, 31, G, 1, 32, 61, M, 0, 1, 32, 31, 32, 61, 1, 2, 0, 0);
|
||||
EXPECT_STREQ(u"\n\
|
||||
pppppppppoooooooooooooppppppppp\n\
|
||||
oppppppooonnnnnnnnnnooooppppprp\n\
|
||||
pppppooonnnnmmmmmmmnnnooopppppp\n\
|
||||
ppppooonnmmmmmmmmmmmmnnnooppppp\n\
|
||||
pppoonnmmmmmmmmmmmmmmmmnnnopppp\n\
|
||||
ppoonnmmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
ppoonnmmmmmmmnnnnmmmmmmmmnnoopp\n\
|
||||
ponnnmmmmmmnnnooonnnmmmmmmnnopp\n\
|
||||
ponnmmmmmnnooppppoonnmmmmmnnnop\n\
|
||||
oonnmmmmnoopqqrrqqpoonmmmmmnnoo\n\
|
||||
onnmmmmmnopqrsssssqponnmmmmnnoo\n\
|
||||
onmmmmmnopqstuuuutsrqoommmmmnoo\n\
|
||||
onnmmmmnpqrtuvvvvvtsrponmmmmnno\n\
|
||||
onmmmmnopqtuvwxxwwutsqonmmmmmno\n\
|
||||
onmmmmnoqrsvwxyyxxvusqpnmmmmmno\n\
|
||||
onmmmmnopstvwxyyyxwutronmmmmmno\n\
|
||||
onmmmmnopstvwxyyyxwtsrpnmmmmmno\n\
|
||||
onmmmmnoprtuvxxxxwvurqpnmmmmmno\n\
|
||||
onmmmmmnpqsuvwwwwvutrqonmmmmmno\n\
|
||||
onmmmmmnoqrstuvvvutrqponmmmmnoo\n\
|
||||
onmmmmmnnoqrsttttssqponmmmmmnoo\n\
|
||||
oonmmmmmnooqrrrrrrqpoommmmmmnoo\n\
|
||||
oonmmmmmmnnoppqqppoonnmmmmmnooo\n\
|
||||
poonnmmmmmnnoooooonnmmmmmmnnoop\n\
|
||||
poonnmmmmmmmnnnnnnnmmmmmmnnoopp\n\
|
||||
ppoonnmmmmmmmmmmmmmmmmmmmnooppp\n\
|
||||
pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
ppppoonnmmmmmmmmmmmmmmnnooopppp\n\
|
||||
pppppoonnnmmmmmmmmmmnnnoooppppp\n\
|
||||
ppppppooonnnnnnnnnnnnoooopppppp\n\
|
||||
qpppppppoooonnnnnnnoooopppppprp\n\
|
||||
ppppppppppooooooooooopppppppppp",
|
||||
gc(bingblit(32, 31, G[0], 32, 31)));
|
||||
Magikarp2xX(32, 61, M[0], 32, 61);
|
||||
EXPECT_STREQ(u"\n\
|
||||
pppppppppoooooooooooooppppppppp\n\
|
||||
nppppppooonnnnnnnnnnooooppppprp\n\
|
||||
pppppooonnnnmmmmmmnnnnooopppppp\n\
|
||||
ppppooonnnmmmmmmmmmmmnnnooppppp\n\
|
||||
pppoonnnmmmmmmmmmmmmmmmnnoopppp\n\
|
||||
ppoonnnmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
ppoonnmmmmmmmnnnnnmmmmmmmnnoopp\n\
|
||||
ponnnmmmmmnnnoooonnnmmmmmmnnopp\n\
|
||||
ponnmmmmmnnoopppppoonnmmmmnnnop\n\
|
||||
oonnmmmmnoopqqrrqqpponmmmmmnnoo\n\
|
||||
onnmmmmmnopqrsssssrqpnnmmmmnnoo\n\
|
||||
onmmmmmnopqstuuuutsrqoommmmmnoo\n\
|
||||
onnmmmmnpqrtuvvvvvtsrponmmmmnno\n\
|
||||
onmmmmnnpqtuvwxxwwutsponmmmmmno\n\
|
||||
onmmmmnoqrsvwxyyxxvurronmmmmmno\n\
|
||||
onmmmmnopstvwxyyyxwutronmmmmmno\n\
|
||||
onmmmmnopssvwxyyyxwtsronmmmmmno\n\
|
||||
onmmmmnopqtuvxxxxwvurqpnmmmmmno\n\
|
||||
onmmmmmnorsuvwwwwvutrqonmmmmmno\n\
|
||||
onmmmmmnoqrstuvvvutrqpnnmmmmnoo\n\
|
||||
onmmmmmnnoqrsttttssqponmmmmmnoo\n\
|
||||
oonmmmmmnooqrrrrrrqpoommmmmmnoo\n\
|
||||
oonmmmmmnnnoppqqqpponnmmmmmnooo\n\
|
||||
poonnmmmmmnnooooooonnmmmmmnnoop\n\
|
||||
poonnmmmmmmnnnnnnnnmmmmmmnnoopp\n\
|
||||
ppoonnmmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
pppoonnmmmmmmmmmmmmmmmmnnnooppp\n\
|
||||
ppppoonnnmmmmmmmmmmmmmnnooopppp\n\
|
||||
pppppoonnnnmmmmmmmmmnnnoooppppp\n\
|
||||
ppppppooonnnnnnnnnnnnoooopppppp\n\
|
||||
qpppppppoooonnnnnnnoooopppppprp\n\
|
||||
ppppppppppooooooooooopppppppppp",
|
||||
gc(bingblit(32, 61, M[0], 32, 31)));
|
||||
AbsoluteDifference(32, 31, D, 32, 31, G[0], 32, 61, M[0]);
|
||||
EXPECT_STREQ(u"\n\
|
||||
\n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
☺ ☺ \n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
☺ ☺ \n\
|
||||
☺ ☺ ☺ \n\
|
||||
☺ \n\
|
||||
☺☺☺ \n\
|
||||
\n\
|
||||
\n\
|
||||
☺ ☺ \n\
|
||||
☺☺☺ \n\
|
||||
\n\
|
||||
☺ ☺ \n\
|
||||
☺ \n\
|
||||
☺☺ \n\
|
||||
☺ \n\
|
||||
\n\
|
||||
\n\
|
||||
☺ ☺ ☺ \n\
|
||||
☺ ☺ \n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
☺ \n\
|
||||
\n\
|
||||
\n\
|
||||
",
|
||||
gc(bingblit(32, 31, D, 32, 31)));
|
||||
}
|
||||
|
||||
TEST(magikarp_vs_gyarados, testHalf) {
|
||||
static unsigned char M[1][32][61], G[1][16][31], D[16][31];
|
||||
memcpy(M, kDieWelle, sizeof(M));
|
||||
EzGyarados(1, 16, 31, G, 1, 32, 61, M, 0, 1, 16, 31, 32, 61, 32. / 16.,
|
||||
61. / 31., 0, 0);
|
||||
Magikarp2xY(32, 61, M[0], 32, 61);
|
||||
Magikarp2xX(32, 61, M[0], 16, 61);
|
||||
AbsoluteDifference(16, 31, D, 16, 32, G[0], 32, 61, M[0]);
|
||||
EXPECT_STREQ(u"\n\
|
||||
oppppppppooooooooooooopppppppqp\n\
|
||||
pppppooonnmmmmmmmmmmmnnoopppppp\n\
|
||||
ppponnmmmmmmmmmmmmmmmmmmnnnpppp\n\
|
||||
ppnommmmmmmmmnnnnnmmmmmmmmnoopp\n\
|
||||
pnnnmmmmmnnoppqqpponnnmmmmmnnop\n\
|
||||
onnmmmmmopqrstttttsrqpnmmmmnnoo\n\
|
||||
onnmmmnnpqtuvwwwwwutsponmmmmnno\n\
|
||||
onmmmmnopstvwxyyyxwutronmmmmmno\n\
|
||||
onmmmmnopssvwxyyyxwtsronmmmmmno\n\
|
||||
onmmmmmooqstuvwwwvusrponmmmmnoo\n\
|
||||
oommmmmmnopqrsssssqqpommmmmmnoo\n\
|
||||
ponmmmmmmmnnoopppoonnmmmmmmnoop\n\
|
||||
ppoonmmmmmmmmmmmmmmmmmmmmmonppp\n\
|
||||
ppppnonmmmmmmmmmmmmmmmmmooopppp\n\
|
||||
ppppppooonnmmmmmmmmmnnooopppppp\n\
|
||||
qpppppppppoooooooooooppppppppqp",
|
||||
gc(bingblit(32, 61, M[0], 16, 31)));
|
||||
EXPECT_STREQ(u"\n\
|
||||
ppppppppooooooooooooooopppppppp\n\
|
||||
pppppoonnnmmmmmmmmmmmnnnooppppp\n\
|
||||
pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
poonnmmmmmmmmnnnnnmmmmmmmmnnoop\n\
|
||||
oonnmmmmmnnoppqqqpponnmmmmmnnoo\n\
|
||||
onnmmmmnnoqrstttttsrqonnmmmmnno\n\
|
||||
onmmmmnnpqstuwwwwwutsqpnnmmmmno\n\
|
||||
onmmmmnoprtuwxyzyxwutrponmmmmno\n\
|
||||
onmmmmnoprsuwxyyyxwusrponmmmmno\n\
|
||||
onmmmmmnoqrtuvwwwvutrqonmmmmmno\n\
|
||||
onnmmmmmnopqrsssssrqponmmmmmnno\n\
|
||||
oonnmmmmmmnnoopppoonnmmmmmmnnoo\n\
|
||||
ppoonmmmmmmmmmmmmmmmmmmmmmnoopp\n\
|
||||
pppoonnmmmmmmmmmmmmmmmmmnnooppp\n\
|
||||
pppppooonnnmmmmmmmmmnnnoooppppp\n\
|
||||
pppppppppoooooooooooooppppppppq",
|
||||
gc(bingblit(16, 31, G[0], 16, 31)));
|
||||
EXPECT_STREQ(u"\n\
|
||||
☺ ☺ ☺ ☺ \n\
|
||||
☺ ☺☺ ☺ ☺ \n\
|
||||
☺☺☺ ☺ ☺☺☺☺☻ ☺\n\
|
||||
☻☻☺☻ ☺☺☺ ☺☺☺ ☺☺☻☺☺ ☺☻\n\
|
||||
♥☺☺☺ ☺☺☻♥☻♥☻☺ ☺☻☻☻☻☺☺☺ ☺☺☻☻☺ ☺♥\n\
|
||||
☻☺ ☺☻♦♣♠♣♦♥☻☺☺☻♥♣♠♣♣♦♥☺☺☺☻☻ ☺☻☻\n\
|
||||
☺ ☻♦♠••○•♠♥☻☺♥♦♠•○••♠♥☻ ☻☻☺ ☺☺☻\n\
|
||||
☻♣•◘◙◙◙◙♠♦☺☻♦•○◙◙◙◘•♣☺☺☻☺ ☺☺\n\
|
||||
☺♦♠◘◙♂♂◙○♣♦☺♦♠○◙♂♂◙•♠♦ ☺☺ ☺☺\n\
|
||||
☻♦•◘○◙◙◘•♦☺☻♦•○◙◙○◘♠♦☺ ☺ ☺☻☺\n\
|
||||
☺☻♣♠♠♠♠♠♦☻ ☻♦♠♠♠♠♠♥♥☺ ☻☺☺ ☺☻☻\n\
|
||||
☻ ☺♥♥♥☻☻☺☺☺☺☻☻♥♥☻☺ ☺☻♥☻☻☺ ☺☻☻♥\n\
|
||||
♥♥☻☻☺ ☺☻☻♥♥♥♥♥☻☻☺☺☻☺♥♥♥\n\
|
||||
♥♥♥♥☺☻☺ ☺☺☻☻♥♥♥♥♥♥♥♥☻ ☺☻☻♥♥\n\
|
||||
♥♥♥♥♥♥☺☺☺☺☺☻♥♥♥♥♥♥♥♥☻☻☺☺☺ ☺☺☺☺☺\n\
|
||||
☻☺☺☺☺☺☺ ☺☺☺☺☺☻oooooppppppppqp",
|
||||
gc(bingblit(16, 31, D, 16, 31)));
|
||||
}
|
||||
|
||||
#define HDX (1920 / 4)
|
||||
#define HDY (1080 / 4)
|
||||
|
||||
#if 0
|
||||
BENCH(Magikarp, bench) {
|
||||
unsigned char(*Me)[HDY][HDX] = tgc(tmalloc(HDX * HDY));
|
||||
unsigned char(*Mo)[HDY][HDX] = tgc(tmalloc(HDX * HDY));
|
||||
EZBENCH2("Magikarp2xY [even]", donothing,
|
||||
Magikarp2xY(HDX, HDY, *Me, HDX, HDY));
|
||||
EZBENCH2("Magikarp2xY [odd]", donothing,
|
||||
Magikarp2xY(HDX, HDY, *Mo, HDX, HDY));
|
||||
EZBENCH2("Magikarp2xX [even]", donothing,
|
||||
Magikarp2xX(HDX, HDY, *Me, HDX, HDY));
|
||||
EZBENCH2("Magikarp2xX [odd]", donothing,
|
||||
Magikarp2xX(HDX, HDY, *Mo, HDX, HDY));
|
||||
}
|
||||
#endif
|
57
test/dsp/scale/test.mk
Normal file
57
test/dsp/scale/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_DSP_SCALE
|
||||
|
||||
TEST_DSP_SCALE_SRCS := $(wildcard test/dsp/scale/*.c)
|
||||
TEST_DSP_SCALE_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_SCALE_SRCS))
|
||||
TEST_DSP_SCALE_COMS = $(TEST_DSP_SCALE_OBJS:%.o=%.com)
|
||||
TEST_DSP_SCALE_BINS = $(TEST_DSP_SCALE_COMS) $(TEST_DSP_SCALE_COMS:%=%.dbg)
|
||||
|
||||
TEST_DSP_SCALE_OBJS = \
|
||||
$(TEST_DSP_SCALE_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_DSP_SCALE_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_DSP_SCALE_TESTS = \
|
||||
$(TEST_DSP_SCALE_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_DSP_SCALE_CHECKS = \
|
||||
$(TEST_DSP_SCALE_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_DSP_SCALE_DIRECTDEPS = \
|
||||
DSP_CORE \
|
||||
DSP_SCALE \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_LOG \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_STDIO \
|
||||
LIBC_X \
|
||||
LIBC_RAND \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_STR \
|
||||
TOOL_VIZ_LIB \
|
||||
LIBC_STUBS \
|
||||
LIBC_TESTLIB
|
||||
|
||||
TEST_DSP_SCALE_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_DSP_SCALE_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/test/dsp/scale/scale.pkg: \
|
||||
$(TEST_DSP_SCALE_OBJS) \
|
||||
$(foreach x,$(TEST_DSP_SCALE_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/test/dsp/scale/%.com.dbg: \
|
||||
$(TEST_DSP_SCALE_DEPS) \
|
||||
o/$(MODE)/test/dsp/scale/%.o \
|
||||
o/$(MODE)/test/dsp/scale/scale.pkg \
|
||||
$(LIBC_TESTMAIN) \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/test/dsp/scale
|
||||
o/$(MODE)/test/dsp/scale: \
|
||||
$(TEST_DSP_SCALE_BINS) \
|
||||
$(TEST_DSP_SCALE_CHECKS)
|
7
test/dsp/test.mk
Normal file
7
test/dsp/test.mk
Normal file
|
@ -0,0 +1,7 @@
|
|||
#-*-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───────────────────────┘
|
||||
|
||||
.PHONY: o/$(MODE)/test/dsp
|
||||
o/$(MODE)/test/dsp: o/$(MODE)/test/dsp/core \
|
||||
o/$(MODE)/test/dsp/scale \
|
||||
o/$(MODE)/test/dsp/tty
|
65
test/dsp/tty/rgb2ansi_test.c
Normal file
65
test/dsp/tty/rgb2ansi_test.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- 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/tty/quant.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
struct TtyRgb res;
|
||||
|
||||
TEST(rgb2ansi, testDesaturatedPurple_isQuantizedBetterThanEuclideanDistance) {
|
||||
ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode);
|
||||
|
||||
/*
|
||||
* the challenge to the xterm256 palette is that it was likely
|
||||
* intended for just syntax highlighting, rather than accurately
|
||||
* modeling the natural phenomenon of illumination.
|
||||
*
|
||||
* as a syntax highlighting palette, it focuses mostly on bright
|
||||
* saturated colors, while also providing a really good greyscale for
|
||||
* everything else.
|
||||
*
|
||||
* as such, if one were to project the colors of this palette into a
|
||||
* three-dimensional space, we might see something like an HSV cone,
|
||||
* where all the color samples are projected mostly around the outside
|
||||
* of the cone, and the greyscale dots tracing through the middle.
|
||||
*
|
||||
* if we want to convert an a real color into an xterm color, we can
|
||||
* use euclidean distance functions to pick the closest color, such as
|
||||
* sum of squared distance. however this will only work well if it's
|
||||
* either a pure grey color, or a bright saturated one.
|
||||
*
|
||||
* but euclidean distance doesnt work well for the sorts of colors
|
||||
* that are generally used for things like film, which conservatively
|
||||
* edits for the colors more towards the middle of the space; and as
|
||||
* such, which basically causes the distance function to pick greys
|
||||
* for almost everything.
|
||||
*/
|
||||
|
||||
res = rgb2tty(0x56, 0x38, 0x66);
|
||||
|
||||
/* EXPECT_NE(0x4e, res.r); */
|
||||
/* EXPECT_NE(0x4e, res.g); */
|
||||
/* EXPECT_NE(0x4e, res.b); */
|
||||
/* EXPECT_NE(239, res.xt); */
|
||||
|
||||
/* EXPECT_EQ(0x5f, res.r); */
|
||||
/* EXPECT_EQ(0x00, res.g); */
|
||||
/* EXPECT_EQ(0x5f, res.b); */
|
||||
/* EXPECT_EQ(53, res.xt); */
|
||||
}
|
47
test/dsp/tty/rgb2xterm256_test.c
Normal file
47
test/dsp/tty/rgb2xterm256_test.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- 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/tty/rgb2xterm256.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(rgb2xterm256, test) {
|
||||
EXPECT_EQ(196, rgb2xterm256v2(0xff, 0x00, 0x00)); /* red */
|
||||
EXPECT_EQ(46, rgb2xterm256v2(0x00, 0xff, 0x00)); /* green */
|
||||
EXPECT_EQ(21, rgb2xterm256v2(0x00, 0x00, 0xff)); /* blue */
|
||||
EXPECT_EQ(226, rgb2xterm256v2(0xff, 0xff, 0x00)); /* yellow */
|
||||
EXPECT_EQ(208, rgb2xterm256v2(0xff, 0x80, 0x00)); /* orange */
|
||||
}
|
||||
|
||||
TEST(rgb2xterm256, testRedBlack) {
|
||||
EXPECT_EQ(16, rgb2xterm256v2(0, 0, 0));
|
||||
EXPECT_EQ(16, rgb2xterm256v2(12, 0, 0));
|
||||
EXPECT_EQ(232, rgb2xterm256v2(13, 0, 0));
|
||||
EXPECT_EQ(233, rgb2xterm256v2(39, 0, 0));
|
||||
EXPECT_EQ(233, rgb2xterm256v2(40, 0, 0));
|
||||
EXPECT_EQ(52, rgb2xterm256v2(53, 0, 0));
|
||||
EXPECT_EQ(88, rgb2xterm256v2(115, 0, 0));
|
||||
EXPECT_EQ(88, rgb2xterm256v2(116, 0, 0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BENCH(rgb2xterm256v2, bench) {
|
||||
EZBENCH(donothing, rgb2xterm256v2(0xff, 0x80, 0x00));
|
||||
}
|
51
test/dsp/tty/test.mk
Normal file
51
test/dsp/tty/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_DSP_TTY
|
||||
|
||||
TEST_DSP_TTY_SRCS := $(wildcard test/dsp/tty/*.c)
|
||||
TEST_DSP_TTY_SRCS_TEST = $(filter %_test.c,$(TEST_DSP_TTY_SRCS))
|
||||
TEST_DSP_TTY_COMS = $(TEST_DSP_TTY_OBJS:%.o=%.com)
|
||||
TEST_DSP_TTY_BINS = $(TEST_DSP_TTY_COMS) $(TEST_DSP_TTY_COMS:%=%.dbg)
|
||||
|
||||
TEST_DSP_TTY_OBJS = \
|
||||
$(TEST_DSP_TTY_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_DSP_TTY_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_DSP_TTY_TESTS = \
|
||||
$(TEST_DSP_TTY_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_DSP_TTY_CHECKS = \
|
||||
$(TEST_DSP_TTY_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_DSP_TTY_DIRECTDEPS = \
|
||||
DSP_TTY \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_LOG \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_RAND \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_TESTLIB
|
||||
|
||||
TEST_DSP_TTY_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_DSP_TTY_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/test/dsp/tty/tty.pkg: \
|
||||
$(TEST_DSP_TTY_OBJS) \
|
||||
$(foreach x,$(TEST_DSP_TTY_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/test/dsp/tty/%.com.dbg: \
|
||||
$(TEST_DSP_TTY_DEPS) \
|
||||
o/$(MODE)/test/dsp/tty/%.o \
|
||||
o/$(MODE)/test/dsp/tty/tty.pkg \
|
||||
$(LIBC_TESTMAIN) \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/test/dsp/tty
|
||||
o/$(MODE)/test/dsp/tty: \
|
||||
$(TEST_DSP_TTY_BINS) \
|
||||
$(TEST_DSP_TTY_CHECKS)
|
191
test/dsp/tty/ttymove_test.c
Normal file
191
test/dsp/tty/ttymove_test.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*-*- 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/tty/tty.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
char p[16];
|
||||
struct TtyCursor c;
|
||||
|
||||
void SetUp(void) { rngset(p, sizeof(p), rand64, -1); }
|
||||
|
||||
TEST(ttymove, sameCoord_doesNothing) {
|
||||
c.y = 0;
|
||||
c.x = 0;
|
||||
EXPECT_EQ(0, ttymove(&c, p, 0, 0) - p);
|
||||
EXPECT_STREQ("", p);
|
||||
EXPECT_EQ(0, c.y);
|
||||
EXPECT_EQ(0, c.x);
|
||||
}
|
||||
|
||||
TEST(ttymove, crlf) {
|
||||
c.y = 0;
|
||||
c.x = 10;
|
||||
EXPECT_EQ(2, ttymove(&c, p, 1, 0) - p);
|
||||
EXPECT_STREQ("\r\n", p);
|
||||
EXPECT_EQ(1, c.y);
|
||||
EXPECT_EQ(0, c.x);
|
||||
}
|
||||
|
||||
TEST(ttymove, cr) {
|
||||
c.y = 7;
|
||||
c.x = 10;
|
||||
EXPECT_EQ(1, ttymove(&c, p, 7, 0) - p);
|
||||
EXPECT_STREQ("\r", p);
|
||||
EXPECT_EQ(7, c.y);
|
||||
EXPECT_EQ(0, c.x);
|
||||
}
|
||||
|
||||
TEST(ttymove, forwardOne) {
|
||||
c.y = 0;
|
||||
c.x = 10;
|
||||
EXPECT_EQ(3, ttymove(&c, p, 0, 11) - p);
|
||||
EXPECT_STREQ("\e[C", p);
|
||||
EXPECT_EQ(0, c.y);
|
||||
EXPECT_EQ(11, c.x);
|
||||
}
|
||||
|
||||
TEST(ttymove, forwardTwo) {
|
||||
c.y = 0;
|
||||
c.x = 0;
|
||||
EXPECT_EQ(4, ttymove(&c, p, 0, 2) - p);
|
||||
EXPECT_STREQ("\e[2C", p);
|
||||
EXPECT_EQ(0, c.y);
|
||||
EXPECT_EQ(2, c.x);
|
||||
}
|
||||
|
||||
TEST(ttymove, forwardHuge_moves255increments) {
|
||||
c.y = 0;
|
||||
c.x = 0;
|
||||
EXPECT_EQ(6 + 3, ttymove(&c, p, 0, 256) - p);
|
||||
EXPECT_STREQ("\e[255C\e[C", p);
|
||||
EXPECT_EQ(0, c.y);
|
||||
EXPECT_EQ(256, c.x);
|
||||
}
|
||||
|
||||
TEST(ttymove, topleft) {
|
||||
c.y = 1000;
|
||||
c.x = 888;
|
||||
EXPECT_EQ(3, ttymove(&c, p, 0, 0) - p);
|
||||
EXPECT_STREQ("\e[H", p);
|
||||
EXPECT_EQ(0, c.y);
|
||||
EXPECT_EQ(0, c.x);
|
||||
}
|
||||
|
||||
#define MOVE(WANT, Y, X) \
|
||||
EXPECT_EQ(strlen(WANT), ttymove(&c, p, Y, X) - p); \
|
||||
EXPECT_STREQ(WANT, p); \
|
||||
EXPECT_EQ(Y, c.y); \
|
||||
EXPECT_EQ(X, c.x)
|
||||
|
||||
TEST(ttymove, absoluteYandX_is1indexed) {
|
||||
c.y = 1000;
|
||||
c.x = 888;
|
||||
MOVE("\e[4;3H", 3, 2);
|
||||
}
|
||||
|
||||
TEST(ttymove, absoluteYandX_implicit1y) {
|
||||
c.y = 1000;
|
||||
c.x = 888;
|
||||
MOVE("\e[;3H", 0, 2);
|
||||
}
|
||||
|
||||
TEST(ttymove, absoluteYandX_implicit1x) {
|
||||
c.y = 1000;
|
||||
c.x = 888;
|
||||
MOVE("\e[4H", 3, 0);
|
||||
}
|
||||
|
||||
TEST(ttymove, up) {
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\eM", 69, 70);
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\e[2A", 68, 70);
|
||||
}
|
||||
|
||||
TEST(ttymove, down) {
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\eD", 71, 70);
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\e[2B", 72, 70);
|
||||
}
|
||||
|
||||
TEST(ttymove, right) {
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\e[C", 70, 71);
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\e[2C", 70, 72);
|
||||
c.y = 70, c.x = 0;
|
||||
MOVE("\e[123C", 70, 123);
|
||||
}
|
||||
|
||||
TEST(ttymove, left) {
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\e[D", 70, 69);
|
||||
c.y = 70, c.x = 70;
|
||||
MOVE("\e[2D", 70, 68);
|
||||
}
|
||||
|
||||
/* TEST(ttymove, bench_absmove) { */
|
||||
/* EZBENCH( */
|
||||
/* { */
|
||||
/* c.y = 70; */
|
||||
/* c.x = 30; */
|
||||
/* }, */
|
||||
/* ttymove(&c, p, 7, 9)); */
|
||||
/* ASSERT_STREQ("\e[8;10H", p); */
|
||||
/* } */
|
||||
|
||||
/* TEST(ttymove, bench_crlf) { */
|
||||
/* EZBENCH( */
|
||||
/* { */
|
||||
/* c.y = 0; */
|
||||
/* c.x = 10; */
|
||||
/* }, */
|
||||
/* ttymove(&c, p, 1, 0)); */
|
||||
/* ASSERT_STREQ("\r\n", p); */
|
||||
/* } */
|
||||
|
||||
/* TEST(ttymove, bench_forward1) { */
|
||||
/* EZBENCH( */
|
||||
/* { */
|
||||
/* c.y = 0; */
|
||||
/* c.x = 10; */
|
||||
/* }, */
|
||||
/* ttymove(&c, p, 0, 11)); */
|
||||
/* ASSERT_STREQ("\e[C", p); */
|
||||
/* } */
|
||||
|
||||
/* TEST(ttymove, bench_forward2) { */
|
||||
/* int y2, x2; */
|
||||
/* EZBENCH( */
|
||||
/* { */
|
||||
/* y2 = rand32() & 127; */
|
||||
/* x2 = rand32() & 127; */
|
||||
/* c.y = rand32() & 127; */
|
||||
/* c.x = rand32() & 127; */
|
||||
/* }, */
|
||||
/* ttymove(&c, p, y2, x2)); */
|
||||
/* int z; */
|
||||
/* EZBENCH(z = rand32() & 127, _memcpy(&z, "\e[2C", 4)); */
|
||||
/* } */
|
152
test/dsp/tty/ttyraster_test.c
Normal file
152
test/dsp/tty/ttyraster_test.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*-*- 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/tty/quant.h"
|
||||
#include "libc/bits/progn.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "net/http/csscolor.h"
|
||||
|
||||
/*TODO(jart): Re-enable me
|
||||
|
||||
static const struct TtyRgb kBlack = {0, 0, 0, 16};
|
||||
static const struct TtyRgb kWhite = {255, 255, 255, 231};
|
||||
static const struct TtyRgb kRed = {0xff, 0, 0, 196};
|
||||
|
||||
char vtbuf[128];
|
||||
|
||||
void ttyraster_true_setup(void) {
|
||||
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
|
||||
}
|
||||
|
||||
void ttyraster2x2_true(void) {
|
||||
ttyraster(vtbuf,
|
||||
(const struct TtyRgb *)(unsigned[2][2]){
|
||||
{DARKRED, GRAY1},
|
||||
{DARKRED, DARKRED},
|
||||
},
|
||||
2, 2, kBlack, kBlack);
|
||||
}
|
||||
|
||||
TEST(ttyraster, testCorner) {
|
||||
ttyraster_true_setup();
|
||||
EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝",
|
||||
PROGN(ttyraster2x2_true(), vtbuf));
|
||||
}
|
||||
|
||||
TEST(ttyraster, testFullBlock_favorsSpace) {
|
||||
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
|
||||
ttyraster(vtbuf,
|
||||
(struct TtyRgb *)(unsigned[2][2]){
|
||||
{DARKRED, DARKRED},
|
||||
{DARKRED, DARKRED},
|
||||
},
|
||||
2, 2, kBlack, kBlack);
|
||||
EXPECT_STREQ("\e[48;2;139;0;0m ", vtbuf);
|
||||
}
|
||||
|
||||
TEST(ttyraster, testFullBlock_favorsUnicodeWhenCurrenttFgMatchesButNotBg) {
|
||||
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
|
||||
ttyraster(vtbuf,
|
||||
(struct TtyRgb *)(unsigned[2][4]){
|
||||
{DARKRED, GRAY1, GRAY1, GRAY1},
|
||||
{DARKRED, DARKRED, GRAY1, GRAY1},
|
||||
},
|
||||
2, 4, kBlack, kBlack);
|
||||
EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝█", vtbuf);
|
||||
}
|
||||
|
||||
TEST(ttyraster, testFullBlock_forcesSwitchBackToSpaceForRuns) {
|
||||
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksUnicode);
|
||||
ttyraster(vtbuf,
|
||||
(struct TtyRgb *)(unsigned[2][8]){
|
||||
{DARKRED, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1},
|
||||
{DARKRED, DARKRED, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1, GRAY1},
|
||||
},
|
||||
2, 8, kBlack, kBlack);
|
||||
EXPECT_STREQ("\e[48;2;139;0;0;38;2;3;3;3m▝█\e[48;2;3;3;3m ", vtbuf);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(ttyraster_cp437, testSide) {
|
||||
ttyquantinit(kTtyQuantTrue, kTtyQuantRgb, kTtyBlocksCp437);
|
||||
ttyraster(vtbuf,
|
||||
(const struct TtyRgb *)(unsigned[2][2]){
|
||||
{DARKRED, GRAY1},
|
||||
{DARKRED, GRAY1},
|
||||
},
|
||||
2, 2, kBlack, kBlack);
|
||||
EXPECT_STREQ("\e[48;2;3;3;3;38;2;139;0;0m▌", vtbuf);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ttyraster_xterm256_setup(void) {
|
||||
ttyquantinit(kTtyQuantXterm256, kTtyQuantRgb, kTtyBlocksUnicode);
|
||||
}
|
||||
|
||||
void ttyraster2x2_xterm256(void) {
|
||||
ttyraster(vtbuf,
|
||||
(const struct TtyRgb *)(struct TtyRgb[2][2]){
|
||||
{kBlack, kWhite},
|
||||
{kBlack, kBlack},
|
||||
},
|
||||
2, 2, kRed, kRed);
|
||||
}
|
||||
|
||||
TEST(ttyraster_xterm256, testCorner) {
|
||||
ttyraster_xterm256_setup();
|
||||
ttyraster2x2_xterm256();
|
||||
EXPECT_STREQ("\e[48;5;16;38;5;231m▝", vtbuf);
|
||||
}
|
||||
|
||||
void ttyraster6x2_xterm256(void) {
|
||||
ttyraster(vtbuf,
|
||||
(const struct TtyRgb *)(struct TtyRgb[2][6]){
|
||||
{kBlack, kWhite, kBlack, kWhite, kBlack, kWhite},
|
||||
{kBlack, kBlack, kBlack, kBlack, kBlack, kBlack},
|
||||
},
|
||||
2, 6, kRed, kRed);
|
||||
}
|
||||
|
||||
TEST(ttyraster_xterm256, testCornerRepeat3) {
|
||||
ttyraster_xterm256_setup();
|
||||
ttyraster6x2_xterm256();
|
||||
EXPECT_STREQ("\e[48;5;16;38;5;231m▝▝▝", vtbuf);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BENCH(ttyraster_true, bench) {
|
||||
ttyraster_true_setup();
|
||||
EZBENCH(donothing, ttyraster2x2_true());
|
||||
}
|
||||
|
||||
BENCH(ttyraster_xterm256, bench2) {
|
||||
ttyraster_xterm256_setup();
|
||||
EZBENCH(donothing, ttyraster2x2_xterm256());
|
||||
}
|
||||
|
||||
BENCH(ttyraster_xterm256, bench6) {
|
||||
ttyraster_xterm256_setup();
|
||||
EZBENCH(donothing, ttyraster6x2_xterm256());
|
||||
}
|
||||
|
||||
*/
|
130
test/dsp/tty/windex_test.c
Normal file
130
test/dsp/tty/windex_test.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ 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/tty/windex.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
unsigned windex$k8(short *, size_t) hidden;
|
||||
unsigned windex$avx2(short *, size_t) hidden;
|
||||
unsigned windex$sse4(short *, size_t) hidden;
|
||||
|
||||
const short kW[64] aligned(32) = {
|
||||
8281, 3883, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
|
||||
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
|
||||
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
|
||||
1085, 7806, 3248, 1186, 1357, 6738, 1311, 1092, 6195, 7089, 6631,
|
||||
1261, 1364, 9007, 8289, 1409, 1090, 8358, 1502, 7658, 2668, 3522,
|
||||
1730, 2041, 7707, 5096, 6876, 1324, 1242, 5283, 0x7fff,
|
||||
};
|
||||
|
||||
const short kW2[32] aligned(32) = {
|
||||
8281, 1, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
|
||||
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
|
||||
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915,
|
||||
};
|
||||
|
||||
const short kW3[64] aligned(32) = {
|
||||
8281, 0x7fff, 1365, 1786, 9006, 3681, 5563, 8013, 5787, 9063, 2923,
|
||||
3564, 6122, 32, 1436, 0741, 7957, 9219, 1320, 2083, 1904, 8905,
|
||||
2465, 9122, 9563, 1290, 4474, 3988, 9920, 8325, 1088, 2915, 33,
|
||||
1085, 7806, 3248, 1186, 1357, 6738, 1311, 1092, 6195, 7089, 6631,
|
||||
1261, 1364, 9007, 8289, 1409, 1090, 8358, 1502, 7658, 2668, 3522,
|
||||
1730, 2041, 7707, 5096, 6876, 1324, 1242, 7, 0x7fff,
|
||||
};
|
||||
|
||||
#define TestIt(impl, index, value, n, array) \
|
||||
({ \
|
||||
short *a = memcpy(tgc(tmemalign(32, n * 2)), array, n * 2); \
|
||||
unsigned res = impl(array, n); \
|
||||
ASSERT_EQ(index, res); \
|
||||
ASSERT_EQ(value, a[res]); \
|
||||
})
|
||||
|
||||
TEST(windex, testRealWorldPicks) {
|
||||
const short kPicks[96] aligned(32) = {
|
||||
103, 85, 145, 146, 121, 103, 145, 187, 146, 189,
|
||||
121, 103, 139, 121, 63, 105, 105, 147, 60, 103,
|
||||
103, 146, 121, 103, 139, 121, 139, 121, 157, 139,
|
||||
199, 200, 163, 223, 164, 225, 81, 141, 105, 165,
|
||||
78, 139, 103, 164, 61, 103, 103, 145, 79, 139,
|
||||
103, 163, 21, 63, 21, 81, 63, 45, 105, 106,
|
||||
106, 107, 102, 103, 103, 104, 64, 107, 107, 150,
|
||||
82, 143, 107, 168, 108, 109, 109, 110, 21, 64,
|
||||
21, 82, 105, 106, 64, 46, 106, 107, 0x7fff, 0x7fff,
|
||||
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff,
|
||||
};
|
||||
/* multiple valid answers are fine if it's deterministic */
|
||||
TestIt(windex$k8, 52, 21, ARRAYLEN(kPicks), kPicks);
|
||||
if (X86_HAVE(AVX2)) TestIt(windex$avx2, 78, 21, ARRAYLEN(kPicks), kPicks);
|
||||
if (X86_HAVE(SSE4_2)) TestIt(windex$sse4, 80, 21, ARRAYLEN(kPicks), kPicks);
|
||||
}
|
||||
|
||||
TEST(windex, test) {
|
||||
TestIt(windex, 13, 32, ARRAYLEN(kW), kW);
|
||||
TestIt(windex, 1, 1, ARRAYLEN(kW2), kW2);
|
||||
TestIt(windex, 62, 7, ARRAYLEN(kW3), kW3);
|
||||
}
|
||||
|
||||
TEST(windex$avx2, test) {
|
||||
if (X86_HAVE(AVX2)) {
|
||||
TestIt(windex$avx2, 13, 32, ARRAYLEN(kW), kW);
|
||||
TestIt(windex$avx2, 1, 1, ARRAYLEN(kW2), kW2);
|
||||
TestIt(windex$avx2, 62, 7, ARRAYLEN(kW3), kW3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(windex$sse4, test) {
|
||||
if (X86_HAVE(SSE4_2)) {
|
||||
TestIt(windex$sse4, 13, 32, ARRAYLEN(kW), kW);
|
||||
TestIt(windex$sse4, 1, 1, ARRAYLEN(kW2), kW2);
|
||||
TestIt(windex$sse4, 62, 7, ARRAYLEN(kW3), kW3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(windex$k8, test) {
|
||||
TestIt(windex$k8, 13, 32, ARRAYLEN(kW), kW);
|
||||
TestIt(windex$k8, 1, 1, ARRAYLEN(kW2), kW2);
|
||||
TestIt(windex$k8, 62, 7, ARRAYLEN(kW3), kW3);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BENCH(windex, bench) {
|
||||
EZBENCH(donothing, windex(kW, ARRAYLEN(kW)));
|
||||
}
|
||||
BENCH(windex$k8, bench) {
|
||||
EZBENCH(donothing, windex$k8(kW, ARRAYLEN(kW)));
|
||||
}
|
||||
BENCH(windex$avx2, bench) {
|
||||
if (X86_HAVE(AVX2)) {
|
||||
EZBENCH(donothing, windex$avx2(kW, ARRAYLEN(kW)));
|
||||
}
|
||||
}
|
||||
BENCH(windex$sse4, bench) {
|
||||
if (X86_HAVE(SSE4_2)) {
|
||||
EZBENCH(donothing, windex$sse4(kW, ARRAYLEN(kW)));
|
||||
}
|
||||
}
|
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)
|
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