Initial import

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

View File

@ -0,0 +1,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()); */
}

View File

@ -0,0 +1,66 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "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);
}

View File

@ -0,0 +1,81 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "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
View 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
View 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
View 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)));
}

View 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));
}

View File

@ -0,0 +1,84 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "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());
}

View File

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "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);
}
}

View 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));
}

View 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));
}

View File

@ -0,0 +1,50 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "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
View File

@ -0,0 +1,40 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "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)));
}

View 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);
}

View 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
View File

@ -0,0 +1,51 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_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)

View 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
View 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
View File

@ -0,0 +1,57 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_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
View 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

View 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); */
}

View 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
View File

@ -0,0 +1,51 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += TEST_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
View 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)); */
/* } */

View 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
View 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)));
}
}

View File

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

View File

@ -0,0 +1,58 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/alg/bisectcarleft.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h"
TEST(bisectcarleft, testEmpty) {
const int32_t cells[][2] = {};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123));
}
TEST(bisectcarleft, testOneEntry) {
const int32_t cells[][2] = {{123, 31337}};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 122));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 123));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 124));
}
TEST(bisectcarleft, testNegativity_usesSignedBehavior) {
const int32_t cells[][2] = {{-2, 31337}};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -3));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -2));
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), -1));
}
TEST(bisectcarleft, testMultipleEntries) {
const int32_t cells[][2] = {{00, 0}, {11, 0}, {20, 0}, {33, 0}, {40, 0},
{50, 0}, {60, 0}, {70, 0}, {80, 0}, {90, 0}};
EXPECT_EQ(0, bisectcarleft(cells, ARRAYLEN(cells), 10));
EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 11));
EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 12));
EXPECT_EQ(1, bisectcarleft(cells, ARRAYLEN(cells), 19));
EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 20));
EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 21));
EXPECT_EQ(2, bisectcarleft(cells, ARRAYLEN(cells), 32));
EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 33));
EXPECT_EQ(3, bisectcarleft(cells, ARRAYLEN(cells), 34));
}

View File

@ -0,0 +1,110 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(comparator, testByteCompare) {
char *b1 = tmalloc(1);
char *b2 = tmalloc(1);
/* sign doesn't matter */
EXPECT_EQ(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0);
EXPECT_LT(cmpsb(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0);
EXPECT_GT(cmpsb(memcpy(b1, "z", 1), memcpy(b2, "a", 1)), 0);
EXPECT_EQ(cmpub(memcpy(b1, "a", 1), memcpy(b2, "a", 1)), 0);
EXPECT_LT(cmpub(memcpy(b1, "a", 1), memcpy(b2, "z", 1)), 0);
EXPECT_GT(cmpub(memcpy(b1, "z", 1), memcpy(b2, "a", 1)), 0);
/* sign matters */
EXPECT_EQ(cmpsb(memcpy(b1, "\xf0", 1), memcpy(b2, "\xf0", 1)), 0);
EXPECT_LT(cmpsb(memcpy(b1, "\xf0", 1), memcpy(b2, "\x10", 1)), 0);
EXPECT_GT(cmpsb(memcpy(b1, "\x10", 1), memcpy(b2, "\xf0", 1)), 0);
EXPECT_EQ(cmpub(memcpy(b1, "\xf0", 1), memcpy(b2, "\xf0", 1)), 0);
EXPECT_GT(cmpub(memcpy(b1, "\xf0", 1), memcpy(b2, "\x10", 1)), 0);
EXPECT_LT(cmpub(memcpy(b1, "\x10", 1), memcpy(b2, "\xf0", 1)), 0);
/* two's complement bane */
EXPECT_GT(cmpsb(memcpy(b1, "\x7f", 1), memcpy(b2, "\x80", 1)), 0);
EXPECT_LT(cmpub(memcpy(b1, "\x7f", 1), memcpy(b2, "\x80", 1)), 0);
tfree(b2);
tfree(b1);
}
TEST(comparator, testWordCompare) {
char *b1 = tmalloc(2);
char *b2 = tmalloc(2);
EXPECT_EQ(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_GT(cmpsw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_LT(cmpsw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0);
EXPECT_EQ(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_LT(cmpuw(memcpy(b1, "\x00\x7f", 2), memcpy(b2, "\x00\x80", 2)), 0);
EXPECT_GT(cmpuw(memcpy(b1, "\x00\x80", 2), memcpy(b2, "\x00\x7f", 2)), 0);
tfree(b2);
tfree(b1);
}
TEST(comparator, testDoublewordCompare) {
char *b1 = tmalloc(4);
char *b2 = tmalloc(4);
EXPECT_EQ(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_GT(cmpsl(memcpy(b1, "\x00\x00\x00\x7f", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_LT(cmpsl(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x7f", 4)),
0);
EXPECT_EQ(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_LT(cmpul(memcpy(b1, "\x00\x00\x00\x7f", 4),
memcpy(b2, "\x00\x00\x00\x80", 4)),
0);
EXPECT_GT(cmpul(memcpy(b1, "\x00\x00\x00\x80", 4),
memcpy(b2, "\x00\x00\x00\x7f", 4)),
0);
tfree(b2);
tfree(b1);
}
TEST(comparator, testQuadwordCompare) {
char *b1 = tmalloc(8);
char *b2 = tmalloc(8);
EXPECT_EQ(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
EXPECT_GT(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
EXPECT_LT(cmpsq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8)),
0);
EXPECT_EQ(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
EXPECT_LT(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x80", 8)),
0);
EXPECT_GT(cmpuq(memcpy(b1, "\x00\x00\x00\x00\x00\x00\x00\x80", 8),
memcpy(b2, "\x00\x00\x00\x00\x00\x00\x00\x7f", 8)),
0);
tfree(b2);
tfree(b1);
}

View File

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

View File

@ -0,0 +1,87 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/limits.h"
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/nexgen32e.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/rand/rand.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
void djbsort$avx2(int32_t *, long);
size_t n;
int32_t *a, *b, *c;
TEST(djbsort, test4) {
static const int kA[] = {4, 3, 2, 1};
n = ARRAYLEN(kA);
a = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
b = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
c = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
insertionsort(n, a);
djbsort$avx2(b, n);
djbsort(n, c);
ASSERT_EQ(0, memcmp(a, b, n * 4));
ASSERT_EQ(0, memcmp(a, c, n * 4));
}
TEST(djbsort, test64) {
static const int kA[64] = {
-578159677, -506496753, 627992389, -1352456426, -632122174,
-1439460768, -1910607416, INT_MAX, 828129452, 388318786,
1361377655, 178046, -250539006, -933303681, 553663398,
801377571, 1798551167, 1926219590, 1322300030, 2005832294,
190425814, 1896617905, -549032465, -930529122, 953163359,
-1290004523, 447201234, 1351982281, 458539920, 791518325,
-1086386708, 291355635, INT_MIN, -1891018285, 1780601656,
1324222158, 1182663010, -1223576562, -676035738, 1367175631,
-1016599422, 1619595549, -783089669, -663931695, -1082674213,
1369114774, -1944970907, 196888289, 1400094001, -1170906601,
835635598, 1506409902, -1528765785, 1132926680, -351522751,
-1737707221, -209740191, -1857759507, -353087096, 763588876,
-1323943608, -1219421355, -582289873, 1062699814,
};
n = ARRAYLEN(kA);
a = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
b = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
c = memcpy(tgc(tmalloc(n * 4)), kA, n * 4);
insertionsort(n, a);
djbsort(n, c);
ASSERT_EQ(0, memcmp(a, c, n * 4));
if (X86_HAVE(AVX2)) {
djbsort$avx2(b, n);
ASSERT_EQ(0, memcmp(a, b, n * 4));
}
}
BENCH(djbsort, bench) {
n = 256;
a = gc(memalign(32, n * 4));
EZBENCH2("insertionsort[255]", rngset(a, n * 4, rand64, -1),
insertionsort(n, a));
EZBENCH2("djbsort[255]", rngset(a, n * 4, rand64, -1), djbsort(n, a));
}

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

@ -0,0 +1,116 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/str/internal.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
void *(*memmemi)(const void *, size_t, const void *, size_t) = memmem;
FIXTURE(memmem, tiny) {
memmemi = tinymemmem;
}
#define MakeMemory(SL) memcpy(tmalloc(sizeof(SL) - 1), SL, sizeof(SL) - 1)
TEST(memmem, test) {
char *needle = MakeMemory("abcdefgh");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_BINEQ(u"abcdefghdddddddd", memmemi(haystk, 32, needle, 8));
memcpy(needle, "aaaaaaaa", 8);
memcpy(haystk, "acccccccbbbbbbbbaaaaaaaadddddddd", 32);
EXPECT_BINEQ(u"aaaaaaaadddddddd", memmemi(haystk, 32, needle, 8));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testNoMatch) {
char *needle = MakeMemory("abcdefzh");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_EQ(NULL, memmemi(haystk, 32, needle, 8));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testStartOfMemory) {
char *needle = MakeMemory("acccc");
char *haystk = MakeMemory("acccccccbbbbbbbbabcdefghdddddddd");
EXPECT_EQ(&haystk[0], memmemi(haystk, 32, needle, 5));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testEndOfMemory) {
char *needle = MakeMemory("123");
char *haystk = MakeMemory("abc123");
EXPECT_EQ(&haystk[3], memmemi(haystk, 6, needle, 3));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testCrossesSseRegister) {
char *needle = MakeMemory("eeeeeeeeeeeeefffffffffffff");
char *haystk = MakeMemory("eeeeeeeeeeeeeeeeffffffffffffffffrrrrrrrrrrrrrrrr");
EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testHasNulCharacters) {
char *needle = MakeMemory("eeeeeeeeeeeee\0ffffffffffff");
char *haystk =
MakeMemory("eeeeeeeeeeeeeeee\0fffffffffffffffrrrrrrrrrrrrrrrr");
EXPECT_EQ(&haystk[3], memmemi(haystk, 16 * 3, needle, 26));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testWeird) {
char *needle = MakeMemory("-*-+-+-+-+-+-+-+");
char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+");
EXPECT_EQ(14, (intptr_t)memmemi(haystk, 32, needle, 16) - (intptr_t)haystk);
tfree(haystk);
tfree(needle);
}
TEST(memmem, testEmptyNeedle_matchesStartOfHaystack) {
char *needle = tmalloc(0);
char *haystk = MakeMemory("-+-+-+-+-+-+-+-*-+-+-+-+-+-+-+-+");
EXPECT_EQ(0, (intptr_t)memmemi(haystk, 32, needle, 0) - (intptr_t)haystk);
tfree(haystk);
tfree(needle);
}
TEST(memmem, testEmptyHaystack_alwaysReturnsNull) {
char *needle = MakeMemory("-*-+-+-+-+-+-+-+");
char *haystk = tmalloc(0);
EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 16));
EXPECT_EQ(NULL, memmemi(haystk, 0, needle, 1));
tfree(haystk);
tfree(needle);
}
TEST(memmem, testEmptyHaystackAndNeedle_returnsHaystack) {
char *needle = tmalloc(0);
char *haystk = tmalloc(0);
EXPECT_EQ(haystk, memmemi(haystk, 0, needle, 0));
tfree(haystk);
tfree(needle);
}

View File

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/macros.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(qsort, test) {
const int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'},
{0, 'e'}, {99, 'f'}, {2, 'g'}, {83, 'h'},
{782, 'i'}, {1, 'j'}};
const int32_t B[][2] = {{-31, 'd'}, {0, 'e'}, {1, 'j'}, {2, 'c'},
{2, 'g'}, {4, 'a'}, {65, 'b'}, {83, 'h'},
{99, 'f'}, {782, 'i'}};
int32_t(*M)[2] = tmalloc(sizeof(A));
memcpy(M, B, sizeof(A));
qsort(M, ARRAYLEN(A), sizeof(*M), cmpsl);
EXPECT_EQ(0, memcmp(M, B, sizeof(B)));
tfree(M);
}

View File

@ -0,0 +1,40 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/errno.h"
#include "libc/testlib/testlib.h"
#define S(x) x
#define REPLACESTR replacestr
#include "test/libc/alg/replacestr_test.inc"
#undef REPLACESTR
#undef S
#define S(x) u##x
#define REPLACESTR replacestr16
#include "test/libc/alg/replacestr_test.inc"
#undef REPLACESTR
#undef S
/* #define S(x) L##x */
/* #define REPLACESTR replacewcs */
/* #include "test/libc/alg/replacestr_test.inc" */
/* #undef REPLACESTR */
/* #undef S */

View File

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
TEST(REPLACESTR, demo) {
EXPECT_STREQ(S("hello friends"),
replacestr(S("hello world"), S("world"), S("friends")));
EXPECT_STREQ(S("bbbbbbbb"), replacestr(S("aaaa"), S("a"), S("bb")));
}
TEST(REPLACESTR, emptyString) {
EXPECT_STREQ(S(""), replacestr(S(""), S("x"), S("y")));
}
TEST(REPLACESTR, emptyNeedle) {
EXPECT_EQ(NULL, replacestr(S("a"), S(""), S("a")));
EXPECT_EQ(EINVAL, errno);
}
TEST(REPLACESTR, needleInReplacement_doesntExplode) {
EXPECT_STREQ(S("xxxxxxx"), replacestr(S("x"), S("x"), S("xxxxxxx")));
}

View File

@ -0,0 +1,40 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/reverse.h"
#include "libc/dce.h"
#include "libc/macros.h"
#include "libc/testlib/testlib.h"
TEST(reverse, test) {
/* this test gets DCE'd :) */
int A[3] = {1, 2, 3};
reverse(A, ARRAYLEN(A));
EXPECT_EQ(3, A[0]);
EXPECT_EQ(2, A[1]);
EXPECT_EQ(1, A[2]);
}
TEST(reverse, testEmpty) {
int A[3] = {1, 2, 3};
reverse(A, 0);
EXPECT_EQ(1, A[0]);
EXPECT_EQ(2, A[1]);
EXPECT_EQ(3, A[2]);
}

View File

@ -0,0 +1,84 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/alg/alg.h"
#include "libc/bits/bits.h"
#include "libc/dce.h"
#include "libc/mem/mem.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/runtime/gc.h"
#include "libc/str/internal.h"
#include "libc/testlib/testlib.h"
#define MAKESTRING(NAME, VALUE) \
char *NAME = strcpy(tmalloc(sizeof(VALUE) + 16), VALUE)
char *strstr$kmp(const char *haystak, const char *needle) {
return memmem(haystak, strlen(haystak), needle, strlen(needle));
}
char *(*strstri)(const char *, const char *) = strstr$kmp;
FIXTURE(strstr, sse42) {
if (X86_HAVE(SSE4_2)) {
strstri = strstr$sse42;
}
}
TEST(strstr, test_emptyString_isFoundAtBeginning) {
MAKESTRING(haystack, "abc123def");
ASSERT_STREQ(&haystack[0], strstri(haystack, gc(strdup(""))));
ASSERT_STREQ(&haystack[0], strstr(haystack, gc(strdup(""))));
tfree(haystack);
}
TEST(strstr, test_notFound) {
MAKESTRING(haystack, "abc123def");
ASSERT_EQ(NULL, strstri(haystack, gc(strdup("xyz"))));
ASSERT_EQ(NULL, strstr(haystack, gc(strdup("xyz"))));
tfree(haystack);
}
TEST(strstr, test_middleOfString) {
MAKESTRING(haystack, "abc123def");
ASSERT_STREQ(&haystack[3], strstri(haystack, gc(strdup("123"))));
ASSERT_STREQ(&haystack[3], strstr(haystack, gc(strdup("123"))));
tfree(haystack);
}
TEST(strstr, test_endOfString) {
MAKESTRING(haystack, "abc123def");
ASSERT_STREQ(&haystack[8], strstri(haystack, gc(strdup("f"))));
ASSERT_STREQ(&haystack[8], strstr(haystack, gc(strdup("f"))));
tfree(haystack);
}
TEST(strstr, test_secondXmmWord) {
MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbb123");
ASSERT_STREQ(&haystack[27], strstri(haystack, gc(strdup("123"))));
ASSERT_STREQ(&haystack[27], strstr(haystack, gc(strdup("123"))));
tfree(haystack);
}
TEST(strstr, test_overlapsXmmWords) {
MAKESTRING(haystack, "eeeeeeeeeeeeeeeebbbbbbbbbbbbbbb");
ASSERT_STREQ(&haystack[15], strstri(haystack, gc(strdup("eb"))));
ASSERT_STREQ(&haystack[15], strstr(haystack, gc(strdup("eb"))));
tfree(haystack);
}

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

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

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

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

View File

@ -0,0 +1,46 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(bitreverse, test) {
EXPECT_EQ(0xde, bitreverse8(123));
EXPECT_EQ(0xde, (bitreverse8)(123));
EXPECT_EQ(0xde00, bitreverse16(123));
EXPECT_EQ(0xde00, (bitreverse16)(123));
EXPECT_EQ(0xde000000u, bitreverse32(123));
EXPECT_EQ(0xde000000u, (bitreverse32)(123));
}
BENCH(bitreverse, bench) {
EZBENCH2("bitreverse8 mac", donothing,
EXPROPRIATE(bitreverse8(CONCEAL("r", 123))));
EZBENCH2("bitreverse8 fun", donothing,
EXPROPRIATE((bitreverse8)(CONCEAL("r", 123))));
EZBENCH2("bitreverse16 mac", donothing,
EXPROPRIATE(bitreverse16(CONCEAL("r", 123))));
EZBENCH2("bitreverse16 fun", donothing,
EXPROPRIATE((bitreverse16)(CONCEAL("r", 123))));
EZBENCH2("bitreverse32 mac", donothing,
EXPROPRIATE(bitreverse32(CONCEAL("r", 123))));
EZBENCH2("bitreverse32 fun", donothing,
EXPROPRIATE((bitreverse32)(CONCEAL("r", (123)))));
}

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

@ -0,0 +1,66 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/testlib/testlib.h"
TEST(bt_uint16x4, test) {
uint16_t v[4] = {0};
EXPECT_FALSE(bt(v, 0));
EXPECT_FALSE(bt(v, 63));
EXPECT_FALSE(bts(v, 63));
EXPECT_TRUE(bt(v, 63));
EXPECT_TRUE(bts(v, 63));
}
TEST(bt_uint32x2, test) {
uint32_t v[2] = {0};
EXPECT_FALSE(bt(v, 0));
EXPECT_FALSE(bt(v, 63));
EXPECT_FALSE(bts(v, 63));
EXPECT_TRUE(bt(v, 63));
EXPECT_TRUE(bts(v, 63));
}
TEST(bt_uint64x1, test) {
uint64_t v = 0;
EXPECT_FALSE(bt(&v, 0));
EXPECT_FALSE(bt(&v, 63));
EXPECT_FALSE(bts(&v, 63));
EXPECT_TRUE(bt(&v, 63));
EXPECT_TRUE(bts(&v, 63));
}
TEST(bt_uint64, testPresent) {
uint64_t v = 1;
EXPECT_TRUE(bt(&v, 0));
EXPECT_FALSE(bt(&v, 63));
v = 0x8000000000000001;
EXPECT_TRUE(bt(&v, 0));
EXPECT_TRUE(bt(&v, 63));
}
TEST(bt_uint64, testPresent_avoidingDeadCodeElimination) {
volatile uint64_t v = 1;
EXPECT_TRUE(bt(&v, 0));
EXPECT_FALSE(bt(&v, 63));
v = 0x8000000000000001;
EXPECT_TRUE(bt(&v, 0));
EXPECT_TRUE(bt(&v, 63));
}

View File

@ -0,0 +1,50 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/testlib/testlib.h"
TEST(TwosComplementBane, LiteralsThatAreLiterallyTheSameNumber) {
EXPECT_EQ(4, sizeof(INT_MIN));
EXPECT_EQ(8, sizeof(-2147483648));
EXPECT_TRUE(TYPE_SIGNED(-2147483648));
EXPECT_FALSE(TYPE_SIGNED(0x80000000));
EXPECT_FALSE(TYPE_SIGNED(-0x80000000));
}
TEST(ShiftArithmeticRight, DeclassifiedByGuySteele) {
EXPECT_EQ(-1u, SAR(-2u, 1u));
EXPECT_EQ(-1u, SAR(-1u, 1u));
EXPECT_EQ(0xc0000000u, SAR(0x80000000u, 1u));
}
TEST(RotateRight, Test) {
EXPECT_EQ(0x41122334u, ROR(0x11223344u, 4));
EXPECT_EQ(0x44112233u, ROR(0x11223344u, 8));
EXPECT_EQ(0x34411223u, ROR(0x11223344u, 12));
EXPECT_EQ(0x33441122u, ROR(0x11223344u, 16));
}
TEST(RotateLeft, Test) {
EXPECT_EQ(0x12233441u, ROL(0x11223344u, 4));
EXPECT_EQ(0x22334411u, ROL(0x11223344u, 8));
EXPECT_EQ(0x23344112u, ROL(0x11223344u, 12));
EXPECT_EQ(0x33441122u, ROL(0x11223344u, 16));
}

View File

@ -0,0 +1,60 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/morton.h"
#include "libc/nexgen32e/kcpuids.h"
#include "libc/str/str.h"
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
TEST(morton, test) {
EXPECT_EQ(0, morton(0, 0));
EXPECT_EQ(1, morton(0, 1));
EXPECT_EQ(2, morton(1, 0));
EXPECT_EQ(3, morton(1, 1));
EXPECT_EQ(4, morton(0, 2));
EXPECT_EQ(~0ul, morton(~0ul, ~0ul));
EXPECT_EQ(0x7ffffffffffffffdul, morton(0x7ffffffeul, 0xfffffffful));
EXPECT_EQ(0b1010101000010101010, morton(0b0000001111, 0b1111000000));
}
TEST(unmorton, test) {
EXPECT_EQ(0, unmorton(0).ax);
EXPECT_EQ(0, unmorton(0).dx);
EXPECT_EQ(0, unmorton(1).ax);
EXPECT_EQ(1, unmorton(1).dx);
EXPECT_EQ(1, unmorton(2).ax);
EXPECT_EQ(0, unmorton(2).dx);
EXPECT_EQ(1, unmorton(3).ax);
EXPECT_EQ(1, unmorton(3).dx);
EXPECT_EQ(0, unmorton(4).ax);
EXPECT_EQ(2, unmorton(4).dx);
EXPECT_EQ(0xffffffffu, unmorton(~0ul).ax);
EXPECT_EQ(0xffffffffu, unmorton(~0ul).dx);
EXPECT_EQ(0x7ffffffeul, unmorton(0x7ffffffffffffffdul).ax);
EXPECT_EQ(0xfffffffful, unmorton(0x7ffffffffffffffdul).dx);
EXPECT_EQ(0b0000001111000000, unmorton(0b010101010000001010101).ax);
EXPECT_EQ(0b0000000000001111, unmorton(0b010101010000001010101).dx);
}
BENCH(morton, bench) {
EZBENCH2("morton", donothing,
EXPROPRIATE(morton(CONCEAL("r", 123), CONCEAL("r", 123))));
EZBENCH2("unmorton", donothing, EXPROPRIATE(unmorton(CONCEAL("r", 123))));
}

View File

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/testlib/testlib.h"
TEST(rounddown2pow, test) {
EXPECT_EQ(0, rounddown2pow(0));
EXPECT_EQ(1, rounddown2pow(1));
EXPECT_EQ(2, rounddown2pow(2));
EXPECT_EQ(2, rounddown2pow(3));
EXPECT_EQ(4, rounddown2pow(4));
EXPECT_EQ(PAGESIZE / 2, rounddown2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE + 1));
EXPECT_EQ(PAGESIZE / 2, rounddown2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE, rounddown2pow(PAGESIZE + 1));
}

View File

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/testlib/testlib.h"
TEST(roundup2log, test) {
EXPECT_EQ(0, roundup2log(0));
EXPECT_EQ(1, roundup2log(1));
EXPECT_EQ(1, roundup2log(2));
EXPECT_EQ(2, roundup2log(3));
EXPECT_EQ(2, roundup2log(4));
EXPECT_EQ(12, roundup2log(PAGESIZE - 1));
EXPECT_EQ(12, roundup2log(PAGESIZE));
EXPECT_EQ(13, roundup2log(PAGESIZE + 1));
EXPECT_EQ(12, roundup2log(PAGESIZE - 1));
EXPECT_EQ(12, roundup2log(PAGESIZE));
EXPECT_EQ(13, roundup2log(PAGESIZE + 1));
}

View File

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/log/check.h"
#include "libc/macros.h"
#include "libc/math.h"
#include "libc/nexgen32e/bsr.h"
#include "libc/testlib/testlib.h"
TEST(roundup2pow, test) {
EXPECT_EQ(0, roundup2pow(0));
EXPECT_EQ(1, roundup2pow(1));
EXPECT_EQ(2, roundup2pow(2));
EXPECT_EQ(4, roundup2pow(3));
EXPECT_EQ(4, roundup2pow(4));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE * 2, roundup2pow(PAGESIZE + 1));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE - 1));
EXPECT_EQ(PAGESIZE, roundup2pow(PAGESIZE));
EXPECT_EQ(PAGESIZE * 2, roundup2pow(PAGESIZE + 1));
}

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

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

View File

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/safemacros.h"
#include "libc/testlib/testlib.h"
TEST(unsignedsubtract, testMacro) {
EXPECT_EQ(5ul, unsignedsubtract(7ul, 2ul));
EXPECT_EQ(18ul, unsignedsubtract(2ul, 0xfffffffffffffff0ul));
}
TEST(unsignedsubtract, testLinked) {
EXPECT_EQ(5ul, (unsignedsubtract)(7ul, 2ul));
EXPECT_EQ(18ul, (unsignedsubtract)(2ul, 0xfffffffffffffff0ul));
}

View File

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

View File

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

View File

@ -0,0 +1,49 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/stdio.h"
#include "libc/calls/struct/stat.h"
#include "libc/calls/calls.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
int64_t fd;
struct stat st;
const char *path;
TEST(ftruncate, test) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);
path = gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid()));
ASSERT_NE(-1, (fd = creat(path, 0755)));
ASSERT_EQ(5, write(fd, "hello", 5));
errno = 31337;
ASSERT_NE(-1, ftruncate(fd, 31337));
EXPECT_EQ(31337, errno);
ASSERT_EQ(5, write(fd, "world", 5));
ASSERT_NE(-1, close(fd));
ASSERT_NE(-1, stat(path, &st));
ASSERT_EQ(31337, st.st_size);
ASSERT_BINEQ(u"helloworld", gc(slurp(path, NULL)));
unlink(path);
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/gc.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/testlib/testlib.h"
TEST(mkntenvblock, emptyList_onlyOutputsDoubleNulStringTerminator) {
char *envp[] = {NULL};
ASSERT_BINEQ(u"  ", gc(mkntenvblock(envp)));
}
TEST(mkntenvblock, envp_becomesSortedDoubleNulTerminatedUtf16String) {
char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL};
ASSERT_BINEQ(
u"c = d   "
u"h d u c = d   "
u"u = b   "
u"u h = d   "
u"Θù= ^ù  "
u"  ",
gc(mkntenvblock(envp)));
}

View File

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/runtime/gc.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/testlib/testlib.h"
TEST(sortenvp, test) {
char *envp[] = {"u=b", "c=d", "韩=非", "uh=d", "hduc=d", NULL};
char **sortedenvp = gc(sortenvp(envp));
EXPECT_STREQ("c=d", sortedenvp[0]);
EXPECT_STREQ("hduc=d", sortedenvp[1]);
EXPECT_STREQ("u=b", sortedenvp[2]);
EXPECT_STREQ("uh=d", sortedenvp[3]);
EXPECT_STREQ("韩=非", sortedenvp[4]);
EXPECT_EQ(NULL, sortedenvp[5]);
}

View File

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

View File

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

View File

@ -0,0 +1,34 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/log/check.h"
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
testonly void OnCtrlC(int sig) { _exit(0); }
TEST(signal, test) {
if (IsWindows()) return; /* omg */
ASSERT_NE(SIG_ERR, signal(SIGINT, OnCtrlC));
ASSERT_NE(-1, raise(SIGINT));
die();
}

View File

@ -0,0 +1,43 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/stat.h"
#include "libc/nt/files.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/runtime.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
char *pathname;
struct stat st;
TEST(stat_000, setupFiles) {
mkdir("o", 0755);
mkdir("o/tmp", 0755);
}
TEST(stat_010, testEmptyFile_sizeIsZero) {
pathname = defer(
unlink,
gc(xasprintf("o/tmp/%s.%d", program_invocation_short_name, getpid())));
ASSERT_NE(-1, touch(pathname, 0755));
EXPECT_NE(-1, stat(pathname, &st));
EXPECT_EQ(0, st.st_size);
}

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

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

View File

@ -0,0 +1,44 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/testlib/testlib.h"
TEST(basename, test) {
EXPECT_STREQ("", basename(""));
EXPECT_STREQ("hello", basename("hello"));
EXPECT_STREQ("there", basename("hello/there"));
EXPECT_STREQ("yo", basename("hello/there/yo"));
}
TEST(basename, testTrailingSlash_isIgnored) {
/* should be "foo" but basename() doesn't allocate memory */
EXPECT_STREQ("foo/", basename("foo/"));
EXPECT_STREQ("foo//", basename("foo//"));
}
TEST(basename, testOnlySlashes_oneSlashOnlyVasily) {
EXPECT_STREQ("/", basename("///"));
}
TEST(basename, testWindows_isGrantedRespect) {
EXPECT_STREQ("there", basename("hello\\there"));
EXPECT_STREQ("yo", basename("hello\\there\\yo"));
}

View File

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(llog10, test) {
EXPECT_EQ(0, llog10(1));
EXPECT_EQ(0, llog10(2));
EXPECT_EQ(0, llog10(9));
EXPECT_EQ(1, llog10(10));
EXPECT_EQ(1, llog10(11));
EXPECT_EQ(1, llog10(99));
EXPECT_EQ(2, llog10(100));
EXPECT_EQ(2, llog10(101));
EXPECT_EQ(9, llog10(INT_MAX));
EXPECT_EQ(12, llog10(1000000000000));
}

View File

@ -0,0 +1,50 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/conv/conv.h"
#include "libc/conv/sizemultiply.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
size_t out;
TEST(sizemultiply, testMultiplication) {
EXPECT_TRUE(sizemultiply(&out, 7, 11));
EXPECT_EQ(7 * 11, out);
EXPECT_TRUE(sizemultiply(&out, 11, 7));
EXPECT_EQ(7 * 11, out);
EXPECT_TRUE(sizemultiply(&out, 0, 11));
EXPECT_EQ(0 * 11, out);
EXPECT_TRUE(sizemultiply(&out, 11, 0));
EXPECT_EQ(0 * 11, out);
}
TEST(sizemultiply, testOverflow_alwaysReturnsSizeMax) {
EXPECT_FALSE(sizemultiply(&out, 7, SIZE_MAX));
EXPECT_EQ(SIZE_MAX, out);
EXPECT_FALSE(sizemultiply(&out, SIZE_MAX, 7));
EXPECT_EQ(SIZE_MAX, out);
}
TEST(sizemultiply, testOverflow_closeButNoCigar) {
EXPECT_TRUE(sizemultiply(&out, SIZE_MAX, 1));
EXPECT_EQ(SIZE_MAX, out);
EXPECT_TRUE(sizemultiply(&out, 1, SIZE_MAX));
EXPECT_EQ(SIZE_MAX, out);
}

View File

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/testlib/testlib.h"
/* todo(jart): work on this more */
TEST(strtoimax, testZero) { EXPECT_EQ(0, strtoimax("0", NULL, 0)); }
TEST(strtoimax, testDecimal) { EXPECT_EQ(-123, strtoimax("-123", NULL, 0)); }
TEST(strtoimax, testHex) { EXPECT_EQ(-255, strtoimax("-0xff", NULL, 0)); }
TEST(strtoimax, testOctal) { EXPECT_EQ(-123, strtoimax("-0173", NULL, 0)); }
TEST(strtoimax, testLimits) {
EXPECT_EQ(
((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("-1", NULL, 0));
EXPECT_EQ(
((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("0x7fffffffffffffffffffffffffffffff", NULL, 0));
}

View File

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/conv/conv.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(strtoumax, testZero) { EXPECT_EQ(UINTMAX_MIN, strtoumax("0", NULL, 0)); }
TEST(strtoumax, testDecimal) { EXPECT_EQ(123, strtoumax("123", NULL, 0)); }
TEST(strtoumax, testHex) { EXPECT_EQ(255, strtoumax("0xff", NULL, 0)); }
TEST(strtoumax, testOctal) { EXPECT_EQ(123, strtoumax("0173", NULL, 0)); }
TEST(strtoumax, testMaximum) {
EXPECT_EQ(UINTMAX_MAX,
strtoumax("340282366920938463463374607431768211455", NULL, 0));
EXPECT_EQ(UINTMAX_MAX,
strtoumax("0xffffffffffffffffffffffffffffffff", NULL, 0));
}

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

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

View File

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/calls/struct/timeval.h"
#include "libc/conv/conv.h"
#include "libc/nt/struct/filetime.h"
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
TEST(timevaltofiletime, roundTrip) {
struct timeval tv1, tv2;
tv1.tv_sec = 31337;
tv1.tv_usec = 1337;
filetimetotimeval(&tv2, timevaltofiletime(&tv1));
EXPECT_EQ(31337, tv2.tv_sec);
EXPECT_EQ(1337, tv2.tv_usec);
}

View File

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

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

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

View File

@ -0,0 +1,48 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/dns/dnsheader.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(serializednsheader, test) {
struct DnsHeader header;
memset(&header, 0, sizeof(header));
header.id = 255;
header.bf1 = true;
header.qdcount = 1;
uint8_t *buf = tmalloc(12);
ASSERT_EQ(12, serializednsheader(buf, 12, header));
EXPECT_BINEQ(u" λ☺  ☺      ", buf);
tfree(buf);
}
TEST(serializednsheader, fuzzSymmetry) {
uint8_t *buf = tmalloc(12);
struct DnsHeader *in = tmalloc(sizeof(struct DnsHeader));
struct DnsHeader *out = tmalloc(sizeof(struct DnsHeader));
ASSERT_EQ(12, serializednsheader(buf, 12, *in));
ASSERT_EQ(12, deserializednsheader(out, buf, 12));
ASSERT_EQ(0, memcmp(in, out, 12));
tfree(out);
tfree(in);
tfree(buf);
}

View File

@ -0,0 +1,101 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(dnsnamecmp, testEmpty) {
char *A = strcpy(tmalloc(1), "");
char *B = strcpy(tmalloc(1), "");
EXPECT_EQ(dnsnamecmp(A, B), 0);
EXPECT_EQ(dnsnamecmp(A, A), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testDotless_caseInsensitiveBehavior) {
char *A = tmalloc(2);
char *B = tmalloc(2);
EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "a")), 0);
EXPECT_EQ(dnsnamecmp(A, A), 0);
EXPECT_EQ(dnsnamecmp(strcpy(A, "a"), strcpy(B, "A")), 0);
EXPECT_EQ(dnsnamecmp(strcpy(A, "A"), strcpy(B, "a")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "b")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "a"), strcpy(B, "B")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "d"), strcpy(B, "a")), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testMultiLabel_lexiReverse) {
char *A = tmalloc(16);
char *B = tmalloc(16);
EXPECT_EQ(dnsnamecmp(strcpy(A, "a.example"), strcpy(B, "a.example")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.example")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "b.example"), strcpy(B, "a.examplz")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "a.zxample"), strcpy(B, "a.examplz")), 0);
EXPECT_EQ(dnsnamecmp(strcpy(A, "c.a.example"), strcpy(B, "c.a.example")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "d.a.example"), strcpy(B, "c.a.example")), 0);
EXPECT_LT(dnsnamecmp(strcpy(A, "cat.example"), strcpy(B, "lol.example")), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testTldDotQualifier_canBeEqualToDottedNames) {
char *A = tmalloc(16);
char *B = tmalloc(16);
EXPECT_EQ(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "aaa.example")), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testFullyQualified_alwaysComesFirst) {
char *A = tmalloc(16);
char *B = tmalloc(16);
EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example."), strcpy(A, "zzz")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example."), strcpy(A, "aaa")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example.")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example.")), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testLikelySld_alwaysComesBeforeLocalName) {
char *A = tmalloc(16);
char *B = tmalloc(16);
EXPECT_LT(dnsnamecmp(strcpy(B, "z.e"), strcpy(A, "a")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "aaa.example"), strcpy(A, "zzz")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "zzz.example"), strcpy(A, "aaa")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "zzz"), strcpy(B, "aaa.example")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "aaa"), strcpy(B, "zzz.example")), 0);
tfree(B);
tfree(A);
}
TEST(dnsnamecmp, testLikelySubdomain_alwaysComesAfterSld) {
char *A = tmalloc(16);
char *B = tmalloc(16);
EXPECT_LT(dnsnamecmp(strcpy(B, "a.e"), strcpy(A, "z.a.e")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "z.a.e"), strcpy(B, "a.e")), 0);
EXPECT_LT(dnsnamecmp(strcpy(B, "b.e"), strcpy(A, "a.b.e")), 0);
EXPECT_GT(dnsnamecmp(strcpy(A, "a.b.e"), strcpy(B, "b.e")), 0);
tfree(B);
tfree(A);
}

View File

@ -0,0 +1,50 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/dns/dnsquestion.h"
#include "libc/errno.h"
#include "libc/testlib/testlib.h"
TEST(serializednsquestion, test) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 4);
char *name = tstrdup("foo.bar");
struct DnsQuestion dq;
dq.qname = name;
dq.qtype = 0x0201;
dq.qclass = 0x0102;
EXPECT_EQ(1 + 3 + 1 + 3 + 1 + 4,
serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 4, dq));
EXPECT_BINEQ(u"♥foo♥bar ☻☺☺☻", buf);
tfree(name);
tfree(buf);
}
TEST(serializednsquestion, testNoSpace) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1 + 3);
char *name = tstrdup("foo.bar");
struct DnsQuestion dq;
dq.qname = name;
dq.qtype = 0x0201;
dq.qclass = 0x0102;
EXPECT_EQ(-1, serializednsquestion(buf, 1 + 3 + 1 + 3 + 1 + 3, dq));
EXPECT_EQ(ENOSPC, errno);
tfree(name);
tfree(buf);
}

View File

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

View File

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

View File

@ -0,0 +1,79 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/dns/dns.h"
#include "libc/errno.h"
#include "libc/str/str.h"
#include "libc/testlib/testlib.h"
TEST(pascalifydnsname, testEmpty) {
uint8_t *buf = tmalloc(1);
char *name = tstrdup("");
EXPECT_EQ(0, pascalifydnsname(buf, 1, name));
EXPECT_BINEQ(u" ", buf);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testOneLabel) {
uint8_t *buf = tmalloc(1 + 3 + 1);
char *name = tstrdup("foo");
EXPECT_EQ(1 + 3, pascalifydnsname(buf, 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo ", buf);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testTwoLabels) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
char *name = tstrdup("foo.bar");
EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo♥bar ", buf);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testFqdnDot_isntIncluded) {
uint8_t *buf = tmalloc(1 + 3 + 1 + 3 + 1);
char *name = tstrdup("foo.bar.");
EXPECT_EQ(1 + 3 + 1 + 3, pascalifydnsname(buf, 1 + 3 + 1 + 3 + 1, name));
EXPECT_BINEQ(u"♥foo♥bar ", buf);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testTooLong) {
uint8_t *buf = tmalloc(1);
char *name = tmalloc(1000);
memset(name, '.', 999);
name[999] = '\0';
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
EXPECT_EQ(ENAMETOOLONG, errno);
tfree(name);
tfree(buf);
}
TEST(pascalifydnsname, testNoSpace) {
uint8_t *buf = tmalloc(1);
char *name = tstrdup("foo");
EXPECT_EQ(-1, pascalifydnsname(buf, 1, name));
EXPECT_EQ(ENOSPC, errno);
tfree(name);
tfree(buf);
}

View File

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

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

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

View File

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

View File

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

View File

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

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

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

View File

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

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

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

View File

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

View File

@ -0,0 +1,55 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/paddsw.h"
#include "libc/intrin/paddw.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(paddw, test) {
short A[8] = {7};
short B[8] = {11};
short C[8];
paddw(C, A, B);
EXPECT_EQ(18, C[0]);
}
TEST(paddsw, test) {
short A[8] = {7};
short B[8] = {11};
short C[8];
paddsw(C, A, B);
EXPECT_EQ(18, C[0]);
}
TEST(paddw, testOverflow_wrapsAround) {
short A[8] = {SHRT_MAX, SHRT_MIN};
short B[8] = {1, -1};
paddw(A, A, B);
EXPECT_EQ(SHRT_MIN, A[0]);
EXPECT_EQ(SHRT_MAX, A[1]);
}
TEST(paddsw, testOverflow_saturates) {
short A[8] = {SHRT_MAX, SHRT_MIN};
short B[8] = {1, -1};
paddsw(A, A, B);
EXPECT_EQ(SHRT_MAX, A[0]);
EXPECT_EQ(SHRT_MIN, A[1]);
}

View File

@ -0,0 +1,87 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/palignr.h"
#include "libc/testlib/testlib.h"
const int A[4] = {1, 2, 3, 4};
const int B[4] = {5, 6, 7, 8};
TEST(palignr, testLeftpad) {
int C[4] = {0};
palignr(C, B, A, 12);
EXPECT_EQ(4, C[0]);
EXPECT_EQ(5, C[1]);
EXPECT_EQ(6, C[2]);
EXPECT_EQ(7, C[3]);
}
TEST(palignr, test0) {
int C[4];
palignr(C, B, A, 0);
EXPECT_EQ(1, C[0]);
EXPECT_EQ(2, C[1]);
EXPECT_EQ(3, C[2]);
EXPECT_EQ(4, C[3]);
}
TEST(palignr, test4) {
int C[4];
palignr(C, B, A, 4);
EXPECT_EQ(2, C[0]);
EXPECT_EQ(3, C[1]);
EXPECT_EQ(4, C[2]);
EXPECT_EQ(5, C[3]);
}
TEST(palignr, test12) {
int C[4];
palignr(C, B, A, 12);
EXPECT_EQ(4, C[0]);
EXPECT_EQ(5, C[1]);
EXPECT_EQ(6, C[2]);
EXPECT_EQ(7, C[3]);
}
TEST(palignr, test16) {
int C[4];
palignr(C, B, A, 16);
EXPECT_EQ(5, C[0]);
EXPECT_EQ(6, C[1]);
EXPECT_EQ(7, C[2]);
EXPECT_EQ(8, C[3]);
}
TEST(palignr, test20) {
int C[4] = {-1, -1, -1, -1};
palignr(C, B, A, 20);
EXPECT_EQ(6, C[0]);
EXPECT_EQ(7, C[1]);
EXPECT_EQ(8, C[2]);
EXPECT_EQ(0, C[3]);
}
TEST(palignr, test32) {
int C[4] = {-1, -1, -1, -1};
palignr(C, B, A, 32);
EXPECT_EQ(0, C[0]);
EXPECT_EQ(0, C[1]);
EXPECT_EQ(0, C[2]);
EXPECT_EQ(0, C[3]);
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/intrin/psraw.h"
#include "libc/limits.h"
#include "libc/testlib/testlib.h"
TEST(psraw, testPositive) {
short A[8] = {1, 2, SHRT_MAX};
psraw(A, A, 1);
EXPECT_EQ(0, A[0]);
EXPECT_EQ(1, A[1]);
EXPECT_EQ(SHRT_MAX / 2, A[2]);
}
TEST(psraw, testNegative) {
short A[8] = {-1, -2, SHRT_MIN};
psraw(A, A, 1);
EXPECT_EQ(-1, A[0]);
EXPECT_EQ(-1, A[1]);
EXPECT_EQ(SHRT_MIN / 2, A[2]);
}

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

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

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

@ -0,0 +1,30 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/runtime/gc.h"
#include "libc/stdio/stdio.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(exp, test) {
ASSERT_STREQ("7.389056", gc(xasprintf("%f", exp(2.0))));
ASSERT_STREQ("6.389056", gc(xasprintf("%f", expm1(2.0))));
ASSERT_STREQ("6.389056", gc(xasprintf("%f", exp(2.0) - 1.0)));
}

View File

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/testlib/testlib.h"
TEST(pow10, testLdbl) {
EXPECT_LDBL_EQ(1, pow10l(0));
EXPECT_LDBL_EQ(10, pow10l(1));
EXPECT_LDBL_EQ(100, pow10l(2));
}
TEST(pow10, testDouble) {
EXPECT_DOUBLE_EQ(1, pow10(0));
EXPECT_DOUBLE_EQ(10, pow10(1));
EXPECT_DOUBLE_EQ(100, pow10(2));
}
TEST(pow10, testFloat) {
EXPECT_FLOAT_EQ(1, pow10f(0));
EXPECT_FLOAT_EQ(10, pow10f(1));
EXPECT_FLOAT_EQ(100, pow10f(2));
}

View File

@ -0,0 +1,52 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/testlib/testlib.h"
long double x, y, z;
COMBO(x, pos1) { x = +1.3L; }
COMBO(x, pos2) { x = +2.3L; }
COMBO(y, pos1) { y = +1.3L; }
COMBO(y, pos2) { y = +2.3L; }
COMBO(z, pi) { z = M_PI; }
COMBO(z, e) { z = M_E; }
TEST(powl, lolgebra) {
/* EXPECT_LDBL_EQ(1, powl(x, 0)); */
/* EXPECT_LDBL_EQ(x, powl(x, 1)); */
/* EXPECT_LDBL_EQ(powl(x, -1), 1.0L / x); */
/* EXPECT_LDBL_EQ(powl(x, 0.5), sqrtl(x)); */
/* EXPECT_LDBL_EQ(powl(x, y) * powl(x, z), powl(x, y + z)); */
/* EXPECT_LDBL_EQ(powl(x, y) * powl(z, y), powl(x * z, y)); */
/* EXPECT_LDBL_EQ(powl(x, y) / x, powl(x, y - 1)); */
/* EXPECT_LDBL_EQ(x / powl(y, z), x * powl(y, -z)); */
/* EXPECT_LDBL_EQ(powi(x, 0), 1); */
/* EXPECT_LDBL_EQ(powi(x, 1), x); */
/* EXPECT_LDBL_EQ(powi(x, -1), 1 / x); */
/* EXPECT_LDBL_EQ(powi(1, x), 1); */
/* EXPECT_LDBL_EQ(powi(x, y) * powi(z, y), powi(x * z, y)); */
}
TEST(powl, testConstants) {
EXPECT_LDBL_EQ(16, powl(2, 4));
/* TODO(jart): We need a better AlmostEqual() */
/* EXPECT_LDBL_EQ(3.347061799072891e+62, powl(1337.31337, 20)); */
}

View File

@ -0,0 +1,77 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/math.h"
#include "libc/runtime/gc.h"
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
TEST(round, test) {
EXPECT_STREQ("-3", gc(xdtoa(round(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(round(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(round(-.5))));
EXPECT_STREQ("1", gc(xdtoa(round(.5))));
EXPECT_STREQ("2", gc(xdtoa(round(1.5))));
EXPECT_STREQ("3", gc(xdtoa(round(2.5))));
}
TEST(round, testCornerCases) {
EXPECT_STREQ("-0", gc(xdtoa(round(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(round(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(round(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(round(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(round(-INFINITY))));
}
TEST(lround, test) {
EXPECT_EQ(-3, lround(-2.5));
EXPECT_EQ(-2, lround(-1.5));
EXPECT_EQ(-1, lround(-.5));
EXPECT_EQ(0, lround(-.0));
EXPECT_EQ(1, lround(.5));
EXPECT_EQ(2, lround(1.5));
EXPECT_EQ(3, lround(2.5));
}
TEST(roundf, test) {
EXPECT_STREQ("-3", gc(xdtoa(roundf(-2.5))));
EXPECT_STREQ("-2", gc(xdtoa(roundf(-1.5))));
EXPECT_STREQ("-1", gc(xdtoa(roundf(-.5))));
EXPECT_STREQ("1", gc(xdtoa(roundf(.5))));
EXPECT_STREQ("2", gc(xdtoa(roundf(1.5))));
EXPECT_STREQ("3", gc(xdtoa(roundf(2.5))));
}
TEST(roundf, testCornerCases) {
EXPECT_STREQ("-0", gc(xdtoa(roundf(-0.0))));
EXPECT_STREQ("NAN", gc(xdtoa(roundf(NAN))));
EXPECT_STREQ("-NAN", gc(xdtoa(roundf(-NAN))));
EXPECT_STREQ("INFINITY", gc(xdtoa(roundf(INFINITY))));
EXPECT_STREQ("-INFINITY", gc(xdtoa(roundf(-INFINITY))));
}
TEST(lroundf, test) {
EXPECT_EQ(-3, lroundf(-2.5));
EXPECT_EQ(-2, lroundf(-1.5));
EXPECT_EQ(-1, lroundf(-.5));
EXPECT_EQ(0, lroundf(-.0));
EXPECT_EQ(1, lroundf(.5));
EXPECT_EQ(2, lroundf(1.5));
EXPECT_EQ(3, lroundf(2.5));
}

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

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

View File

@ -0,0 +1,24 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/testlib/testlib.h"
TEST(malloc, test) { free(malloc(123)); }

View File

@ -0,0 +1,41 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney │
│ │
│ This program is free software; you can redistribute it and/or modify │
│ it under the terms of the GNU General Public License as published by │
│ the Free Software Foundation; version 2 of the License. │
│ │
│ This program is distributed in the hope that it will be useful, but │
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
│ General Public License for more details. │
│ │
│ You should have received a copy of the GNU General Public License │
│ along with this program; if not, write to the Free Software │
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
│ 02110-1301 USA │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/testlib/testlib.h"
char *s2;
TEST(strdup, test) {
EXPECT_STREQ("hello", (s2 = strdup("hello")));
EXPECT_NE((intptr_t) "hello", (intptr_t)s2);
free(s2);
}
TEST(strndup, test) {
EXPECT_STREQ("hello", (s2 = strndup("hello", 8)));
EXPECT_NE((intptr_t) "hello", (intptr_t)s2);
free(s2);
}
TEST(strndup, tooLong_truncatesWithNul) {
EXPECT_STREQ("hell", (s2 = strndup("hello", 4)));
free(s2);
}

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

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

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