361 lines
7.6 KiB
Go
361 lines
7.6 KiB
Go
// Copyright 2020 The Libc Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build !(linux && (amd64 || arm64 || loong64 || ppc64le || s390x || riscv64 || 386 || arm))
|
|
|
|
package libc // import "modernc.org/libc"
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
"time"
|
|
"unsafe"
|
|
|
|
_ "modernc.org/cc/v4"
|
|
_ "modernc.org/ccgo/v4/lib"
|
|
_ "modernc.org/fileutil/ccgo"
|
|
ctime "modernc.org/libc/time"
|
|
)
|
|
|
|
func TestXfmod(t *testing.T) {
|
|
x := 1.3518643030646695
|
|
y := 6.283185307179586
|
|
if g, e := Xfmod(nil, x, y), 1.3518643030646695; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
}
|
|
|
|
func TestSwap(t *testing.T) {
|
|
if g, e := X__builtin_bswap16(nil, 0x1234), uint16(0x3412); g != e {
|
|
t.Errorf("%#04x %#04x", g, e)
|
|
}
|
|
if g, e := X__builtin_bswap32(nil, 0x12345678), uint32(0x78563412); g != e {
|
|
t.Errorf("%#04x %#04x", g, e)
|
|
}
|
|
if g, e := X__builtin_bswap64(nil, 0x123456789abcdef0), uint64(0xf0debc9a78563412); g != e {
|
|
t.Errorf("%#04x %#04x", g, e)
|
|
}
|
|
}
|
|
|
|
var (
|
|
valist [256]byte
|
|
formatString [256]byte
|
|
srcString [256]byte
|
|
testPrintfS1 = [...]byte{'X', 'Y', 0}
|
|
)
|
|
|
|
func TestPrintf(t *testing.T) {
|
|
isWindows = true
|
|
i := uint64(0x123456789abcdef)
|
|
j := uint64(0xf123456789abcde)
|
|
k := uint64(0x23456789abcdef1)
|
|
l := uint64(0xef123456789abcd)
|
|
for itest, test := range []struct {
|
|
fmt string
|
|
args []interface{}
|
|
result string
|
|
}{
|
|
{
|
|
"%I64x %I32x %I64x %I32x",
|
|
[]interface{}{int64(i), int32(j), int64(k), int32(l)},
|
|
"123456789abcdef 789abcde 23456789abcdef1 6789abcd",
|
|
},
|
|
{
|
|
"%llx %x %llx %x",
|
|
[]interface{}{int64(i), int32(j), int64(k), int32(l)},
|
|
"123456789abcdef 789abcde 23456789abcdef1 6789abcd",
|
|
},
|
|
{
|
|
"%.1s\n",
|
|
[]interface{}{uintptr(unsafe.Pointer(&testPrintfS1[0]))},
|
|
"X\n",
|
|
},
|
|
{
|
|
"%.2s\n",
|
|
[]interface{}{uintptr(unsafe.Pointer(&testPrintfS1[0]))},
|
|
"XY\n",
|
|
},
|
|
} {
|
|
copy(formatString[:], test.fmt+"\x00")
|
|
b := printf(uintptr(unsafe.Pointer(&formatString[0])), VaList(uintptr(unsafe.Pointer(&valist[0])), test.args...))
|
|
if g, e := string(b), test.result; g != e {
|
|
t.Errorf("%v: %q %q", itest, g, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStrtod(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("TODO")
|
|
}
|
|
|
|
tls := NewTLS()
|
|
defer tls.Close()
|
|
|
|
for itest, test := range []struct {
|
|
s string
|
|
result float64
|
|
}{
|
|
{"+0", 0},
|
|
{"+1", 1},
|
|
{"+2", 2},
|
|
{"-0", 0},
|
|
{"-1", -1},
|
|
{"-2", -2},
|
|
{".5", .5},
|
|
{"0", 0},
|
|
{"1", 1},
|
|
{"1.", 1},
|
|
{"1.024e3", 1024},
|
|
{"16", 16},
|
|
{"2", 2},
|
|
{"32", 32},
|
|
} {
|
|
copy(srcString[:], test.s+"\x00")
|
|
if g, e := Xstrtod(tls, uintptr(unsafe.Pointer(&srcString[0])), 0), test.result; g != e {
|
|
t.Errorf("%v: %q: %v %v", itest, test.s, g, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseZone(t *testing.T) {
|
|
for itest, test := range []struct {
|
|
in, out string
|
|
off int
|
|
}{
|
|
{"America/Los_Angeles", "America/Los_Angeles", 0},
|
|
{"America/Los_Angeles+12", "America/Los_Angeles", 43200},
|
|
{"America/Los_Angeles-12", "America/Los_Angeles", -43200},
|
|
{"UTC", "UTC", 0},
|
|
{"UTC+1", "UTC", 3600},
|
|
{"UTC+10", "UTC", 36000},
|
|
{"UTC-1", "UTC", -3600},
|
|
{"UTC-10", "UTC", -36000},
|
|
} {
|
|
out, off := parseZone(test.in)
|
|
if g, e := out, test.out; g != e {
|
|
t.Errorf("%d: %+v %v %v", itest, test, g, e)
|
|
}
|
|
if g, e := off, test.off; g != e {
|
|
t.Errorf("%d: %+v %v %v", itest, test, g, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRint(t *testing.T) {
|
|
tls := NewTLS()
|
|
for itest, test := range []struct {
|
|
x, y float64
|
|
}{
|
|
{-1.1, -1.0},
|
|
{-1.0, -1.0},
|
|
{-0.9, -1.0},
|
|
{-0.51, -1.0},
|
|
{-0.49, 0},
|
|
{-0.1, 0},
|
|
{-0, 0},
|
|
{0.1, 0},
|
|
{0.49, 0},
|
|
{0.51, 1},
|
|
{0.9, 1},
|
|
{1, 1},
|
|
{1.1, 1},
|
|
} {
|
|
if g, e := Xrint(tls, test.x), test.y; g != e {
|
|
t.Errorf("#%d: x %v, got %v, expected %v", itest, test.x, g, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
var testMemsetBuf [67]byte
|
|
|
|
func TestMemset(t *testing.T) {
|
|
v := 0
|
|
for start := 0; start < len(testMemsetBuf); start++ {
|
|
for n := 0; n < len(testMemsetBuf)-start; n++ {
|
|
for x := range testMemsetBuf {
|
|
testMemsetBuf[x] = byte(v)
|
|
v++
|
|
}
|
|
for x := start; x < start+n; x++ {
|
|
testMemsetBuf[x] = byte(v)
|
|
}
|
|
e := testMemsetBuf
|
|
Xmemset(nil, uintptr(unsafe.Pointer(&testMemsetBuf[start])), int32(v), size_t(n))
|
|
if testMemsetBuf != e {
|
|
t.Fatalf("start %v, v %#x n %v, exp\n%s\ngot\n%s", start, byte(v), n, hex.Dump(e[:]), hex.Dump(testMemsetBuf[:]))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const testGetentropySize = 100
|
|
|
|
var testGetentropyBuf [testGetentropySize]byte
|
|
|
|
func TestGetentropy(t *testing.T) {
|
|
Xgetentropy(NewTLS(), uintptr(unsafe.Pointer(&testGetentropyBuf[0])), testGetentropySize)
|
|
t.Logf("\n%s", hex.Dump(testGetentropyBuf[:]))
|
|
}
|
|
|
|
func TestReallocArray(t *testing.T) {
|
|
const size = 16
|
|
tls := NewTLS()
|
|
p := Xmalloc(tls, size)
|
|
if p == 0 {
|
|
t.Fatal()
|
|
}
|
|
|
|
for i := 0; i < size; i++ {
|
|
(*RawMem)(unsafe.Pointer(p))[i] = byte(i ^ 0x55)
|
|
}
|
|
|
|
q := Xreallocarray(tls, p, 2, size)
|
|
if q == 0 {
|
|
t.Fatal()
|
|
}
|
|
|
|
for i := 0; i < size; i++ {
|
|
if g, e := (*RawMem)(unsafe.Pointer(q))[i], byte(i^0x55); g != e {
|
|
t.Fatal(i, g, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
func mustCString(s string) uintptr {
|
|
r, err := CString(s)
|
|
if err != nil {
|
|
panic("CString failed")
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
var testSnprintfBuf [3]byte
|
|
|
|
func TestSnprintf(t *testing.T) {
|
|
testSnprintfBuf = [3]byte{0xff, 0xff, 0xff}
|
|
p := uintptr(unsafe.Pointer(&testSnprintfBuf[0]))
|
|
if g, e := Xsnprintf(nil, p, 0, 0, 0), int32(0); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := testSnprintfBuf, [3]byte{0xff, 0xff, 0xff}; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := Xsnprintf(nil, p, 0, mustCString(""), 0), int32(0); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := testSnprintfBuf, [3]byte{0xff, 0xff, 0xff}; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
s := mustCString("12")
|
|
if g, e := Xsnprintf(nil, p, 0, s, 0), int32(2); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := testSnprintfBuf, [3]byte{0xff, 0xff, 0xff}; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := Xsnprintf(nil, p, 1, s, 0), int32(2); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := testSnprintfBuf, [3]byte{0x00, 0xff, 0xff}; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
testSnprintfBuf = [3]byte{0xff, 0xff, 0xff}
|
|
if g, e := Xsnprintf(nil, p, 2, s, 0), int32(2); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := testSnprintfBuf, [3]byte{'1', 0x00, 0xff}; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
testSnprintfBuf = [3]byte{0xff, 0xff, 0xff}
|
|
if g, e := Xsnprintf(nil, p, 3, s, 0), int32(2); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := testSnprintfBuf, [3]byte{'1', '2', 0x00}; g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
}
|
|
|
|
var testFdopenBuf [100]byte
|
|
|
|
func TestFdopen(t *testing.T) {
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("not implemented on Windows")
|
|
}
|
|
|
|
const s = "foobarbaz\n"
|
|
tempdir := t.TempDir()
|
|
f, err := os.Create(filepath.Join(tempdir, "test_fdopen"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := f.Write([]byte(s)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := f.Seek(0, os.SEEK_SET); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
tls := NewTLS()
|
|
|
|
defer tls.Close()
|
|
|
|
p := Xfdopen(tls, int32(f.Fd()), mustCString("r"))
|
|
|
|
bp := uintptr(unsafe.Pointer(&testFdopenBuf))
|
|
if g, e := Xfread(tls, bp, 1, size_t(len(testFdopenBuf)), p), size_t(len(s)); g != e {
|
|
t.Fatal(g, e)
|
|
}
|
|
|
|
if g, e := string(GoBytes(bp, len(s))), s; g != e {
|
|
t.Fatalf("%q %q", g, e)
|
|
}
|
|
}
|
|
|
|
func TestSync(t *testing.T) {
|
|
tls := NewTLS()
|
|
X__sync_synchronize(tls)
|
|
tls.Close()
|
|
}
|
|
|
|
func TestProbes(t *testing.T) {
|
|
p := NewPerfCounter([]string{"a", "b", "c"})
|
|
p.Inc(1)
|
|
t.Logf("====\n%s\n----", p)
|
|
c := NewStackCapture(100)
|
|
for i := 0; i < 20; i++ {
|
|
c.Record()
|
|
if i%3 == 0 {
|
|
c.Record()
|
|
}
|
|
}
|
|
t.Logf("====\n%s\n----", c)
|
|
}
|
|
|
|
var _time ctime.Time_t
|
|
|
|
func TestGmtime(t *testing.T) {
|
|
tls := NewTLS()
|
|
_time = ctime.Time_t(time.Now().Unix())
|
|
p := Xgmtime(tls, uintptr(unsafe.Pointer(&_time)))
|
|
t.Logf("%v %+v", _time, (*ctime.Tm)(unsafe.Pointer(p)))
|
|
tls.Close()
|
|
}
|