libgo: Update to weekly.2011-12-14.

From-SVN: r183118
This commit is contained in:
Ian Lance Taylor 2012-01-12 01:31:45 +00:00
parent c6135f0633
commit 9a0e3259f4
167 changed files with 3547 additions and 1686 deletions

View file

@ -9943,7 +9943,11 @@ Call_expression::do_get_tree(Translate_context* context)
fn = build_fold_addr_expr_loc(location.gcc_location(),
excess_fndecl);
for (int i = 0; i < nargs; ++i)
args[i] = ::convert(excess_type, args[i]);
{
if (SCALAR_FLOAT_TYPE_P(TREE_TYPE(args[i]))
|| COMPLEX_FLOAT_TYPE_P(TREE_TYPE(args[i])))
args[i] = ::convert(excess_type, args[i]);
}
}
}
}

View file

@ -125,17 +125,108 @@ Gogo::define_builtin_function_trees()
NULL_TREE),
false);
// We provide sqrt for the math library.
define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
// We provide some functions for the math library.
tree math_function_type = build_function_type_list(double_type_node,
double_type_node,
NULL_TREE);
tree math_function_type_long =
build_function_type_list(long_double_type_node, long_double_type_node,
long_double_type_node, NULL_TREE);
tree math_function_type_two = build_function_type_list(double_type_node,
double_type_node,
double_type_node,
NULL_TREE);
tree math_function_type_long_two =
build_function_type_list(long_double_type_node, long_double_type_node,
long_double_type_node, NULL_TREE);
define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos",
math_function_type, true);
define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl",
math_function_type_long, true);
define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin",
math_function_type, true);
define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl",
math_function_type_long, true);
define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan",
math_function_type, true);
define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl",
math_function_type_long, true);
define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2",
math_function_type_two, true);
define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l",
math_function_type_long_two, true);
define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil",
math_function_type, true);
define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill",
math_function_type_long, true);
define_builtin(BUILT_IN_COS, "__builtin_cos", "cos",
math_function_type, true);
define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl",
math_function_type_long, true);
define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp",
math_function_type, true);
define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl",
math_function_type_long, true);
define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1",
math_function_type, true);
define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l",
math_function_type_long, true);
define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs",
math_function_type, true);
define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl",
math_function_type_long, true);
define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor",
math_function_type, true);
define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl",
math_function_type_long, true);
define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod",
math_function_type_two, true);
define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl",
math_function_type_long_two, true);
define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp",
build_function_type_list(double_type_node,
double_type_node,
integer_type_node,
NULL_TREE),
true);
define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl",
build_function_type_list(long_double_type_node,
long_double_type_node,
integer_type_node,
NULL_TREE),
true);
define_builtin(BUILT_IN_LOG, "__builtin_log", "log",
math_function_type, true);
define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl",
math_function_type_long, true);
define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p",
math_function_type, true);
define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl",
math_function_type_long, true);
define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10",
math_function_type, true);
define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l",
math_function_type_long, true);
define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2",
math_function_type, true);
define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l",
math_function_type_long, true);
define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin",
math_function_type, true);
define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl",
math_function_type_long, true);
define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt",
math_function_type, true);
define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl",
math_function_type_long, true);
define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan",
math_function_type, true);
define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl",
math_function_type_long, true);
define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc",
math_function_type, true);
define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl",
math_function_type_long, true);
// We use __builtin_return_address in the thunk we build for
// functions which call recover.

View file

@ -1,4 +1,4 @@
0c39eee85b0d
82fdc445f2ff
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.

View file

@ -576,6 +576,7 @@ go_html_files = \
go/html/doctype.go \
go/html/entity.go \
go/html/escape.go \
go/html/foreign.go \
go/html/node.go \
go/html/parse.go \
go/html/render.go \
@ -610,14 +611,11 @@ go_math_files = \
go/math/dim.go \
go/math/erf.go \
go/math/exp.go \
go/math/exp_port.go \
go/math/exp2.go \
go/math/expm1.go \
go/math/floor.go \
go/math/frexp.go \
go/math/gamma.go \
go/math/hypot.go \
go/math/hypot_port.go \
go/math/j0.go \
go/math/j1.go \
go/math/jn.go \
@ -638,7 +636,6 @@ go_math_files = \
go/math/sincos.go \
go/math/sinh.go \
go/math/sqrt.go \
go/math/sqrt_port.go \
go/math/tan.go \
go/math/tanh.go \
go/math/unsafe.go
@ -888,7 +885,6 @@ go_testing_files = \
go_time_files = \
go/time/format.go \
go/time/sleep.go \
go/time/sys.go \
go/time/sys_unix.go \
go/time/tick.go \
go/time/time.go \

View file

@ -962,6 +962,7 @@ go_html_files = \
go/html/doctype.go \
go/html/entity.go \
go/html/escape.go \
go/html/foreign.go \
go/html/node.go \
go/html/parse.go \
go/html/render.go \
@ -996,14 +997,11 @@ go_math_files = \
go/math/dim.go \
go/math/erf.go \
go/math/exp.go \
go/math/exp_port.go \
go/math/exp2.go \
go/math/expm1.go \
go/math/floor.go \
go/math/frexp.go \
go/math/gamma.go \
go/math/hypot.go \
go/math/hypot_port.go \
go/math/j0.go \
go/math/j1.go \
go/math/jn.go \
@ -1024,7 +1022,6 @@ go_math_files = \
go/math/sincos.go \
go/math/sinh.go \
go/math/sqrt.go \
go/math/sqrt_port.go \
go/math/tan.go \
go/math/tanh.go \
go/math/unsafe.go
@ -1202,7 +1199,6 @@ go_testing_files = \
go_time_files = \
go/time/format.go \
go/time/sleep.go \
go/time/sys.go \
go/time/sys_unix.go \
go/time/tick.go \
go/time/time.go \

View file

@ -10,7 +10,6 @@ import (
"fmt"
"io"
"os"
"reflect"
"testing"
"time"
)
@ -127,7 +126,7 @@ testLoop:
f.Close()
continue testLoop
}
if !reflect.DeepEqual(hdr, header) {
if *hdr != *header {
t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v",
i, j, *hdr, *header)
}
@ -201,7 +200,7 @@ func TestIncrementalRead(t *testing.T) {
}
// check the header
if !reflect.DeepEqual(hdr, headers[nread]) {
if *hdr != *headers[nread] {
t.Errorf("Incorrect header:\nhave %+v\nwant %+v",
*hdr, headers[nread])
}

View file

@ -9,6 +9,7 @@ import (
"encoding/binary"
"io"
"io/ioutil"
"os"
"testing"
"time"
)
@ -25,7 +26,7 @@ type ZipTestFile struct {
Content []byte // if blank, will attempt to compare against File
File string // name of file to compare to (relative to testdata/)
Mtime string // modified time in format "mm-dd-yy hh:mm:ss"
Mode uint32
Mode os.FileMode
}
// Caution: The Mtime values found for the test files should correspond to
@ -47,13 +48,13 @@ var tests = []ZipTest{
Name: "test.txt",
Content: []byte("This is a test text file.\n"),
Mtime: "09-05-10 12:12:02",
Mode: 0x81a4,
Mode: 0644,
},
{
Name: "gophercolor16x16.png",
File: "gophercolor16x16.png",
Mtime: "09-05-10 15:52:58",
Mode: 0x81a4,
Mode: 0644,
},
},
},
@ -64,6 +65,7 @@ var tests = []ZipTest{
Name: "r/r.zip",
File: "r.zip",
Mtime: "03-04-10 00:24:16",
Mode: 0666,
},
},
},
@ -76,9 +78,43 @@ var tests = []ZipTest{
Name: "filename",
Content: []byte("This is a test textfile.\n"),
Mtime: "02-02-11 13:06:20",
Mode: 0666,
},
},
},
{
// created in windows XP file manager.
Name: "winxp.zip",
File: crossPlatform,
},
{
// created by Zip 3.0 under Linux
Name: "unix.zip",
File: crossPlatform,
},
}
var crossPlatform = []ZipTestFile{
{
Name: "hello",
Content: []byte("world \r\n"),
Mode: 0666,
},
{
Name: "dir/bar",
Content: []byte("foo \r\n"),
Mode: 0666,
},
{
Name: "dir/empty/",
Content: []byte{},
Mode: os.ModeDir | 0777,
},
{
Name: "readonly",
Content: []byte("important \r\n"),
Mode: 0444,
},
}
func TestReader(t *testing.T) {
@ -159,13 +195,15 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
t.Errorf("name=%q, want %q", f.Name, ft.Name)
}
mtime, err := time.Parse("01-02-06 15:04:05", ft.Mtime)
if err != nil {
t.Error(err)
return
}
if ft := f.ModTime(); !ft.Equal(mtime) {
t.Errorf("%s: mtime=%s, want %s", f.Name, ft, mtime)
if ft.Mtime != "" {
mtime, err := time.Parse("01-02-06 15:04:05", ft.Mtime)
if err != nil {
t.Error(err)
return
}
if ft := f.ModTime(); !ft.Equal(mtime) {
t.Errorf("%s: mtime=%s, want %s", f.Name, ft, mtime)
}
}
testFileMode(t, f, ft.Mode)
@ -191,7 +229,7 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
r.Close()
var c []byte
if len(ft.Content) != 0 {
if ft.Content != nil {
c = ft.Content
} else if c, err = ioutil.ReadFile("testdata/" + ft.File); err != nil {
t.Error(err)
@ -211,7 +249,7 @@ func readTestFile(t *testing.T, ft ZipTestFile, f *File) {
}
}
func testFileMode(t *testing.T, f *File, want uint32) {
func testFileMode(t *testing.T, f *File, want os.FileMode) {
mode, err := f.Mode()
if want == 0 {
if err == nil {
@ -220,7 +258,7 @@ func testFileMode(t *testing.T, f *File, want uint32) {
} else if err != nil {
t.Errorf("%s mode: %s", f.Name, err)
} else if mode != want {
t.Errorf("%s mode: want 0x%x, got 0x%x", f.Name, want, mode)
t.Errorf("%s mode: want %v, got %v", f.Name, want, mode)
}
}

View file

@ -12,7 +12,7 @@ This package does not support ZIP64 or disk spanning.
package zip
import (
"errors"
"os"
"time"
)
@ -32,7 +32,11 @@ const (
dataDescriptorLen = 12
// Constants for the first byte in CreatorVersion
creatorUnix = 3
creatorFAT = 0
creatorUnix = 3
creatorNTFS = 11
creatorVFAT = 14
creatorMacOSX = 19
)
type FileHeader struct {
@ -98,17 +102,85 @@ func (h *FileHeader) ModTime() time.Time {
return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
}
// traditional names for Unix constants
const (
s_IFMT = 0xf000
s_IFDIR = 0x4000
s_IFREG = 0x8000
s_ISUID = 0x800
s_ISGID = 0x400
msdosDir = 0x10
msdosReadOnly = 0x01
)
// Mode returns the permission and mode bits for the FileHeader.
// An error is returned in case the information is not available.
func (h *FileHeader) Mode() (mode uint32, err error) {
if h.CreatorVersion>>8 == creatorUnix {
return h.ExternalAttrs >> 16, nil
func (h *FileHeader) Mode() (mode os.FileMode, err error) {
switch h.CreatorVersion >> 8 {
case creatorUnix, creatorMacOSX:
mode = unixModeToFileMode(h.ExternalAttrs >> 16)
case creatorNTFS, creatorVFAT, creatorFAT:
mode = msdosModeToFileMode(h.ExternalAttrs)
}
return 0, errors.New("file mode not available")
if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' {
mode |= os.ModeDir
}
return mode, nil
}
// SetMode changes the permission and mode bits for the FileHeader.
func (h *FileHeader) SetMode(mode uint32) {
func (h *FileHeader) SetMode(mode os.FileMode) {
h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
h.ExternalAttrs = mode << 16
h.ExternalAttrs = fileModeToUnixMode(mode) << 16
// set MSDOS attributes too, as the original zip does.
if mode&os.ModeDir != 0 {
h.ExternalAttrs |= msdosDir
}
if mode&0200 == 0 {
h.ExternalAttrs |= msdosReadOnly
}
}
func msdosModeToFileMode(m uint32) (mode os.FileMode) {
if m&msdosDir != 0 {
mode = os.ModeDir | 0777
} else {
mode = 0666
}
if m&msdosReadOnly != 0 {
mode &^= 0222
}
return mode
}
func fileModeToUnixMode(mode os.FileMode) uint32 {
var m uint32
if mode&os.ModeDir != 0 {
m = s_IFDIR
} else {
m = s_IFREG
}
if mode&os.ModeSetuid != 0 {
m |= s_ISUID
}
if mode&os.ModeSetgid != 0 {
m |= s_ISGID
}
return m | uint32(mode&0777)
}
func unixModeToFileMode(m uint32) os.FileMode {
var mode os.FileMode
if m&s_IFMT == s_IFDIR {
mode |= os.ModeDir
}
if m&s_ISGID != 0 {
mode |= os.ModeSetgid
}
if m&s_ISUID != 0 {
mode |= os.ModeSetuid
}
return mode | os.FileMode(m&0777)
}

BIN
libgo/go/archive/zip/testdata/unix.zip vendored Normal file

Binary file not shown.

BIN
libgo/go/archive/zip/testdata/winxp.zip vendored Normal file

Binary file not shown.

View file

@ -8,6 +8,7 @@ import (
"bytes"
"io/ioutil"
"math/rand"
"os"
"testing"
)
@ -17,7 +18,7 @@ type WriteTest struct {
Name string
Data []byte
Method uint16
Mode uint32
Mode os.FileMode
}
var writeTests = []WriteTest{
@ -25,12 +26,31 @@ var writeTests = []WriteTest{
Name: "foo",
Data: []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."),
Method: Store,
Mode: 0666,
},
{
Name: "bar",
Data: nil, // large data set in the test
Method: Deflate,
Mode: 0x81ed,
Mode: 0644,
},
{
Name: "setuid",
Data: []byte("setuid file"),
Method: Deflate,
Mode: 0755 | os.ModeSetuid,
},
{
Name: "setgid",
Data: []byte("setgid file"),
Method: Deflate,
Mode: 0755 | os.ModeSetgid,
},
{
Name: "setgid",
Data: []byte("setgid file"),
Method: Deflate,
Mode: 0755 | os.ModeSetgid,
},
}

View file

@ -52,12 +52,14 @@ type Reader struct {
lastRuneSize int
}
const minReadBufferSize = 16
// NewReaderSize creates a new Reader whose buffer has the specified size,
// which must be greater than one. If the argument io.Reader is already a
// which must be at least 16 bytes. If the argument io.Reader is already a
// Reader with large enough size, it returns the underlying Reader.
// It returns the Reader and any error.
func NewReaderSize(rd io.Reader, size int) (*Reader, error) {
if size <= 1 {
if size < minReadBufferSize {
return nil, BufSizeError(size)
}
// Is it already a Reader?

View file

@ -135,9 +135,10 @@ var bufreaders = []bufReader{
{"lines", readLines},
}
const minReadBufferSize = 16
var bufsizes = []int{
2, 3, 4, 5, 6, 7, 8, 9, 10,
23, 32, 46, 64, 93, 128, 1024, 4096,
minReadBufferSize, 23, 32, 46, 64, 93, 128, 1024, 4096,
}
func TestReader(t *testing.T) {
@ -514,27 +515,32 @@ func TestWriteString(t *testing.T) {
}
func TestBufferFull(t *testing.T) {
buf, _ := NewReaderSize(strings.NewReader("hello, world"), 5)
line, err := buf.ReadSlice(',')
if string(line) != "hello" || err != ErrBufferFull {
const longString = "And now, hello, world! It is the time for all good men to come to the aid of their party"
buf, err := NewReaderSize(strings.NewReader(longString), minReadBufferSize)
if err != nil {
t.Fatal("NewReaderSize:", err)
}
line, err := buf.ReadSlice('!')
if string(line) != "And now, hello, " || err != ErrBufferFull {
t.Errorf("first ReadSlice(,) = %q, %v", line, err)
}
line, err = buf.ReadSlice(',')
if string(line) != "," || err != nil {
line, err = buf.ReadSlice('!')
if string(line) != "world!" || err != nil {
t.Errorf("second ReadSlice(,) = %q, %v", line, err)
}
}
func TestPeek(t *testing.T) {
p := make([]byte, 10)
buf, _ := NewReaderSize(strings.NewReader("abcdefghij"), 4)
// string is 16 (minReadBufferSize) long.
buf, _ := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBufferSize)
if s, err := buf.Peek(1); string(s) != "a" || err != nil {
t.Fatalf("want %q got %q, err=%v", "a", string(s), err)
}
if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
t.Fatalf("want %q got %q, err=%v", "abcd", string(s), err)
}
if _, err := buf.Peek(5); err != ErrBufferFull {
if _, err := buf.Peek(32); err != ErrBufferFull {
t.Fatalf("want ErrBufFull got %v", err)
}
if _, err := buf.Read(p[0:3]); string(p[0:3]) != "abc" || err != nil {
@ -552,8 +558,8 @@ func TestPeek(t *testing.T) {
if s, err := buf.Peek(4); string(s) != "ghij" || err != nil {
t.Fatalf("want %q got %q, err=%v", "ghij", string(s), err)
}
if _, err := buf.Read(p[0:4]); string(p[0:4]) != "ghij" || err != nil {
t.Fatalf("want %q got %q, err=%v", "ghij", string(p[0:3]), err)
if _, err := buf.Read(p[0:]); string(p[0:]) != "ghijklmnop" || err != nil {
t.Fatalf("want %q got %q, err=%v", "ghijklmnop", string(p[0:minReadBufferSize]), err)
}
if s, err := buf.Peek(0); string(s) != "" || err != nil {
t.Fatalf("want %q got %q, err=%v", "", string(s), err)
@ -635,19 +641,25 @@ func TestReadLine(t *testing.T) {
}
func TestLineTooLong(t *testing.T) {
buf := bytes.NewBuffer([]byte("aaabbbcc\n"))
l, _ := NewReaderSize(buf, 3)
data := make([]byte, 0)
for i := 0; i < minReadBufferSize*5/2; i++ {
data = append(data, '0'+byte(i%10))
}
buf := bytes.NewBuffer(data)
l, _ := NewReaderSize(buf, minReadBufferSize)
line, isPrefix, err := l.ReadLine()
if !isPrefix || !bytes.Equal(line, []byte("aaa")) || err != nil {
t.Errorf("bad result for first line: %x %s", line, err)
if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
t.Errorf("bad result for first line: got %q want %q %v", line, data[:minReadBufferSize], err)
}
data = data[len(line):]
line, isPrefix, err = l.ReadLine()
if !isPrefix || !bytes.Equal(line, []byte("bbb")) || err != nil {
t.Errorf("bad result for second line: %x", line)
if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
t.Errorf("bad result for second line: got %q want %q %v", line, data[:minReadBufferSize], err)
}
data = data[len(line):]
line, isPrefix, err = l.ReadLine()
if isPrefix || !bytes.Equal(line, []byte("cc")) || err != nil {
t.Errorf("bad result for third line: %x", line)
if isPrefix || !bytes.Equal(line, data[:minReadBufferSize/2]) || err != nil {
t.Errorf("bad result for third line: got %q want %q %v", line, data[:minReadBufferSize/2], err)
}
line, isPrefix, err = l.ReadLine()
if isPrefix || err == nil {
@ -656,8 +668,8 @@ func TestLineTooLong(t *testing.T) {
}
func TestReadAfterLines(t *testing.T) {
line1 := "line1"
restData := "line2\nline 3\n"
line1 := "this is line1"
restData := "this is line2\nthis is line 3\n"
inbuf := bytes.NewBuffer([]byte(line1 + "\n" + restData))
outbuf := new(bytes.Buffer)
maxLineLength := len(line1) + len(restData)/2
@ -676,7 +688,7 @@ func TestReadAfterLines(t *testing.T) {
}
func TestReadEmptyBuffer(t *testing.T) {
l, _ := NewReaderSize(bytes.NewBuffer(nil), 10)
l, _ := NewReaderSize(bytes.NewBuffer(nil), minReadBufferSize)
line, isPrefix, err := l.ReadLine()
if err != io.EOF {
t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
@ -684,7 +696,7 @@ func TestReadEmptyBuffer(t *testing.T) {
}
func TestLinesAfterRead(t *testing.T) {
l, _ := NewReaderSize(bytes.NewBuffer([]byte("foo")), 10)
l, _ := NewReaderSize(bytes.NewBuffer([]byte("foo")), minReadBufferSize)
_, err := ioutil.ReadAll(l)
if err != nil {
t.Error(err)
@ -715,34 +727,19 @@ type readLineResult struct {
}
var readLineNewlinesTests = []struct {
input string
bufSize int
expect []readLineResult
input string
expect []readLineResult
}{
{"h\r\nb\r\n", 2, []readLineResult{
{[]byte("h"), true, nil},
{"012345678901234\r\n012345678901234\r\n", []readLineResult{
{[]byte("012345678901234"), true, nil},
{nil, false, nil},
{[]byte("b"), true, nil},
{[]byte("012345678901234"), true, nil},
{nil, false, nil},
{nil, false, io.EOF},
}},
{"hello\r\nworld\r\n", 6, []readLineResult{
{[]byte("hello"), true, nil},
{nil, false, nil},
{[]byte("world"), true, nil},
{nil, false, nil},
{nil, false, io.EOF},
}},
{"hello\rworld\r", 6, []readLineResult{
{[]byte("hello"), true, nil},
{[]byte("\rworld"), true, nil},
{[]byte("\r"), false, nil},
{nil, false, io.EOF},
}},
{"h\ri\r\n\r", 2, []readLineResult{
{[]byte("h"), true, nil},
{[]byte("\ri"), true, nil},
{nil, false, nil},
{"0123456789012345\r012345678901234\r", []readLineResult{
{[]byte("0123456789012345"), true, nil},
{[]byte("\r012345678901234"), true, nil},
{[]byte("\r"), false, nil},
{nil, false, io.EOF},
}},
@ -750,12 +747,12 @@ var readLineNewlinesTests = []struct {
func TestReadLineNewlines(t *testing.T) {
for _, e := range readLineNewlinesTests {
testReadLineNewlines(t, e.input, e.bufSize, e.expect)
testReadLineNewlines(t, e.input, e.expect)
}
}
func testReadLineNewlines(t *testing.T, input string, bufSize int, expect []readLineResult) {
b, err := NewReaderSize(strings.NewReader(input), bufSize)
func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) {
b, err := NewReaderSize(strings.NewReader(input), minReadBufferSize)
if err != nil {
t.Fatal(err)
}

View file

@ -37,7 +37,9 @@ func Compare(a, b []byte) int {
}
// Equal returns a boolean reporting whether a == b.
func Equal(a, b []byte) bool {
func Equal(a, b []byte) bool
func equalPortable(a, b []byte) bool {
if len(a) != len(b) {
return false
}
@ -74,18 +76,33 @@ func explode(s []byte, n int) [][]byte {
// Count counts the number of non-overlapping instances of sep in s.
func Count(s, sep []byte) int {
if len(sep) == 0 {
n := len(sep)
if n == 0 {
return utf8.RuneCount(s) + 1
}
c := sep[0]
n := 0
for i := 0; i+len(sep) <= len(s); i++ {
if s[i] == c && (len(sep) == 1 || Equal(s[i:i+len(sep)], sep)) {
n++
i += len(sep) - 1
}
if n > len(s) {
return 0
}
return n
count := 0
c := sep[0]
i := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if n == 1 || Equal(s[i:i+n], sep) {
count++
i += n
continue
}
i++
}
return count
}
// Contains returns whether subslice is within b.
@ -99,11 +116,27 @@ func Index(s, sep []byte) int {
if n == 0 {
return 0
}
if n > len(s) {
return -1
}
c := sep[0]
for i := 0; i+n <= len(s); i++ {
if s[i] == c && (n == 1 || Equal(s[i:i+n], sep)) {
if n == 1 {
return IndexByte(s, c)
}
i := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
}
return -1
}
@ -437,7 +470,7 @@ func Title(s []byte) []byte {
// Use a closure here to remember state.
// Hackish but effective. Depends on Map scanning in order and calling
// the closure once per rune.
prev := rune(' ')
prev := ' '
return Map(
func(r rune) rune {
if isSeparator(prev) {

View file

@ -64,13 +64,17 @@ func TestCompare(t *testing.T) {
a := []byte(tt.a)
b := []byte(tt.b)
cmp := Compare(a, b)
eql := Equal(a, b)
if cmp != tt.i {
t.Errorf(`Compare(%q, %q) = %v`, tt.a, tt.b, cmp)
}
eql := Equal(a, b)
if eql != (tt.i == 0) {
t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
}
eql = EqualPortable(a, b)
if eql != (tt.i == 0) {
t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql)
}
}
}
@ -264,27 +268,18 @@ func TestIndexRune(t *testing.T) {
}
}
func BenchmarkIndexByte4K(b *testing.B) { bmIndex(b, IndexByte, 4<<10) }
func BenchmarkIndexByte4M(b *testing.B) { bmIndex(b, IndexByte, 4<<20) }
func BenchmarkIndexByte64M(b *testing.B) { bmIndex(b, IndexByte, 64<<20) }
func BenchmarkIndexBytePortable4K(b *testing.B) {
bmIndex(b, IndexBytePortable, 4<<10)
}
func BenchmarkIndexBytePortable4M(b *testing.B) {
bmIndex(b, IndexBytePortable, 4<<20)
}
func BenchmarkIndexBytePortable64M(b *testing.B) {
bmIndex(b, IndexBytePortable, 64<<20)
}
var bmbuf []byte
func bmIndex(b *testing.B, index func([]byte, byte) int, n int) {
func BenchmarkIndexByte32(b *testing.B) { bmIndexByte(b, IndexByte, 32) }
func BenchmarkIndexByte4K(b *testing.B) { bmIndexByte(b, IndexByte, 4<<10) }
func BenchmarkIndexByte4M(b *testing.B) { bmIndexByte(b, IndexByte, 4<<20) }
func BenchmarkIndexByte64M(b *testing.B) { bmIndexByte(b, IndexByte, 64<<20) }
func BenchmarkIndexBytePortable32(b *testing.B) { bmIndexByte(b, IndexBytePortable, 32) }
func BenchmarkIndexBytePortable4K(b *testing.B) { bmIndexByte(b, IndexBytePortable, 4<<10) }
func BenchmarkIndexBytePortable4M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 4<<20) }
func BenchmarkIndexBytePortable64M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 64<<20) }
func bmIndexByte(b *testing.B, index func([]byte, byte) int, n int) {
if len(bmbuf) < n {
bmbuf = make([]byte, n)
}
@ -298,7 +293,127 @@ func bmIndex(b *testing.B, index func([]byte, byte) int, n int) {
panic("bad index")
}
}
buf[n-1] = '0'
buf[n-1] = '\x00'
}
func BenchmarkEqual32(b *testing.B) { bmEqual(b, Equal, 32) }
func BenchmarkEqual4K(b *testing.B) { bmEqual(b, Equal, 4<<10) }
func BenchmarkEqual4M(b *testing.B) { bmEqual(b, Equal, 4<<20) }
func BenchmarkEqual64M(b *testing.B) { bmEqual(b, Equal, 64<<20) }
func BenchmarkEqualPort32(b *testing.B) { bmEqual(b, EqualPortable, 32) }
func BenchmarkEqualPort4K(b *testing.B) { bmEqual(b, EqualPortable, 4<<10) }
func BenchmarkEqualPortable4M(b *testing.B) { bmEqual(b, EqualPortable, 4<<20) }
func BenchmarkEqualPortable64M(b *testing.B) { bmEqual(b, EqualPortable, 64<<20) }
func bmEqual(b *testing.B, equal func([]byte, []byte) bool, n int) {
if len(bmbuf) < 2*n {
bmbuf = make([]byte, 2*n)
}
b.SetBytes(int64(n))
buf1 := bmbuf[0:n]
buf2 := bmbuf[n : 2*n]
buf1[n-1] = 'x'
buf2[n-1] = 'x'
for i := 0; i < b.N; i++ {
eq := equal(buf1, buf2)
if !eq {
panic("bad equal")
}
}
buf1[n-1] = '\x00'
buf2[n-1] = '\x00'
}
func BenchmarkIndex32(b *testing.B) { bmIndex(b, Index, 32) }
func BenchmarkIndex4K(b *testing.B) { bmIndex(b, Index, 4<<10) }
func BenchmarkIndex4M(b *testing.B) { bmIndex(b, Index, 4<<20) }
func BenchmarkIndex64M(b *testing.B) { bmIndex(b, Index, 64<<20) }
func bmIndex(b *testing.B, index func([]byte, []byte) int, n int) {
if len(bmbuf) < n {
bmbuf = make([]byte, n)
}
b.SetBytes(int64(n))
buf := bmbuf[0:n]
buf[n-1] = 'x'
for i := 0; i < b.N; i++ {
j := index(buf, buf[n-7:])
if j != n-7 {
println("bad index", j)
panic("bad index")
}
}
buf[n-1] = '\x00'
}
func BenchmarkIndexEasy32(b *testing.B) { bmIndexEasy(b, Index, 32) }
func BenchmarkIndexEasy4K(b *testing.B) { bmIndexEasy(b, Index, 4<<10) }
func BenchmarkIndexEasy4M(b *testing.B) { bmIndexEasy(b, Index, 4<<20) }
func BenchmarkIndexEasy64M(b *testing.B) { bmIndexEasy(b, Index, 64<<20) }
func bmIndexEasy(b *testing.B, index func([]byte, []byte) int, n int) {
if len(bmbuf) < n {
bmbuf = make([]byte, n)
}
b.SetBytes(int64(n))
buf := bmbuf[0:n]
buf[n-1] = 'x'
buf[n-7] = 'x'
for i := 0; i < b.N; i++ {
j := index(buf, buf[n-7:])
if j != n-7 {
println("bad index", j)
panic("bad index")
}
}
buf[n-1] = '\x00'
buf[n-7] = '\x00'
}
func BenchmarkCount32(b *testing.B) { bmCount(b, Count, 32) }
func BenchmarkCount4K(b *testing.B) { bmCount(b, Count, 4<<10) }
func BenchmarkCount4M(b *testing.B) { bmCount(b, Count, 4<<20) }
func BenchmarkCount64M(b *testing.B) { bmCount(b, Count, 64<<20) }
func bmCount(b *testing.B, count func([]byte, []byte) int, n int) {
if len(bmbuf) < n {
bmbuf = make([]byte, n)
}
b.SetBytes(int64(n))
buf := bmbuf[0:n]
buf[n-1] = 'x'
for i := 0; i < b.N; i++ {
j := count(buf, buf[n-7:])
if j != 1 {
println("bad count", j)
panic("bad count")
}
}
buf[n-1] = '\x00'
}
func BenchmarkCountEasy32(b *testing.B) { bmCountEasy(b, Count, 32) }
func BenchmarkCountEasy4K(b *testing.B) { bmCountEasy(b, Count, 4<<10) }
func BenchmarkCountEasy4M(b *testing.B) { bmCountEasy(b, Count, 4<<20) }
func BenchmarkCountEasy64M(b *testing.B) { bmCountEasy(b, Count, 64<<20) }
func bmCountEasy(b *testing.B, count func([]byte, []byte) int, n int) {
if len(bmbuf) < n {
bmbuf = make([]byte, n)
}
b.SetBytes(int64(n))
buf := bmbuf[0:n]
buf[n-1] = 'x'
buf[n-7] = 'x'
for i := 0; i < b.N; i++ {
j := count(buf, buf[n-7:])
if j != 1 {
println("bad count", j)
panic("bad count")
}
}
buf[n-1] = '\x00'
buf[n-7] = '\x00'
}
type ExplodeTest struct {

View file

@ -6,3 +6,4 @@ package bytes
// Export func for testing
var IndexBytePortable = indexBytePortable
var EqualPortable = equalPortable

View file

@ -26,3 +26,17 @@ IndexByte (struct __go_open_array s, char b)
return -1;
return p - (char *) s.__values;
}
/* Comparison. */
_Bool Equal (struct __go_open_array a, struct __go_open_array b)
asm ("libgo_bytes.bytes.Equal")
__attribute__ ((no_split_stack));
_Bool
Equal (struct __go_open_array a, struct __go_open_array b)
{
if (a.__count != b.__count)
return 0;
return __builtin_memcmp (a.__values, b.__values, a.__count) == 0;
}

View file

@ -319,7 +319,9 @@ Loop:
// For matches this long, we don't bother inserting each individual
// item into the table.
d.index += d.length
d.hash = (int(d.window[d.index])<<hashShift + int(d.window[d.index+1]))
if d.index < d.maxInsertIndex {
d.hash = (int(d.window[d.index])<<hashShift + int(d.window[d.index+1]))
}
}
if d.ti == maxFlateBlockTokens {
// The block includes the current character

View file

@ -318,3 +318,15 @@ func TestWriterDict(t *testing.T) {
t.Fatalf("writer wrote %q want %q", b1.Bytes(), b.Bytes())
}
}
// See http://code.google.com/p/go/issues/detail?id=2508
func TestRegression2508(t *testing.T) {
w := NewWriter(ioutil.Discard, 1)
buf := make([]byte, 1024)
for i := 0; i < 131072; i++ {
if _, err := w.Write(buf); err != nil {
t.Fatalf("writer failed: %v", err)
}
}
w.Close()
}

View file

@ -96,6 +96,7 @@ func get4(p []byte) uint32 {
func (z *Decompressor) readString() (string, error) {
var err error
needconv := false
for i := 0; ; i++ {
if i >= len(z.buf) {
return "", HeaderError
@ -104,9 +105,18 @@ func (z *Decompressor) readString() (string, error) {
if err != nil {
return "", err
}
if z.buf[i] > 0x7f {
needconv = true
}
if z.buf[i] == 0 {
// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
// TODO(nigeltao): Convert from ISO 8859-1 (Latin-1) to UTF-8.
if needconv {
s := make([]rune, 0, i)
for _, v := range z.buf[0:i] {
s = append(s, rune(v))
}
return string(s), nil
}
return string(z.buf[0:i]), nil
}
}

View file

@ -86,13 +86,25 @@ func (z *Compressor) writeBytes(b []byte) error {
// writeString writes a string (in ISO 8859-1 (Latin-1) format) to z.w.
func (z *Compressor) writeString(s string) error {
// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
// TODO(nigeltao): Convert from UTF-8 to ISO 8859-1 (Latin-1).
var err error
needconv := false
for _, v := range s {
if v == 0 || v > 0x7f {
return errors.New("gzip.Write: non-ASCII header string")
if v == 0 || v > 0xff {
return errors.New("gzip.Write: non-Latin-1 header string")
}
if v > 0x7f {
needconv = true
}
}
_, err := io.WriteString(z.w, s)
if needconv {
b := make([]byte, 0, len(s))
for _, v := range s {
b = append(b, byte(v))
}
_, err = z.w.Write(b)
} else {
_, err = io.WriteString(z.w, s)
}
if err != nil {
return err
}

View file

@ -5,6 +5,8 @@
package gzip
import (
"bufio"
"bytes"
"io"
"io/ioutil"
"testing"
@ -52,7 +54,8 @@ func TestEmpty(t *testing.T) {
func TestWriter(t *testing.T) {
pipe(t,
func(compressor *Compressor) {
compressor.Comment = "comment"
compressor.Comment = "Äußerung"
//compressor.Comment = "comment"
compressor.Extra = []byte("extra")
compressor.ModTime = time.Unix(1e8, 0)
compressor.Name = "name"
@ -69,8 +72,8 @@ func TestWriter(t *testing.T) {
if string(b) != "payload" {
t.Fatalf("payload is %q, want %q", string(b), "payload")
}
if decompressor.Comment != "comment" {
t.Fatalf("comment is %q, want %q", decompressor.Comment, "comment")
if decompressor.Comment != "Äußerung" {
t.Fatalf("comment is %q, want %q", decompressor.Comment, "Äußerung")
}
if string(decompressor.Extra) != "extra" {
t.Fatalf("extra is %q, want %q", decompressor.Extra, "extra")
@ -83,3 +86,29 @@ func TestWriter(t *testing.T) {
}
})
}
func TestLatin1(t *testing.T) {
latin1 := []byte{0xc4, 'u', 0xdf, 'e', 'r', 'u', 'n', 'g', 0}
utf8 := "Äußerung"
z := Decompressor{r: bufio.NewReader(bytes.NewBuffer(latin1))}
s, err := z.readString()
if err != nil {
t.Fatalf("%v", err)
}
if s != utf8 {
t.Fatalf("string is %q, want %q", s, utf8)
}
buf := bytes.NewBuffer(make([]byte, 0, len(latin1)))
c := Compressor{w: buf}
if err = c.writeString(utf8); err != nil {
t.Fatalf("%v", err)
}
s = buf.String()
if s != string(latin1) {
t.Fatalf("string is %v, want %v", s, latin1)
}
//if s, err = buf.ReadString(0); err != nil {
//t.Fatalf("%v", err)
//}
}

View file

@ -91,6 +91,7 @@ func TestTe(t *testing.T) {
s2 := mul(s, 2)
s3 := mul(s, 3)
w := s2<<24 | s<<16 | s<<8 | s3
te := [][256]uint32{te0, te1, te2, te3}
for j := 0; j < 4; j++ {
if x := te[j][i]; x != w {
t.Fatalf("te[%d][%d] = %#x, want %#x", j, i, x, w)
@ -110,6 +111,7 @@ func TestTd(t *testing.T) {
sd := mul(s, 0xd)
se := mul(s, 0xe)
w := se<<24 | s9<<16 | sd<<8 | sb
td := [][256]uint32{td0, td1, td2, td3}
for j := 0; j < 4; j++ {
if x := td[j][i]; x != w {
t.Fatalf("td[%d][%d] = %#x, want %#x", j, i, x, w)

View file

@ -56,10 +56,10 @@ func encryptBlock(xk []uint32, dst, src []byte) {
nr := len(xk)/4 - 2 // - 2: one above, one more below
k := 4
for r := 0; r < nr; r++ {
t0 = xk[k+0] ^ te[0][uint8(s0>>24)] ^ te[1][uint8(s1>>16)] ^ te[2][uint8(s2>>8)] ^ te[3][uint8(s3)]
t1 = xk[k+1] ^ te[0][uint8(s1>>24)] ^ te[1][uint8(s2>>16)] ^ te[2][uint8(s3>>8)] ^ te[3][uint8(s0)]
t2 = xk[k+2] ^ te[0][uint8(s2>>24)] ^ te[1][uint8(s3>>16)] ^ te[2][uint8(s0>>8)] ^ te[3][uint8(s1)]
t3 = xk[k+3] ^ te[0][uint8(s3>>24)] ^ te[1][uint8(s0>>16)] ^ te[2][uint8(s1>>8)] ^ te[3][uint8(s2)]
t0 = xk[k+0] ^ te0[uint8(s0>>24)] ^ te1[uint8(s1>>16)] ^ te2[uint8(s2>>8)] ^ te3[uint8(s3)]
t1 = xk[k+1] ^ te0[uint8(s1>>24)] ^ te1[uint8(s2>>16)] ^ te2[uint8(s3>>8)] ^ te3[uint8(s0)]
t2 = xk[k+2] ^ te0[uint8(s2>>24)] ^ te1[uint8(s3>>16)] ^ te2[uint8(s0>>8)] ^ te3[uint8(s1)]
t3 = xk[k+3] ^ te0[uint8(s3>>24)] ^ te1[uint8(s0>>16)] ^ te2[uint8(s1>>8)] ^ te3[uint8(s2)]
k += 4
s0, s1, s2, s3 = t0, t1, t2, t3
}
@ -101,10 +101,10 @@ func decryptBlock(xk []uint32, dst, src []byte) {
nr := len(xk)/4 - 2 // - 2: one above, one more below
k := 4
for r := 0; r < nr; r++ {
t0 = xk[k+0] ^ td[0][uint8(s0>>24)] ^ td[1][uint8(s3>>16)] ^ td[2][uint8(s2>>8)] ^ td[3][uint8(s1)]
t1 = xk[k+1] ^ td[0][uint8(s1>>24)] ^ td[1][uint8(s0>>16)] ^ td[2][uint8(s3>>8)] ^ td[3][uint8(s2)]
t2 = xk[k+2] ^ td[0][uint8(s2>>24)] ^ td[1][uint8(s1>>16)] ^ td[2][uint8(s0>>8)] ^ td[3][uint8(s3)]
t3 = xk[k+3] ^ td[0][uint8(s3>>24)] ^ td[1][uint8(s2>>16)] ^ td[2][uint8(s1>>8)] ^ td[3][uint8(s0)]
t0 = xk[k+0] ^ td0[uint8(s0>>24)] ^ td1[uint8(s3>>16)] ^ td2[uint8(s2>>8)] ^ td3[uint8(s1)]
t1 = xk[k+1] ^ td0[uint8(s1>>24)] ^ td1[uint8(s0>>16)] ^ td2[uint8(s3>>8)] ^ td3[uint8(s2)]
t2 = xk[k+2] ^ td0[uint8(s2>>24)] ^ td1[uint8(s1>>16)] ^ td2[uint8(s0>>8)] ^ td3[uint8(s3)]
t3 = xk[k+3] ^ td0[uint8(s3>>24)] ^ td1[uint8(s2>>16)] ^ td2[uint8(s1>>8)] ^ td3[uint8(s0)]
k += 4
s0, s1, s2, s3 = t0, t1, t2, t3
}
@ -168,7 +168,7 @@ func expandKey(key []byte, enc, dec []uint32) {
for j := 0; j < 4; j++ {
x := enc[ei+j]
if i > 0 && i+4 < n {
x = td[0][sbox0[x>>24]] ^ td[1][sbox0[x>>16&0xff]] ^ td[2][sbox0[x>>8&0xff]] ^ td[3][sbox0[x&0xff]]
x = td0[sbox0[x>>24]] ^ td1[sbox0[x>>16&0xff]] ^ td2[sbox0[x>>8&0xff]] ^ td3[sbox0[x&0xff]]
}
dec[i+j] = x
}

View file

@ -80,283 +80,279 @@ var sbox1 = [256]byte{
// Lookup tables for encryption.
// These can be recomputed by adapting the tests in aes_test.go.
var te = [4][256]uint32{
{
0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
},
{
0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
},
{
0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
},
{
0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
},
var te0 = [256]uint32{
0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
}
var te1 = [256]uint32{
0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b, 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b, 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d, 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf, 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626, 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1, 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3, 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2, 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a, 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3, 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded, 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939, 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb, 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f, 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f, 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121, 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec, 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d, 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc, 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414, 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a, 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262, 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d, 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea, 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e, 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f, 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666, 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9, 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111, 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9, 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d, 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f, 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
}
var te2 = [256]uint32{
0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b, 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b, 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d, 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af, 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26, 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1, 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3, 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2, 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a, 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3, 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed, 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239, 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb, 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f, 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f, 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221, 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec, 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d, 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc, 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814, 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a, 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462, 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d, 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea, 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e, 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f, 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66, 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9, 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211, 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9, 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d, 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f, 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
}
var te3 = [256]uint32{
0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6, 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56, 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa, 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45, 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c, 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9, 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d, 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf, 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34, 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d, 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1, 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72, 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed, 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe, 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05, 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342, 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3, 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a, 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3, 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28, 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14, 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4, 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da, 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf, 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c, 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e, 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc, 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069, 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322, 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9, 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a, 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e, 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
}
// Lookup tables for decryption.
// These can be recomputed by adapting the tests in aes_test.go.
var td = [4][256]uint32{
{
0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
},
{
0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
},
{
0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
},
{
0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
},
var td0 = [256]uint32{
0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
}
var td1 = [256]uint32{
0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e, 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c, 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0, 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259, 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971, 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f, 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8, 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708, 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2, 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb, 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd, 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e, 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000, 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39, 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91, 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17, 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60, 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1, 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1, 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964, 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b, 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46, 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512, 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a, 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c, 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8, 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604, 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41, 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c, 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737, 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340, 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1, 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
}
var td2 = [256]uint32{
0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27, 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502, 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe, 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552, 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9, 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253, 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b, 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337, 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69, 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6, 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6, 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9, 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000, 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d, 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b, 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b, 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f, 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4, 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729, 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9, 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4, 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e, 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25, 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f, 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0, 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7, 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496, 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b, 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13, 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7, 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3, 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456, 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
}
var td3 = [256]uint32{
0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
}

View file

@ -185,6 +185,10 @@ func GenerateKey(priv *PrivateKey, rand io.Reader) error {
// larger message) using the private key, priv. It returns the signature as a
// pair of integers. The security of the private key depends on the entropy of
// rand.
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
// FIPS 186-3, section 4.6
@ -218,10 +222,7 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
continue
}
if n > len(hash) {
n = len(hash)
}
z := k.SetBytes(hash[:n])
z := k.SetBytes(hash)
s = new(big.Int).Mul(priv.X, r)
s.Add(s, z)
@ -238,7 +239,11 @@ func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err err
}
// Verify verifies the signature in r, s of hash using the public key, pub. It
// returns true iff the signature is valid.
// reports whether the signature is valid.
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
// FIPS 186-3, section 4.7
@ -255,12 +260,7 @@ func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
if n&7 != 0 {
return false
}
n >>= 3
if n > len(hash) {
n = len(hash)
}
z := new(big.Int).SetBytes(hash[:n])
z := new(big.Int).SetBytes(hash)
u1 := new(big.Int).Mul(z, w)
u1.Mod(u1, pub.Q)

View file

@ -23,11 +23,11 @@ func TestOCSPDecode(t *testing.T) {
NextUpdate: time.Date(2010, 7, 7, 18, 35, 17, 0, time.UTC),
}
if !reflect.DeepEqual(resp.ThisUpdate, resp.ThisUpdate) {
if !reflect.DeepEqual(resp.ThisUpdate, expected.ThisUpdate) {
t.Errorf("resp.ThisUpdate: got %d, want %d", resp.ThisUpdate, expected.ThisUpdate)
}
if !reflect.DeepEqual(resp.NextUpdate, resp.NextUpdate) {
if !reflect.DeepEqual(resp.NextUpdate, expected.NextUpdate) {
t.Errorf("resp.NextUpdate: got %d, want %d", resp.NextUpdate, expected.NextUpdate)
}

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build plan9
package tls
func initDefaultRoots() {

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build freebsd linux openbsd netbsd
package tls
import (

View file

@ -1068,7 +1068,12 @@ func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *de
engine.instr = make([]decInstr, 1) // one item
name := rt.String() // best we can do
if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) {
return nil, errors.New("gob: wrong type received for local value " + name + ": " + dec.typeString(remoteId))
remoteType := dec.typeString(remoteId)
// Common confusing case: local interface type, remote concrete type.
if ut.base.Kind() == reflect.Interface && remoteId != tInterface {
return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType)
}
return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType)
}
op, indir := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp))
ovfl := errors.New(`value for "` + name + `" out of range`)

View file

@ -309,7 +309,7 @@ var singleTests = []SingleTest{
{[7]int{4, 55, 1, 44, 22, 66, 1234}, &testArray, ""},
// Decode errors
{172, &testFloat32, "wrong type"},
{172, &testFloat32, "type"},
}
func TestSingletons(t *testing.T) {

View file

@ -339,13 +339,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.WriteString("null")
break
}
// Slices can be marshalled as nil, but otherwise are handled
// as arrays.
fallthrough
case reflect.Array:
if v.Type() == byteSliceType {
if v.Type().Elem().Kind() == reflect.Uint8 {
// Byte slices get special treatment; arrays don't.
s := v.Bytes()
e.WriteByte('"')
s := v.Interface().([]byte)
if len(s) < 1024 {
// for small buffers, using Encode directly is much faster.
dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
@ -361,6 +358,10 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.WriteByte('"')
break
}
// Slices can be marshalled as nil, but otherwise are handled
// as arrays.
fallthrough
case reflect.Array:
e.WriteByte('[')
n := v.Len()
for i := 0; i < n; i++ {

View file

@ -82,3 +82,28 @@ func TestStringTag(t *testing.T) {
t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
}
}
// byte slices are special even if they're renamed types.
type renamedByte byte
type renamedByteSlice []byte
type renamedRenamedByteSlice []renamedByte
func TestEncodeRenamedByteSlice(t *testing.T) {
s := renamedByteSlice("abc")
result, err := Marshal(s)
if err != nil {
t.Fatal(err)
}
expect := `"YWJj"`
if string(result) != expect {
t.Errorf(" got %s want %s", result, expect)
}
r := renamedRenamedByteSlice("abc")
result, err = Marshal(r)
if err != nil {
t.Fatal(err)
}
if string(result) != expect {
t.Errorf(" got %s want %s", result, expect)
}
}

Binary file not shown.

View file

@ -57,7 +57,7 @@ func TestInotifyEvents(t *testing.T) {
}
// We expect this event to be received almost immediately, but let's wait 1 s to be sure
time.Sleep(1000e6) // 1000 ms
time.Sleep(1 * time.Second)
if eventsReceived == 0 {
t.Fatal("inotify event hasn't been received after 1 second")
}
@ -69,7 +69,7 @@ func TestInotifyEvents(t *testing.T) {
select {
case <-done:
t.Log("event channel closed")
case <-time.After(1e9):
case <-time.After(1 * time.Second):
t.Fatal("event stream was not closed after 1 second")
}
}
@ -84,7 +84,7 @@ func TestInotifyClose(t *testing.T) {
done = true
}()
time.Sleep(50e6) // 50 ms
time.Sleep(50 * time.Millisecond)
if !done {
t.Fatal("double Close() test failed: second Close() call didn't return")
}

View file

@ -177,7 +177,7 @@ func loadTestData() {
}
if test.r == 0 {
// save for CharacterByCharacterTests
test.r = int(r)
test.r = rune(r)
}
var buf [utf8.UTFMax]byte
sz := utf8.EncodeRune(buf[:], rune(r))
@ -242,9 +242,9 @@ func doConformanceTests(t *Test, partn int) {
func CharacterByCharacterTests() {
tests := part[1].tests
last := 0
var last rune = 0
for i := 0; i <= len(tests); i++ { // last one is special case
var r int
var r rune
if i == len(tests) {
r = 0x2FA1E // Don't have to go to 0x10FFFF
} else {
@ -285,7 +285,7 @@ func PerformanceTest() {
norm.NFC.Append(nil, buf...)
success <- true
}()
timeout := time.After(1e9)
timeout := time.After(1 * time.Second)
select {
case <-success:
// test completed before the timeout

View file

@ -95,35 +95,26 @@ func convertAssign(dest, src interface{}) error {
switch dv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
s := asString(src)
i64, err := strconv.ParseInt(s, 10, 64)
i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
if dv.OverflowInt(i64) {
return fmt.Errorf("string %q overflows %s", s, dv.Kind())
}
dv.SetInt(i64)
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
s := asString(src)
u64, err := strconv.ParseUint(s, 10, 64)
u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
if dv.OverflowUint(u64) {
return fmt.Errorf("string %q overflows %s", s, dv.Kind())
}
dv.SetUint(u64)
return nil
case reflect.Float32, reflect.Float64:
s := asString(src)
f64, err := strconv.ParseFloat(s, 64)
f64, err := strconv.ParseFloat(s, dv.Type().Bits())
if err != nil {
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
}
if dv.OverflowFloat(f64) {
return fmt.Errorf("value %q overflows %s", s, dv.Kind())
}
dv.SetFloat(f64)
return nil
}

View file

@ -55,10 +55,10 @@ var conversionTests = []conversionTest{
// Strings to integers
{s: "255", d: &scanuint8, wantuint: 255},
{s: "256", d: &scanuint8, wanterr: `string "256" overflows uint8`},
{s: "256", d: &scanuint8, wanterr: `converting string "256" to a uint8: strconv.ParseUint: parsing "256": value out of range`},
{s: "256", d: &scanuint16, wantuint: 256},
{s: "-1", d: &scanint, wantint: -1},
{s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: parsing "foo": invalid syntax`},
{s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: strconv.ParseInt: parsing "foo": invalid syntax`},
// True bools
{s: true, d: &scanbool, wantbool: true},

View file

@ -134,6 +134,7 @@ func (db *DB) maxIdleConns() int {
func (db *DB) conn() (driver.Conn, error) {
db.mu.Lock()
if db.closed {
db.mu.Unlock()
return nil, errors.New("sql: database is closed")
}
if n := len(db.freeConn); n > 0 {

View file

@ -228,3 +228,16 @@ func TestTxStmt(t *testing.T) {
t.Fatalf("Commit = %v", err)
}
}
// Tests fix for issue 2542, that we release a lock when querying on
// a closed connection.
func TestIssue2542Deadlock(t *testing.T) {
db := newTestDB(t, "people")
closeDB(t, db)
for i := 0; i < 2; i++ {
_, err := db.Query("SELECT|people|age,name|")
if err == nil {
t.Fatalf("expected error")
}
}
}

View file

@ -200,7 +200,7 @@ func (c *ClientConn) mainLoop() {
peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4])
if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 {
packet = packet[9:]
c.getChan(peersId).stdout.data <- packet[:length]
c.getChan(peersId).stdout.handleData(packet[:length])
}
case msgChannelExtendedData:
if len(packet) < 13 {
@ -215,7 +215,7 @@ func (c *ClientConn) mainLoop() {
// for stderr on interactive sessions. Other data types are
// silently discarded.
if datatype == 1 {
c.getChan(peersId).stderr.data <- packet[:length]
c.getChan(peersId).stderr.handleData(packet[:length])
}
}
default:
@ -228,12 +228,22 @@ func (c *ClientConn) mainLoop() {
c.getChan(msg.PeersId).msg <- msg
case *channelCloseMsg:
ch := c.getChan(msg.PeersId)
ch.theyClosed = true
close(ch.stdin.win)
close(ch.stdout.data)
close(ch.stderr.data)
ch.stdout.eof()
ch.stderr.eof()
close(ch.msg)
if !ch.weClosed {
ch.weClosed = true
ch.sendClose()
}
c.chanlist.remove(msg.PeersId)
case *channelEOFMsg:
c.getChan(msg.PeersId).msg <- msg
ch := c.getChan(msg.PeersId)
ch.stdout.eof()
// RFC 4254 is mute on how EOF affects dataExt messages but
// it is logical to signal EOF at the same time.
ch.stderr.eof()
case *channelRequestSuccessMsg:
c.getChan(msg.PeersId).msg <- msg
case *channelRequestFailureMsg:
@ -242,6 +252,8 @@ func (c *ClientConn) mainLoop() {
c.getChan(msg.PeersId).msg <- msg
case *windowAdjustMsg:
c.getChan(msg.PeersId).stdin.win <- int(msg.AdditionalBytes)
case *disconnectMsg:
break
default:
fmt.Printf("mainLoop: unhandled message %T: %v\n", msg, msg)
}
@ -294,6 +306,9 @@ type clientChan struct {
stdout *chanReader // receives the payload of channelData messages
stderr *chanReader // receives the payload of channelExtendedData messages
msg chan interface{} // incoming messages
theyClosed bool // indicates the close msg has been received from the remote side
weClosed bool // incidates the close msg has been sent from our side
}
// newClientChan returns a partially constructed *clientChan
@ -335,13 +350,29 @@ func (c *clientChan) waitForChannelOpenResponse() error {
return errors.New("unexpected packet")
}
// Close closes the channel. This does not close the underlying connection.
func (c *clientChan) Close() error {
// sendEOF sends EOF to the server. RFC 4254 Section 5.3
func (c *clientChan) sendEOF() error {
return c.writePacket(marshal(msgChannelEOF, channelEOFMsg{
PeersId: c.peersId,
}))
}
// sendClose signals the intent to close the channel.
func (c *clientChan) sendClose() error {
return c.writePacket(marshal(msgChannelClose, channelCloseMsg{
PeersId: c.peersId,
}))
}
// Close closes the channel. This does not close the underlying connection.
func (c *clientChan) Close() error {
if !c.weClosed {
c.weClosed = true
return c.sendClose()
}
return nil
}
// Thread safe channel list.
type chanlist struct {
// protects concurrent access to chans
@ -413,7 +444,7 @@ func (w *chanWriter) Write(data []byte) (n int, err error) {
}
func (w *chanWriter) Close() error {
return w.clientChan.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.clientChan.peersId}))
return w.clientChan.sendEOF()
}
// A chanReader represents stdout or stderr of a remote process.
@ -422,10 +453,27 @@ type chanReader struct {
// If writes to this channel block, they will block mainLoop, making
// it unable to receive new messages from the remote side.
data chan []byte // receives data from remote
dataClosed bool // protects data from being closed twice
clientChan *clientChan // the channel backing this reader
buf []byte
}
// eof signals to the consumer that there is no more data to be received.
func (r *chanReader) eof() {
if !r.dataClosed {
r.dataClosed = true
close(r.data)
}
}
// handleData sends buf to the reader's consumer. If r.data is closed
// the data will be silently discarded
func (r *chanReader) handleData(buf []byte) {
if !r.dataClosed {
r.data <- buf
}
}
// Read reads data from the remote process's stdout or stderr.
func (r *chanReader) Read(data []byte) (int, error) {
var ok bool

View file

@ -34,6 +34,20 @@ const (
SIGUSR2 Signal = "USR2"
)
var signals = map[Signal]int{
SIGABRT: 6,
SIGALRM: 14,
SIGFPE: 8,
SIGHUP: 1,
SIGILL: 4,
SIGINT: 2,
SIGKILL: 9,
SIGPIPE: 13,
SIGQUIT: 3,
SIGSEGV: 11,
SIGTERM: 15,
}
// A Session represents a connection to a remote command or shell.
type Session struct {
// Stdin specifies the remote process's standard input.
@ -170,10 +184,17 @@ func (s *Session) Start(cmd string) error {
return s.start()
}
// Run runs cmd on the remote host and waits for it to terminate.
// Typically, the remote server passes cmd to the shell for
// interpretation. A Session only accepts one call to Run,
// Start or Shell.
// Run runs cmd on the remote host. Typically, the remote
// server passes cmd to the shell for interpretation.
// A Session only accepts one call to Run, Start or Shell.
//
// The returned error is nil if the command runs, has no problems
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (s *Session) Run(cmd string) error {
err := s.Start(cmd)
if err != nil {
@ -233,6 +254,14 @@ func (s *Session) start() error {
}
// Wait waits for the remote command to exit.
//
// The returned error is nil if the command runs, has no problems
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (s *Session) Wait() error {
if !s.started {
return errors.New("ssh: session not started")
@ -255,21 +284,40 @@ func (s *Session) Wait() error {
}
func (s *Session) wait() error {
for {
switch msg := (<-s.msg).(type) {
wm := Waitmsg{status: -1}
// Wait for msg channel to be closed before returning.
for msg := range s.msg {
switch msg := msg.(type) {
case *channelRequestMsg:
// TODO(dfc) improve this behavior to match os.Waitmsg
switch msg.Request {
case "exit-status":
d := msg.RequestSpecificData
status := int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3])
if status > 0 {
return fmt.Errorf("remote process exited with %d", status)
}
return nil
wm.status = int(d[0])<<24 | int(d[1])<<16 | int(d[2])<<8 | int(d[3])
case "exit-signal":
// TODO(dfc) make a more readable error message
return fmt.Errorf("%v", msg.RequestSpecificData)
signal, rest, ok := parseString(msg.RequestSpecificData)
if !ok {
return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData)
}
wm.signal = safeString(string(signal))
// skip coreDumped bool
if len(rest) == 0 {
return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData)
}
rest = rest[1:]
errmsg, rest, ok := parseString(rest)
if !ok {
return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData)
}
wm.msg = safeString(string(errmsg))
lang, _, ok := parseString(rest)
if !ok {
return fmt.Errorf("wait: could not parse request data: %v", msg.RequestSpecificData)
}
wm.lang = safeString(string(lang))
default:
return fmt.Errorf("wait: unexpected channel request: %v", msg)
}
@ -277,7 +325,20 @@ func (s *Session) wait() error {
return fmt.Errorf("wait: unexpected packet %T received: %v", msg, msg)
}
}
panic("unreachable")
if wm.status == 0 {
return nil
}
if wm.status == -1 {
// exit-status was never sent from server
if wm.signal == "" {
return errors.New("wait: remote command exited without exit status or exit signal")
}
wm.status = 128
if _, ok := signals[Signal(wm.signal)]; ok {
wm.status += signals[Signal(wm.signal)]
}
}
return &ExitError{wm}
}
func (s *Session) stdin() error {
@ -391,3 +452,46 @@ func (c *ClientConn) NewSession() (*Session, error) {
clientChan: ch,
}, nil
}
// An ExitError reports unsuccessful completion of a remote command.
type ExitError struct {
Waitmsg
}
func (e *ExitError) Error() string {
return e.Waitmsg.String()
}
// Waitmsg stores the information about an exited remote command
// as reported by Wait.
type Waitmsg struct {
status int
signal string
msg string
lang string
}
// ExitStatus returns the exit status of the remote command.
func (w Waitmsg) ExitStatus() int {
return w.status
}
// Signal returns the exit signal of the remote command if
// it was terminated violently.
func (w Waitmsg) Signal() string {
return w.signal
}
// Msg returns the exit message given by the remote command
func (w Waitmsg) Msg() string {
return w.msg
}
// Lang returns the language tag. See RFC 3066
func (w Waitmsg) Lang() string {
return w.lang
}
func (w Waitmsg) String() string {
return fmt.Sprintf("Process exited with: %v. Reason was: %v (%v)", w.status, w.msg, w.signal)
}

View file

@ -12,8 +12,10 @@ import (
"testing"
)
type serverType func(*channel)
// dial constructs a new test server and returns a *ClientConn.
func dial(t *testing.T) *ClientConn {
func dial(handler serverType, t *testing.T) *ClientConn {
pw := password("tiger")
serverConfig.PasswordCallback = func(user, pass string) bool {
return user == "testuser" && pass == string(pw)
@ -50,27 +52,7 @@ func dial(t *testing.T) *ClientConn {
continue
}
ch.Accept()
go func() {
defer ch.Close()
// this string is returned to stdout
shell := NewServerShell(ch, "golang")
shell.ReadLine()
type exitMsg struct {
PeersId uint32
Request string
WantReply bool
Status uint32
}
// TODO(dfc) converting to the concrete type should not be
// necessary to send a packet.
msg := exitMsg{
PeersId: ch.(*channel).theirId,
Request: "exit-status",
WantReply: false,
Status: 0,
}
ch.(*channel).serverConn.writePacket(marshal(msgChannelRequest, msg))
}()
go handler(ch.(*channel))
}
t.Log("done")
}()
@ -91,7 +73,7 @@ func dial(t *testing.T) *ClientConn {
// Test a simple string is returned to session.Stdout.
func TestSessionShell(t *testing.T) {
conn := dial(t)
conn := dial(shellHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
@ -116,7 +98,7 @@ func TestSessionShell(t *testing.T) {
// Test a simple string is returned via StdoutPipe.
func TestSessionStdoutPipe(t *testing.T) {
conn := dial(t)
conn := dial(shellHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
@ -147,3 +129,237 @@ func TestSessionStdoutPipe(t *testing.T) {
t.Fatalf("Remote shell did not return expected string: expected=golang, actual=%s", actual)
}
}
// Test non-0 exit status is returned correctly.
func TestExitStatusNonZero(t *testing.T) {
conn := dial(exitStatusNonZeroHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("Unable to request new session: %s", err)
}
defer session.Close()
if err := session.Shell(); err != nil {
t.Fatalf("Unable to execute command: %s", err)
}
err = session.Wait()
if err == nil {
t.Fatalf("expected command to fail but it didn't")
}
e, ok := err.(*ExitError)
if !ok {
t.Fatalf("expected *ExitError but got %T", err)
}
if e.ExitStatus() != 15 {
t.Fatalf("expected command to exit with 15 but got %s", e.ExitStatus())
}
}
// Test 0 exit status is returned correctly.
func TestExitStatusZero(t *testing.T) {
conn := dial(exitStatusZeroHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("Unable to request new session: %s", err)
}
defer session.Close()
if err := session.Shell(); err != nil {
t.Fatalf("Unable to execute command: %s", err)
}
err = session.Wait()
if err != nil {
t.Fatalf("expected nil but got %s", err)
}
}
// Test exit signal and status are both returned correctly.
func TestExitSignalAndStatus(t *testing.T) {
conn := dial(exitSignalAndStatusHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("Unable to request new session: %s", err)
}
defer session.Close()
if err := session.Shell(); err != nil {
t.Fatalf("Unable to execute command: %s", err)
}
err = session.Wait()
if err == nil {
t.Fatalf("expected command to fail but it didn't")
}
e, ok := err.(*ExitError)
if !ok {
t.Fatalf("expected *ExitError but got %T", err)
}
if e.Signal() != "TERM" || e.ExitStatus() != 15 {
t.Fatalf("expected command to exit with signal TERM and status 15 but got signal %s and status %v", e.Signal(), e.ExitStatus())
}
}
// Test exit signal and status are both returned correctly.
func TestKnownExitSignalOnly(t *testing.T) {
conn := dial(exitSignalHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("Unable to request new session: %s", err)
}
defer session.Close()
if err := session.Shell(); err != nil {
t.Fatalf("Unable to execute command: %s", err)
}
err = session.Wait()
if err == nil {
t.Fatalf("expected command to fail but it didn't")
}
e, ok := err.(*ExitError)
if !ok {
t.Fatalf("expected *ExitError but got %T", err)
}
if e.Signal() != "TERM" || e.ExitStatus() != 143 {
t.Fatalf("expected command to exit with signal TERM and status 143 but got signal %s and status %v", e.Signal(), e.ExitStatus())
}
}
// Test exit signal and status are both returned correctly.
func TestUnknownExitSignal(t *testing.T) {
conn := dial(exitSignalUnknownHandler, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("Unable to request new session: %s", err)
}
defer session.Close()
if err := session.Shell(); err != nil {
t.Fatalf("Unable to execute command: %s", err)
}
err = session.Wait()
if err == nil {
t.Fatalf("expected command to fail but it didn't")
}
e, ok := err.(*ExitError)
if !ok {
t.Fatalf("expected *ExitError but got %T", err)
}
if e.Signal() != "SYS" || e.ExitStatus() != 128 {
t.Fatalf("expected command to exit with signal SYS and status 128 but got signal %s and status %v", e.Signal(), e.ExitStatus())
}
}
// Test WaitMsg is not returned if the channel closes abruptly.
func TestExitWithoutStatusOrSignal(t *testing.T) {
conn := dial(exitWithoutSignalOrStatus, t)
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
t.Fatalf("Unable to request new session: %s", err)
}
defer session.Close()
if err := session.Shell(); err != nil {
t.Fatalf("Unable to execute command: %s", err)
}
err = session.Wait()
if err == nil {
t.Fatalf("expected command to fail but it didn't")
}
_, ok := err.(*ExitError)
if ok {
// you can't actually test for errors.errorString
// because it's not exported.
t.Fatalf("expected *errorString but got %T", err)
}
}
type exitStatusMsg struct {
PeersId uint32
Request string
WantReply bool
Status uint32
}
type exitSignalMsg struct {
PeersId uint32
Request string
WantReply bool
Signal string
CoreDumped bool
Errmsg string
Lang string
}
func exitStatusZeroHandler(ch *channel) {
defer ch.Close()
// this string is returned to stdout
shell := NewServerShell(ch, "> ")
shell.ReadLine()
sendStatus(0, ch)
}
func exitStatusNonZeroHandler(ch *channel) {
defer ch.Close()
shell := NewServerShell(ch, "> ")
shell.ReadLine()
sendStatus(15, ch)
}
func exitSignalAndStatusHandler(ch *channel) {
defer ch.Close()
shell := NewServerShell(ch, "> ")
shell.ReadLine()
sendStatus(15, ch)
sendSignal("TERM", ch)
}
func exitSignalHandler(ch *channel) {
defer ch.Close()
shell := NewServerShell(ch, "> ")
shell.ReadLine()
sendSignal("TERM", ch)
}
func exitSignalUnknownHandler(ch *channel) {
defer ch.Close()
shell := NewServerShell(ch, "> ")
shell.ReadLine()
sendSignal("SYS", ch)
}
func exitWithoutSignalOrStatus(ch *channel) {
defer ch.Close()
shell := NewServerShell(ch, "> ")
shell.ReadLine()
}
func shellHandler(ch *channel) {
defer ch.Close()
// this string is returned to stdout
shell := NewServerShell(ch, "golang")
shell.ReadLine()
sendStatus(0, ch)
}
func sendStatus(status uint32, ch *channel) {
msg := exitStatusMsg{
PeersId: ch.theirId,
Request: "exit-status",
WantReply: false,
Status: status,
}
ch.serverConn.writePacket(marshal(msgChannelRequest, msg))
}
func sendSignal(signal string, ch *channel) {
sig := exitSignalMsg{
PeersId: ch.theirId,
Request: "exit-signal",
WantReply: false,
Signal: signal,
CoreDumped: false,
Errmsg: "Process terminated",
Lang: "en-GB-oed",
}
ch.serverConn.writePacket(marshal(msgChannelRequest, sig))
}

View file

@ -81,7 +81,7 @@ type gcParser struct {
func (p *gcParser) init(filename, id string, src io.Reader, imports map[string]*ast.Object) {
p.scanner.Init(src)
p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
p.scanner.Whitespace = 1<<'\t' | 1<<' '
p.scanner.Filename = filename // for good error messages
p.next()
@ -145,18 +145,14 @@ func GcImporter(imports map[string]*ast.Object, path string) (pkg *ast.Object, e
// Declare inserts a named object of the given kind in scope.
func (p *gcParser) declare(scope *ast.Scope, kind ast.ObjKind, name string) *ast.Object {
// a type may have been declared before - if it exists
// already in the respective package scope, return that
// type
if kind == ast.Typ {
if obj := scope.Lookup(name); obj != nil {
assert(obj.Kind == ast.Typ)
return obj
}
// the object may have been imported before - if it exists
// already in the respective package scope, return that object
if obj := scope.Lookup(name); obj != nil {
assert(obj.Kind == kind)
return obj
}
// any other object must be a newly declared object -
// create it and insert it into the package scope
// otherwise create a new object and insert it into the package scope
obj := ast.NewObj(kind, name)
if scope.Insert(obj) != nil {
p.errorf("already declared: %v %s", kind, obj.Name)
@ -199,14 +195,15 @@ func (p *gcParser) errorf(format string, args ...interface{}) {
func (p *gcParser) expect(tok rune) string {
lit := p.lit
if p.tok != tok {
p.errorf("expected %q, got %q (%q)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
panic(1)
p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
}
p.next()
return lit
}
func (p *gcParser) expectSpecial(tok string) {
sep := rune('x') // not white space
sep := 'x' // not white space
i := 0
for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
@ -261,7 +258,7 @@ func (p *gcParser) parsePkgId() *ast.Object {
func (p *gcParser) parseDotIdent() string {
ident := ""
if p.tok != scanner.Int {
sep := rune('x') // not white space
sep := 'x' // not white space
for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
ident += p.lit
sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
@ -645,6 +642,7 @@ func (p *gcParser) parseNumber() Const {
// Literal = bool_lit | int_lit | float_lit | complex_lit | string_lit .
// bool_lit = "true" | "false" .
// complex_lit = "(" float_lit "+" float_lit ")" .
// rune_lit = "(" int_lit "+" int_lit ")" .
// string_lit = `"` { unicode_char } `"` .
//
func (p *gcParser) parseConstDecl() {
@ -674,21 +672,33 @@ func (p *gcParser) parseConstDecl() {
typ = Float64.Underlying
}
case '(':
// complex_lit
// complex_lit or rune_lit
p.next()
if p.tok == scanner.Char {
p.next()
p.expect('+')
p.parseNumber()
p.expect(')')
// TODO: x = ...
break
}
re := p.parseNumber()
p.expect('+')
im := p.parseNumber()
p.expect(')')
x = Const{cmplx{re.val.(*big.Rat), im.val.(*big.Rat)}}
typ = Complex128.Underlying
case scanner.Char:
// TODO: x = ...
p.next()
case scanner.String:
// string_lit
x = MakeConst(token.STRING, p.lit)
p.next()
typ = String.Underlying
default:
p.error("expected literal")
println(p.tok)
p.errorf("expected literal got %s", scanner.TokenString(p.tok))
}
if obj.Type == nil {
obj.Type = typ

View file

@ -75,7 +75,7 @@ type Watcher struct {
// NewWatcher creates and returns a Watcher.
func NewWatcher() (*Watcher, error) {
port, e := syscall.CreateIoCompletionPort(syscall.InvalidHandle, 0, 0, 0)
if e != 0 {
if e != nil {
return nil, os.NewSyscallError("CreateIoCompletionPort", e)
}
w := &Watcher{
@ -147,7 +147,7 @@ func (w *Watcher) RemoveWatch(path string) error {
func (w *Watcher) wakeupReader() error {
e := syscall.PostQueuedCompletionStatus(w.port, 0, 0, nil)
if e != 0 {
if e != nil {
return os.NewSyscallError("PostQueuedCompletionStatus", e)
}
return nil
@ -155,7 +155,7 @@ func (w *Watcher) wakeupReader() error {
func getDir(pathname string) (dir string, err error) {
attr, e := syscall.GetFileAttributes(syscall.StringToUTF16Ptr(pathname))
if e != 0 {
if e != nil {
return "", os.NewSyscallError("GetFileAttributes", e)
}
if attr&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
@ -173,11 +173,11 @@ func getIno(path string) (ino *inode, err error) {
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
nil, syscall.OPEN_EXISTING,
syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OVERLAPPED, 0)
if e != 0 {
if e != nil {
return nil, os.NewSyscallError("CreateFile", e)
}
var fi syscall.ByHandleFileInformation
if e = syscall.GetFileInformationByHandle(h, &fi); e != 0 {
if e = syscall.GetFileInformationByHandle(h, &fi); e != nil {
syscall.CloseHandle(h)
return nil, os.NewSyscallError("GetFileInformationByHandle", e)
}
@ -222,7 +222,7 @@ func (w *Watcher) addWatch(pathname string, flags uint64) error {
}
watchEntry := w.watches.get(ino)
if watchEntry == nil {
if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != 0 {
if _, e := syscall.CreateIoCompletionPort(ino.handle, w.port, 0, 0); e != nil {
syscall.CloseHandle(ino.handle)
return os.NewSyscallError("CreateIoCompletionPort", e)
}
@ -295,7 +295,7 @@ func (w *Watcher) deleteWatch(watch *watch) {
// Must run within the I/O thread.
func (w *Watcher) startRead(watch *watch) error {
if e := syscall.CancelIo(watch.ino.handle); e != 0 {
if e := syscall.CancelIo(watch.ino.handle); e != nil {
w.Error <- os.NewSyscallError("CancelIo", e)
w.deleteWatch(watch)
}
@ -304,7 +304,7 @@ func (w *Watcher) startRead(watch *watch) error {
mask |= toWindowsFlags(m)
}
if mask == 0 {
if e := syscall.CloseHandle(watch.ino.handle); e != 0 {
if e := syscall.CloseHandle(watch.ino.handle); e != nil {
w.Error <- os.NewSyscallError("CloseHandle", e)
}
delete(w.watches[watch.ino.volume], watch.ino.index)
@ -312,7 +312,7 @@ func (w *Watcher) startRead(watch *watch) error {
}
e := syscall.ReadDirectoryChanges(watch.ino.handle, &watch.buf[0],
uint32(unsafe.Sizeof(watch.buf)), false, mask, nil, &watch.ov, 0)
if e != 0 {
if e != nil {
err := os.NewSyscallError("ReadDirectoryChanges", e)
if e == syscall.ERROR_ACCESS_DENIED && watch.mask&provisional == 0 {
// Watched directory was probably removed
@ -354,7 +354,7 @@ func (w *Watcher) readEvents() {
}
}
var err error
if e := syscall.CloseHandle(w.port); e != 0 {
if e := syscall.CloseHandle(w.port); e != nil {
err = os.NewSyscallError("CloseHandle", e)
}
close(w.Event)
@ -386,7 +386,7 @@ func (w *Watcher) readEvents() {
default:
w.Error <- os.NewSyscallError("GetQueuedCompletionPort", e)
continue
case 0:
case nil:
}
var offset uint32

View file

@ -21,7 +21,7 @@ func expect(t *testing.T, eventstream <-chan *Event, name string, mask uint32) {
if event.Name != name || event.Mask != mask {
t.Fatal("did not receive expected event")
}
case <-time.After(1e9):
case <-time.After(1 * time.Second):
t.Fatal("timed out waiting for event")
}
}
@ -108,7 +108,7 @@ func TestNotifyClose(t *testing.T) {
done = true
}()
time.Sleep(50e6) // 50 ms
time.Sleep(50 * time.Millisecond)
if !done {
t.Fatal("double Close() test failed: second Close() call didn't return")
}

View file

@ -18,8 +18,9 @@ func abortf(format string, a ...interface{}) {
os.Exit(1)
}
func abortErrNo(funcname string, err int) {
abortf("%s failed: %d %s\n", funcname, err, syscall.Errstr(err))
func abortErrNo(funcname string, err error) {
errno, _ := err.(syscall.Errno)
abortf("%s failed: %d %s\n", funcname, uint32(errno), err)
}
// global vars
@ -33,7 +34,7 @@ var (
func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
switch msg {
case WM_CREATE:
var e int
var e error
// CreateWindowEx
bh, e = CreateWindowEx(
0,
@ -42,7 +43,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt
WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
75, 70, 140, 25,
hwnd, 1, mh, 0)
if e != 0 {
if e != nil {
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("button handle is %x\n", bh)
@ -51,7 +52,7 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt
switch syscall.Handle(lparam) {
case bh:
e := PostMessage(hwnd, WM_CLOSE, 0, 0)
if e != 0 {
if e != nil {
abortErrNo("PostMessage", e)
}
default:
@ -69,23 +70,23 @@ func WndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintpt
}
func rungui() int {
var e int
var e error
// GetModuleHandle
mh, e = GetModuleHandle(nil)
if e != 0 {
if e != nil {
abortErrNo("GetModuleHandle", e)
}
// Get icon we're going to use.
myicon, e := LoadIcon(0, IDI_APPLICATION)
if e != 0 {
if e != nil {
abortErrNo("LoadIcon", e)
}
// Get cursor we're going to use.
mycursor, e := LoadCursor(0, IDC_ARROW)
if e != 0 {
if e != nil {
abortErrNo("LoadCursor", e)
}
@ -104,7 +105,7 @@ func rungui() int {
wc.MenuName = nil
wc.ClassName = wcname
wc.IconSm = myicon
if _, e := RegisterClassEx(&wc); e != 0 {
if _, e := RegisterClassEx(&wc); e != nil {
abortErrNo("RegisterClassEx", e)
}
@ -116,7 +117,7 @@ func rungui() int {
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
0, 0, mh, 0)
if e != 0 {
if e != nil {
abortErrNo("CreateWindowEx", e)
}
fmt.Printf("main window handle is %x\n", wh)
@ -125,7 +126,7 @@ func rungui() int {
ShowWindow(wh, SW_SHOWDEFAULT)
// UpdateWindow
if e := UpdateWindow(wh); e != 0 {
if e := UpdateWindow(wh); e != nil {
abortErrNo("UpdateWindow", e)
}
@ -133,7 +134,7 @@ func rungui() int {
var m Msg
for {
r, e := GetMessage(&m, 0, 0, 0)
if e != 0 {
if e != nil {
abortErrNo("GetMessage", e)
}
if r == 0 {

View file

@ -110,22 +110,22 @@ var (
IDI_INFORMATION = IDI_ASTERISK
)
//sys GetModuleHandle(modname *uint16) (handle syscall.Handle, errno int) = GetModuleHandleW
//sys RegisterClassEx(wndclass *Wndclassex) (atom uint16, errno int) = user32.RegisterClassExW
//sys CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, errno int) = user32.CreateWindowExW
//sys GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) = GetModuleHandleW
//sys RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) = user32.RegisterClassExW
//sys CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) = user32.CreateWindowExW
//sys DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) = user32.DefWindowProcW
//sys DestroyWindow(hwnd syscall.Handle) (errno int) = user32.DestroyWindow
//sys DestroyWindow(hwnd syscall.Handle) (err error) = user32.DestroyWindow
//sys PostQuitMessage(exitcode int32) = user32.PostQuitMessage
//sys ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) = user32.ShowWindow
//sys UpdateWindow(hwnd syscall.Handle) (errno int) = user32.UpdateWindow
//sys GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, errno int) [failretval==-1] = user32.GetMessageW
//sys UpdateWindow(hwnd syscall.Handle) (err error) = user32.UpdateWindow
//sys GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) [failretval==-1] = user32.GetMessageW
//sys TranslateMessage(msg *Msg) (done bool) = user32.TranslateMessage
//sys DispatchMessage(msg *Msg) (ret int32) = user32.DispatchMessageW
//sys LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, errno int) = user32.LoadIconW
//sys LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, errno int) = user32.LoadCursorW
//sys SetCursor(cursor syscall.Handle) (precursor syscall.Handle, errno int) = user32.SetCursor
//sys LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) = user32.LoadIconW
//sys LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) = user32.LoadCursorW
//sys SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) = user32.SetCursor
//sys SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (lresult uintptr) = user32.SendMessageW
//sys PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (errno int) = user32.PostMessageW
//sys PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) = user32.PostMessageW
func MakeIntResource(id uint16) *uint16 {
return (*uint16)(unsafe.Pointer(uintptr(id)))

View file

@ -28,47 +28,41 @@ var (
procPostMessageW = moduser32.NewProc("PostMessageW")
)
func GetModuleHandle(modname *uint16) (handle syscall.Handle, errno int) {
func GetModuleHandle(modname *uint16) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procGetModuleHandleW.Addr(), 1, uintptr(unsafe.Pointer(modname)), 0, 0)
handle = syscall.Handle(r0)
if handle == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
func RegisterClassEx(wndclass *Wndclassex) (atom uint16, errno int) {
func RegisterClassEx(wndclass *Wndclassex) (atom uint16, err error) {
r0, _, e1 := syscall.Syscall(procRegisterClassExW.Addr(), 1, uintptr(unsafe.Pointer(wndclass)), 0, 0)
atom = uint16(r0)
if atom == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, errno int) {
func CreateWindowEx(exstyle uint32, classname *uint16, windowname *uint16, style uint32, x int32, y int32, width int32, height int32, wndparent syscall.Handle, menu syscall.Handle, instance syscall.Handle, param uintptr) (hwnd syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall12(procCreateWindowExW.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(classname)), uintptr(unsafe.Pointer(windowname)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(wndparent), uintptr(menu), uintptr(instance), uintptr(param))
hwnd = syscall.Handle(r0)
if hwnd == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
@ -79,16 +73,14 @@ func DefWindowProc(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintp
return
}
func DestroyWindow(hwnd syscall.Handle) (errno int) {
func DestroyWindow(hwnd syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hwnd), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
@ -104,31 +96,27 @@ func ShowWindow(hwnd syscall.Handle, cmdshow int32) (wasvisible bool) {
return
}
func UpdateWindow(hwnd syscall.Handle) (errno int) {
func UpdateWindow(hwnd syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hwnd), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
func GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, errno int) {
func GetMessage(msg *Msg, hwnd syscall.Handle, MsgFilterMin uint32, MsgFilterMax uint32) (ret int32, err error) {
r0, _, e1 := syscall.Syscall6(procGetMessageW.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(MsgFilterMin), uintptr(MsgFilterMax), 0, 0)
ret = int32(r0)
if ret == -1 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
@ -145,47 +133,41 @@ func DispatchMessage(msg *Msg) (ret int32) {
return
}
func LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, errno int) {
func LoadIcon(instance syscall.Handle, iconname *uint16) (icon syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procLoadIconW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(iconname)), 0)
icon = syscall.Handle(r0)
if icon == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
func LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, errno int) {
func LoadCursor(instance syscall.Handle, cursorname *uint16) (cursor syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procLoadCursorW.Addr(), 2, uintptr(instance), uintptr(unsafe.Pointer(cursorname)), 0)
cursor = syscall.Handle(r0)
if cursor == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
func SetCursor(cursor syscall.Handle) (precursor syscall.Handle, errno int) {
func SetCursor(cursor syscall.Handle) (precursor syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procSetCursor.Addr(), 1, uintptr(cursor), 0, 0)
precursor = syscall.Handle(r0)
if precursor == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}
@ -196,16 +178,14 @@ func SendMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr
return
}
func PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (errno int) {
func PostMessage(hwnd syscall.Handle, msg uint32, wparam uintptr, lparam uintptr) (err error) {
r1, _, e1 := syscall.Syscall6(procPostMessageW.Addr(), 4, uintptr(hwnd), uintptr(msg), uintptr(wparam), uintptr(lparam), 0, 0)
if int(r1) == 0 {
if e1 != 0 {
errno = int(e1)
err = error(e1)
} else {
errno = syscall.EINVAL
err = syscall.EINVAL
}
} else {
errno = 0
}
return
}

View file

@ -193,7 +193,7 @@ func (f Func) String() string {
var vars map[string]Var = make(map[string]Var)
var mutex sync.Mutex
// Publish declares an named exported variable. This should be called from a
// Publish declares a named exported variable. This should be called from a
// package's init function when it creates its Vars. If the name is already
// registered then this will log.Panic.
func Publish(name string, v Var) {

View file

@ -813,3 +813,37 @@ func TestPanics(t *testing.T) {
}
}
}
// Test that erroneous String routine doesn't cause fatal recursion.
var recurCount = 0
type Recur struct {
i int
failed *bool
}
func (r Recur) String() string {
if recurCount++; recurCount > 10 {
*r.failed = true
return "FAIL"
}
// This will call badVerb. Before the fix, that would cause us to recur into
// this routine to print %!p(value). Now we don't call the user's method
// during an error.
return Sprintf("recur@%p value: %d", r, r.i)
}
func TestBadVerbRecursion(t *testing.T) {
failed := false
r := Recur{3, &failed}
Sprintf("recur@%p value: %d\n", &r, r.i)
if failed {
t.Error("fail with pointer")
}
failed = false
r = Recur{4, &failed}
Sprintf("recur@%p, value: %d\n", r, r.i)
if failed {
t.Error("fail with value")
}
}

View file

@ -331,9 +331,9 @@ func (f *fmt) fmt_q(s string) {
func (f *fmt) fmt_qc(c int64) {
var quoted string
if f.plus {
quoted = strconv.QuoteRuneToASCII(int(c))
quoted = strconv.QuoteRuneToASCII(rune(c))
} else {
quoted = strconv.QuoteRune(int(c))
quoted = strconv.QuoteRune(rune(c))
}
f.padString(quoted)
}

View file

@ -74,6 +74,7 @@ type GoStringer interface {
type pp struct {
n int
panicking bool
erroring bool // printing an error condition
buf bytes.Buffer
// field holds the current item, as an interface{}.
field interface{}
@ -124,6 +125,7 @@ var ppFree = newCache(func() interface{} { return new(pp) })
func newPrinter() *pp {
p := ppFree.get().(*pp)
p.panicking = false
p.erroring = false
p.fmt.init(&p.buf)
return p
}
@ -299,6 +301,7 @@ func (p *pp) unknownType(v interface{}) {
}
func (p *pp) badVerb(verb rune) {
p.erroring = true
p.add('%')
p.add('!')
p.add(verb)
@ -316,6 +319,7 @@ func (p *pp) badVerb(verb rune) {
p.buf.Write(nilAngleBytes)
}
p.add(')')
p.erroring = false
}
func (p *pp) fmtBool(v bool, verb rune) {
@ -606,6 +610,9 @@ func (p *pp) catchPanic(field interface{}, verb rune) {
}
func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString, handled bool) {
if p.erroring {
return
}
// Is it a Formatter?
if formatter, ok := p.field.(Formatter); ok {
handled = true

View file

@ -56,6 +56,7 @@ var (
stringVal string
stringVal1 string
bytesVal []byte
runeVal rune
complex64Val complex64
complex128Val complex128
renamedBoolVal renamedBool
@ -225,9 +226,9 @@ var scanfTests = []ScanfTest{
{"%v", "0377\n", &intVal, 0377},
{"%v", "0x44\n", &intVal, 0x44},
{"%d", "72\n", &intVal, 72},
{"%c", "a\n", &intVal, 'a'},
{"%c", "\u5072\n", &intVal, 0x5072},
{"%c", "\u1234\n", &intVal, '\u1234'},
{"%c", "a\n", &runeVal, 'a'},
{"%c", "\u5072\n", &runeVal, '\u5072'},
{"%c", "\u1234\n", &runeVal, '\u1234'},
{"%d", "73\n", &int8Val, int8(73)},
{"%d", "+74\n", &int16Val, int16(74)},
{"%d", "75\n", &int32Val, int32(75)},
@ -322,6 +323,7 @@ var s, t string
var c complex128
var x, y Xs
var z IntString
var r1, r2, r3 rune
var multiTests = []ScanfMultiTest{
{"", "", []interface{}{}, []interface{}{}, ""},
@ -333,7 +335,7 @@ var multiTests = []ScanfMultiTest{
{"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
{"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""},
{"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
// Custom scanners.
{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
@ -347,7 +349,7 @@ var multiTests = []ScanfMultiTest{
{"X%d", "10X", args(&intVal), nil, "input does not match format"},
// Bad UTF-8: should see every byte.
{"%c%c%c", "\xc2X\xc2", args(&i, &j, &k), args(utf8.RuneError, 'X', utf8.RuneError), ""},
{"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
}
func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {

View file

@ -466,7 +466,7 @@ func splitQuoted(s string) (r []string, err error) {
arg := make([]rune, len(s))
escaped := false
quoted := false
quote := rune(0)
quote := '\x00'
i := 0
for _, rune := range s {
switch {
@ -475,9 +475,9 @@ func splitQuoted(s string) (r []string, err error) {
case rune == '\\':
escaped = true
continue
case quote != 0:
case quote != '\x00':
if rune == quote {
quote = 0
quote = '\x00'
continue
}
case rune == '"' || rune == '\'':

View file

@ -281,7 +281,20 @@ func heading(line string) string {
return line
}
// Convert comment text to formatted HTML.
type op int
const (
opPara op = iota
opHead
opPre
)
type block struct {
op op
lines []string
}
// ToHTML converts comment text to formatted HTML.
// The comment was prepared by DocReader,
// so it is known not to have leading, trailing blank lines
// nor to have trailing spaces at the end of lines.
@ -299,20 +312,43 @@ func heading(line string) string {
// map value is not the empty string, it is considered a URL and the word is converted
// into a link.
func ToHTML(w io.Writer, text string, words map[string]string) {
inpara := false
lastWasBlank := false
lastWasHeading := false
close := func() {
if inpara {
for _, b := range blocks(text) {
switch b.op {
case opPara:
w.Write(html_p)
for _, line := range b.lines {
emphasize(w, line, words, true)
}
w.Write(html_endp)
inpara = false
case opHead:
w.Write(html_h)
for _, line := range b.lines {
commentEscape(w, line, true)
}
w.Write(html_endh)
case opPre:
w.Write(html_pre)
for _, line := range b.lines {
emphasize(w, line, nil, false)
}
w.Write(html_endpre)
}
}
open := func() {
if !inpara {
w.Write(html_p)
inpara = true
}
func blocks(text string) []block {
var (
out []block
para []string
lastWasBlank = false
lastWasHeading = false
)
close := func() {
if para != nil {
out = append(out, block{opPara, para})
para = nil
}
}
@ -340,17 +376,13 @@ func ToHTML(w io.Writer, text string, words map[string]string) {
for j > i && isBlank(lines[j-1]) {
j--
}
block := lines[i:j]
pre := lines[i:j]
i = j
unindent(block)
unindent(pre)
// put those lines in a pre block
w.Write(html_pre)
for _, line := range block {
emphasize(w, line, nil, false) // no nice text formatting
}
w.Write(html_endpre)
out = append(out, block{opPre, pre})
lastWasHeading = false
continue
}
@ -362,9 +394,7 @@ func ToHTML(w io.Writer, text string, words map[string]string) {
// might be a heading.
if head := heading(line); head != "" {
close()
w.Write(html_h)
commentEscape(w, head, true) // nice text formatting
w.Write(html_endh)
out = append(out, block{opHead, []string{head}})
i += 2
lastWasHeading = true
continue
@ -372,11 +402,95 @@ func ToHTML(w io.Writer, text string, words map[string]string) {
}
// open paragraph
open()
lastWasBlank = false
lastWasHeading = false
emphasize(w, lines[i], words, true) // nice text formatting
para = append(para, lines[i])
i++
}
close()
return out
}
// ToText prepares comment text for presentation in textual output.
// It wraps paragraphs of text to width or fewer Unicode code points
// and then prefixes each line with the indent. In preformatted sections
// (such as program text), it prefixes each non-blank line with preIndent.
func ToText(w io.Writer, text string, indent, preIndent string, width int) {
l := lineWrapper{
out: w,
width: width,
indent: indent,
}
for i, b := range blocks(text) {
switch b.op {
case opPara:
if i > 0 {
w.Write(nl)
}
for _, line := range b.lines {
l.write(line)
}
l.flush()
case opHead:
w.Write(nl)
for _, line := range b.lines {
l.write(line + "\n")
}
l.flush()
case opPre:
w.Write(nl)
for _, line := range b.lines {
if !isBlank(line) {
w.Write([]byte(preIndent))
w.Write([]byte(line))
}
}
}
}
}
type lineWrapper struct {
out io.Writer
printed bool
width int
indent string
n int
pendSpace int
}
var nl = []byte("\n")
var space = []byte(" ")
func (l *lineWrapper) write(text string) {
if l.n == 0 && l.printed {
l.out.Write(nl) // blank line before new paragraph
}
l.printed = true
for _, f := range strings.Fields(text) {
w := utf8.RuneCountInString(f)
// wrap if line is too long
if l.n > 0 && l.n+l.pendSpace+w > l.width {
l.out.Write(nl)
l.n = 0
l.pendSpace = 0
}
if l.n == 0 {
l.out.Write([]byte(l.indent))
}
l.out.Write(space[:l.pendSpace])
l.out.Write([]byte(f))
l.n += l.pendSpace + w
l.pendSpace = 1
}
}
func (l *lineWrapper) flush() {
if l.n == 0 {
return
}
l.out.Write(nl)
l.pendSpace = 0
l.n = 0
}

View file

@ -5,6 +5,7 @@
package doc
import (
"reflect"
"testing"
)
@ -38,3 +39,45 @@ func TestIsHeading(t *testing.T) {
}
}
}
var blocksTests = []struct {
in string
out []block
}{
{
in: `Para 1.
Para 1 line 2.
Para 2.
Section
Para 3.
pre
pre1
Para 4.
pre
pre2
`,
out: []block{
{opPara, []string{"Para 1.\n", "Para 1 line 2.\n"}},
{opPara, []string{"Para 2.\n"}},
{opHead, []string{"Section"}},
{opPara, []string{"Para 3.\n"}},
{opPre, []string{"pre\n", "pre1\n"}},
{opPara, []string{"Para 4.\n"}},
{opPre, []string{"pre\n", "pre2\n"}},
},
},
}
func TestBlocks(t *testing.T) {
for i, tt := range blocksTests {
b := blocks(tt.in)
if !reflect.DeepEqual(b, tt.out) {
t.Errorf("#%d: mismatch\nhave: %v\nwant: %v", i, b, tt.out)
}
}
}

View file

@ -8,15 +8,16 @@ package doc
import (
"go/ast"
"go/printer"
"strings"
"unicode"
"unicode/utf8"
)
type Example struct {
Name string // name of the item being demonstrated
Body *ast.BlockStmt // code
Output string // expected output
Name string // name of the item being demonstrated
Body *printer.CommentedNode // code
Output string // expected output
}
func Examples(pkg *ast.Package) []*Example {
@ -33,7 +34,7 @@ func Examples(pkg *ast.Package) []*Example {
}
examples = append(examples, &Example{
Name: name[len("Example"):],
Body: f.Body,
Body: &printer.CommentedNode{f.Body, src.Comments},
Output: CommentText(f.Doc),
})
}

View file

@ -807,13 +807,75 @@ func (p *printer) flush(next token.Position, tok token.Token) (droppedFF bool) {
return
}
// getNode returns the ast.CommentGroup associated with n, if any.
func getDoc(n ast.Node) *ast.CommentGroup {
switch n := n.(type) {
// *ast.Fields cannot be printed separately - ignore for now
case *ast.ImportSpec:
return n.Doc
case *ast.ValueSpec:
return n.Doc
case *ast.TypeSpec:
return n.Doc
case *ast.GenDecl:
return n.Doc
case *ast.FuncDecl:
return n.Doc
case *ast.File:
return n.Doc
}
return nil
}
func (p *printer) printNode(node interface{}) error {
// unpack *CommentedNode, if any
var comments []*ast.CommentGroup
if cnode, ok := node.(*CommentedNode); ok {
node = cnode.Node
comments = cnode.Comments
}
if comments != nil {
// commented node - restrict comment list to relevant range
n, ok := node.(ast.Node)
if !ok {
goto unsupported
}
beg := n.Pos()
end := n.End()
// if the node has associated documentation,
// include that commentgroup in the range
// (the comment list is sorted in the order
// of the comment appearance in the source code)
if doc := getDoc(n); doc != nil {
beg = doc.Pos()
}
// token.Pos values are global offsets, we can
// compare them directly
i := 0
for i < len(comments) && comments[i].End() < beg {
i++
}
j := i
for j < len(comments) && comments[j].Pos() < end {
j++
}
if i < j {
p.comments = comments[i:j]
}
} else if n, ok := node.(*ast.File); ok {
// use ast.File comments, if any
p.comments = n.Comments
}
// if there are no comments, use node comments
p.useNodeComments = p.comments == nil
// format node
switch n := node.(type) {
case ast.Expr:
p.useNodeComments = true
p.expr(n, ignoreMultiLine)
case ast.Stmt:
p.useNodeComments = true
// A labeled statement will un-indent to position the
// label. Set indent to 1 so we don't get indent "underflow".
if _, labeledStmt := n.(*ast.LabeledStmt); labeledStmt {
@ -821,19 +883,19 @@ func (p *printer) printNode(node interface{}) error {
}
p.stmt(n, false, ignoreMultiLine)
case ast.Decl:
p.useNodeComments = true
p.decl(n, ignoreMultiLine)
case ast.Spec:
p.useNodeComments = true
p.spec(n, 1, false, ignoreMultiLine)
case *ast.File:
p.comments = n.Comments
p.useNodeComments = n.Comments == nil
p.file(n)
default:
return fmt.Errorf("go/printer: unsupported node type %T", n)
goto unsupported
}
return nil
unsupported:
return fmt.Errorf("go/printer: unsupported node type %T", node)
}
// ----------------------------------------------------------------------------
@ -1001,10 +1063,18 @@ func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node interface{
return
}
// A CommentedNode bundles an AST node and corresponding comments.
// It may be provided as argument to any of the FPrint functions.
//
type CommentedNode struct {
Node interface{} // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt
Comments []*ast.CommentGroup
}
// Fprint "pretty-prints" an AST node to output for a given configuration cfg.
// Position information is interpreted relative to the file set fset.
// The node type must be *ast.File, or assignment-compatible to ast.Expr,
// ast.Decl, ast.Spec, or ast.Stmt.
// The node type must be *ast.File, *CommentedNode, or assignment-compatible
// to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt.
//
func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{}) error {
return cfg.fprint(output, fset, node, make(map[ast.Node]int))

View file

@ -107,7 +107,7 @@ func check(t *testing.T, source, golden string, mode checkMode) {
// start a timer to produce a time-out signal
tc := make(chan int)
go func() {
time.Sleep(10e9) // plenty of a safety margin, even for very slow machines
time.Sleep(10 * time.Second) // plenty of a safety margin, even for very slow machines
tc <- 0
}()

View file

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build 386 arm
package crc32
// The file contains the generic version of updateCastagnoli which just calls

View file

@ -4,7 +4,7 @@
package html
// Section 11.2.3.2 of the HTML5 specification says "The following elements
// Section 12.2.3.2 of the HTML5 specification says "The following elements
// have varying levels of special parsing rules".
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#the-stack-of-open-elements
var isSpecialElement = map[string]bool{

View file

@ -78,7 +78,7 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
i++
}
x := rune(0)
x := '\x00'
for i < len(s) {
c = s[i]
i++

56
libgo/go/html/foreign.go Normal file
View file

@ -0,0 +1,56 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package html
// Section 12.2.5.5.
var breakout = map[string]bool{
"b": true,
"big": true,
"blockquote": true,
"body": true,
"br": true,
"center": true,
"code": true,
"dd": true,
"div": true,
"dl": true,
"dt": true,
"em": true,
"embed": true,
"font": true,
"h1": true,
"h2": true,
"h3": true,
"h4": true,
"h5": true,
"h6": true,
"head": true,
"hr": true,
"i": true,
"img": true,
"li": true,
"listing": true,
"menu": true,
"meta": true,
"nobr": true,
"ol": true,
"p": true,
"pre": true,
"ruby": true,
"s": true,
"small": true,
"span": true,
"strong": true,
"strike": true,
"sub": true,
"sup": true,
"table": true,
"tt": true,
"u": true,
"ul": true,
"var": true,
}
// TODO: add look-up tables for MathML and SVG adjustments.

View file

@ -17,21 +17,22 @@ const (
scopeMarkerNode
)
// Section 11.2.3.3 says "scope markers are inserted when entering applet
// Section 12.2.3.3 says "scope markers are inserted when entering applet
// elements, buttons, object elements, marquees, table cells, and table
// captions, and are used to prevent formatting from 'leaking'".
var scopeMarker = Node{Type: scopeMarkerNode}
// A Node consists of a NodeType and some Data (tag name for element nodes,
// content for text) and are part of a tree of Nodes. Element nodes may also
// contain a slice of Attributes. Data is unescaped, so that it looks like
// "a<b" rather than "a&lt;b".
// have a Namespace and contain a slice of Attributes. Data is unescaped, so
// that it looks like "a<b" rather than "a&lt;b".
type Node struct {
Parent *Node
Child []*Node
Type NodeType
Data string
Attr []Attribute
Parent *Node
Child []*Node
Type NodeType
Data string
Namespace string
Attr []Attribute
}
// Add adds a node as a child of n.

View file

@ -22,12 +22,12 @@ type parser struct {
hasSelfClosingToken bool
// doc is the document root element.
doc *Node
// The stack of open elements (section 11.2.3.2) and active formatting
// elements (section 11.2.3.3).
// The stack of open elements (section 12.2.3.2) and active formatting
// elements (section 12.2.3.3).
oe, afe nodeStack
// Element pointers (section 11.2.3.4).
// Element pointers (section 12.2.3.4).
head, form *Node
// Other parsing state flags (section 11.2.3.5).
// Other parsing state flags (section 12.2.3.5).
scripting, framesetOK bool
// im is the current insertion mode.
im insertionMode
@ -35,12 +35,12 @@ type parser struct {
// or inTableText insertion mode.
originalIM insertionMode
// fosterParenting is whether new elements should be inserted according to
// the foster parenting rules (section 11.2.5.3).
// the foster parenting rules (section 12.2.5.3).
fosterParenting bool
// quirks is whether the parser is operating in "quirks mode."
quirks bool
// context is the context element when parsing an HTML fragment
// (section 11.4).
// (section 12.4).
context *Node
}
@ -51,7 +51,7 @@ func (p *parser) top() *Node {
return p.doc
}
// stopTags for use in popUntil. These come from section 11.2.3.2.
// stopTags for use in popUntil. These come from section 12.2.3.2.
var (
defaultScopeStopTags = []string{"applet", "caption", "html", "table", "td", "th", "marquee", "object"}
listItemScopeStopTags = []string{"applet", "caption", "html", "table", "td", "th", "marquee", "object", "ol", "ul"}
@ -130,7 +130,7 @@ func (p *parser) addChild(n *Node) {
}
// fosterParent adds a child node according to the foster parenting rules.
// Section 11.2.5.3, "foster parenting".
// Section 12.2.5.3, "foster parenting".
func (p *parser) fosterParent(n *Node) {
p.fosterParenting = false
var table, parent *Node
@ -192,20 +192,21 @@ func (p *parser) addText(text string) {
// addElement calls addChild with an element node.
func (p *parser) addElement(tag string, attr []Attribute) {
p.addChild(&Node{
Type: ElementNode,
Data: tag,
Attr: attr,
Type: ElementNode,
Data: tag,
Namespace: p.top().Namespace,
Attr: attr,
})
}
// Section 11.2.3.3.
// Section 12.2.3.3.
func (p *parser) addFormattingElement(tag string, attr []Attribute) {
p.addElement(tag, attr)
p.afe = append(p.afe, p.top())
// TODO.
}
// Section 11.2.3.3.
// Section 12.2.3.3.
func (p *parser) clearActiveFormattingElements() {
for {
n := p.afe.pop()
@ -215,7 +216,7 @@ func (p *parser) clearActiveFormattingElements() {
}
}
// Section 11.2.3.3.
// Section 12.2.3.3.
func (p *parser) reconstructActiveFormattingElements() {
n := p.afe.top()
if n == nil {
@ -265,12 +266,12 @@ func (p *parser) read() error {
return nil
}
// Section 11.2.4.
// Section 12.2.4.
func (p *parser) acknowledgeSelfClosingTag() {
p.hasSelfClosingToken = false
}
// An insertion mode (section 11.2.3.1) is the state transition function from
// An insertion mode (section 12.2.3.1) is the state transition function from
// a particular state in the HTML5 parser's state machine. It updates the
// parser's fields depending on parser.tok (where ErrorToken means EOF).
// It returns whether the token was consumed.
@ -278,7 +279,7 @@ type insertionMode func(*parser) bool
// setOriginalIM sets the insertion mode to return to after completing a text or
// inTableText insertion mode.
// Section 11.2.3.1, "using the rules for".
// Section 12.2.3.1, "using the rules for".
func (p *parser) setOriginalIM() {
if p.originalIM != nil {
panic("html: bad parser state: originalIM was set twice")
@ -286,7 +287,7 @@ func (p *parser) setOriginalIM() {
p.originalIM = p.im
}
// Section 11.2.3.1, "reset the insertion mode".
// Section 12.2.3.1, "reset the insertion mode".
func (p *parser) resetInsertionMode() {
for i := len(p.oe) - 1; i >= 0; i-- {
n := p.oe[i]
@ -318,7 +319,10 @@ func (p *parser) resetInsertionMode() {
case "html":
p.im = beforeHeadIM
default:
continue
if p.top().Namespace == "" {
continue
}
p.im = inForeignContentIM
}
return
}
@ -327,7 +331,7 @@ func (p *parser) resetInsertionMode() {
const whitespace = " \t\r\n\f"
// Section 11.2.5.4.1.
// Section 12.2.5.4.1.
func initialIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -354,7 +358,7 @@ func initialIM(p *parser) bool {
return false
}
// Section 11.2.5.4.2.
// Section 12.2.5.4.2.
func beforeHTMLIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -390,7 +394,7 @@ func beforeHTMLIM(p *parser) bool {
return false
}
// Section 11.2.5.4.3.
// Section 12.2.5.4.3.
func beforeHeadIM(p *parser) bool {
var (
add bool
@ -439,7 +443,7 @@ func beforeHeadIM(p *parser) bool {
return !implied
}
// Section 11.2.5.4.4.
// Section 12.2.5.4.4.
func inHeadIM(p *parser) bool {
var (
pop bool
@ -506,7 +510,7 @@ func inHeadIM(p *parser) bool {
return true
}
// Section 11.2.5.4.6.
// Section 12.2.5.4.6.
func afterHeadIM(p *parser) bool {
var (
add bool
@ -594,7 +598,7 @@ func copyAttributes(dst *Node, src Token) {
}
}
// Section 11.2.5.4.7.
// Section 12.2.5.4.7.
func inBodyIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
@ -730,6 +734,11 @@ func inBodyIM(p *parser) bool {
case "plaintext":
p.popUntil(buttonScopeStopTags, "p")
p.addElement(p.tok.Data, p.tok.Attr)
case "button":
p.popUntil(defaultScopeStopTags, "button")
p.reconstructActiveFormattingElements()
p.addElement(p.tok.Data, p.tok.Attr)
p.framesetOK = false
case "optgroup", "option":
if p.top().Data == "option" {
p.oe.pop()
@ -792,6 +801,21 @@ func inBodyIM(p *parser) bool {
p.reconstructActiveFormattingElements()
p.framesetOK = false
p.addElement(p.tok.Data, p.tok.Attr)
case "math", "svg":
p.reconstructActiveFormattingElements()
namespace := ""
if p.tok.Data == "math" {
// TODO: adjust MathML attributes.
namespace = "mathml"
} else {
// TODO: adjust SVG attributes.
namespace = "svg"
}
// TODO: adjust foreign attributes.
p.addElement(p.tok.Data, p.tok.Attr)
p.top().Namespace = namespace
p.im = inForeignContentIM
return true
case "caption", "col", "colgroup", "frame", "head", "tbody", "td", "tfoot", "th", "thead", "tr":
// Ignore the token.
default:
@ -970,7 +994,7 @@ func (p *parser) inBodyEndTagOther(tag string) {
}
}
// Section 11.2.5.4.8.
// Section 12.2.5.4.8.
func textIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -986,7 +1010,7 @@ func textIM(p *parser) bool {
return p.tok.Type == EndTagToken
}
// Section 11.2.5.4.9.
// Section 12.2.5.4.9.
func inTableIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1075,7 +1099,7 @@ func (p *parser) clearStackToContext(stopTags []string) {
}
}
// Section 11.2.5.4.11.
// Section 12.2.5.4.11.
func inCaptionIM(p *parser) bool {
switch p.tok.Type {
case StartTagToken:
@ -1115,7 +1139,7 @@ func inCaptionIM(p *parser) bool {
return inBodyIM(p)
}
// Section 11.2.5.4.12.
// Section 12.2.5.4.12.
func inColumnGroupIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1142,8 +1166,8 @@ func inColumnGroupIM(p *parser) bool {
case "colgroup":
if p.oe.top().Data != "html" {
p.oe.pop()
p.im = inTableIM
}
p.im = inTableIM
return true
case "col":
// Ignore the token.
@ -1152,12 +1176,13 @@ func inColumnGroupIM(p *parser) bool {
}
if p.oe.top().Data != "html" {
p.oe.pop()
p.im = inTableIM
return false
}
p.im = inTableIM
return false
return true
}
// Section 11.2.5.4.13.
// Section 12.2.5.4.13.
func inTableBodyIM(p *parser) bool {
var (
add bool
@ -1213,7 +1238,7 @@ func inTableBodyIM(p *parser) bool {
return inTableIM(p)
}
// Section 11.2.5.4.14.
// Section 12.2.5.4.14.
func inRowIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1272,7 +1297,7 @@ func inRowIM(p *parser) bool {
return inTableIM(p)
}
// Section 11.2.5.4.15.
// Section 12.2.5.4.15.
func inCellIM(p *parser) bool {
var (
closeTheCellAndReprocess bool
@ -1317,7 +1342,7 @@ func inCellIM(p *parser) bool {
return inBodyIM(p)
}
// Section 11.2.5.4.16.
// Section 12.2.5.4.16.
func inSelectIM(p *parser) bool {
endSelect := false
switch p.tok.Type {
@ -1394,7 +1419,7 @@ func inSelectIM(p *parser) bool {
return true
}
// Section 11.2.5.4.18.
// Section 12.2.5.4.18.
func afterBodyIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1424,7 +1449,7 @@ func afterBodyIM(p *parser) bool {
return false
}
// Section 11.2.5.4.19.
// Section 12.2.5.4.19.
func inFramesetIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1432,6 +1457,18 @@ func inFramesetIM(p *parser) bool {
Type: CommentNode,
Data: p.tok.Data,
})
case TextToken:
// Ignore all text but whitespace.
s := strings.Map(func(c rune) rune {
switch c {
case ' ', '\t', '\n', '\f', '\r':
return c
}
return -1
}, p.tok.Data)
if s != "" {
p.addText(s)
}
case StartTagToken:
switch p.tok.Data {
case "html":
@ -1462,7 +1499,7 @@ func inFramesetIM(p *parser) bool {
return true
}
// Section 11.2.5.4.20.
// Section 12.2.5.4.20.
func afterFramesetIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1470,6 +1507,18 @@ func afterFramesetIM(p *parser) bool {
Type: CommentNode,
Data: p.tok.Data,
})
case TextToken:
// Ignore all text but whitespace.
s := strings.Map(func(c rune) rune {
switch c {
case ' ', '\t', '\n', '\f', '\r':
return c
}
return -1
}, p.tok.Data)
if s != "" {
p.addText(s)
}
case StartTagToken:
switch p.tok.Data {
case "html":
@ -1489,7 +1538,7 @@ func afterFramesetIM(p *parser) bool {
return true
}
// Section 11.2.5.4.21.
// Section 12.2.5.4.21.
func afterAfterBodyIM(p *parser) bool {
switch p.tok.Type {
case ErrorToken:
@ -1512,7 +1561,7 @@ func afterAfterBodyIM(p *parser) bool {
return false
}
// Section 11.2.5.4.22.
// Section 12.2.5.4.22.
func afterAfterFramesetIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
@ -1533,6 +1582,37 @@ func afterAfterFramesetIM(p *parser) bool {
return true
}
// Section 12.2.5.5.
func inForeignContentIM(p *parser) bool {
switch p.tok.Type {
case CommentToken:
p.addChild(&Node{
Type: CommentNode,
Data: p.tok.Data,
})
case StartTagToken:
if breakout[p.tok.Data] {
// TODO.
}
switch p.top().Namespace {
case "mathml":
// TODO: adjust MathML attributes.
case "svg":
// TODO: adjust SVG tag names.
// TODO: adjust SVG attributes.
default:
panic("html: bad parser state: unexpected namespace")
}
// TODO: adjust foreign attributes.
p.addElement(p.tok.Data, p.tok.Attr)
case EndTagToken:
// TODO.
default:
// Ignore the token.
}
return true
}
func (p *parser) parse() error {
// Iterate until EOF. Any other error will cause an early return.
consumed := true

View file

@ -98,7 +98,11 @@ func dumpLevel(w io.Writer, n *Node, level int) error {
case DocumentNode:
return errors.New("unexpected DocumentNode")
case ElementNode:
fmt.Fprintf(w, "<%s>", n.Data)
if n.Namespace != "" {
fmt.Fprintf(w, "<%s %s>", n.Namespace, n.Data)
} else {
fmt.Fprintf(w, "<%s>", n.Data)
}
for _, a := range n.Attr {
io.WriteString(w, "\n")
dumpIndent(w, level+1)
@ -161,13 +165,14 @@ func TestParser(t *testing.T) {
n int
}{
// TODO(nigeltao): Process all the test cases from all the .dat files.
{"adoption01.dat", -1},
{"doctype01.dat", -1},
{"tests1.dat", -1},
{"tests2.dat", -1},
{"tests3.dat", -1},
{"tests4.dat", -1},
{"tests5.dat", -1},
{"tests6.dat", 7},
{"tests6.dat", 36},
}
for _, tf := range testFiles {
f, err := os.Open("testdata/webkit/" + tf.filename)

View file

@ -247,7 +247,7 @@ func writeQuoted(w writer, s string) error {
return nil
}
// Section 13.1.2, "Elements", gives this list of void elements. Void elements
// Section 12.1.2, "Elements", gives this list of void elements. Void elements
// are those that can't have any contents.
var voidElements = map[string]bool{
"area": true,

View file

@ -106,7 +106,7 @@ func isHex(c byte) bool {
// hexDecode decodes a short hex digit sequence: "10" -> 16.
func hexDecode(s []byte) rune {
n := rune(0)
n := '\x00'
for _, c := range s {
n <<= 4
switch {

View file

@ -654,7 +654,7 @@ func TestEscape(t *testing.T) {
for _, test := range tests {
tmpl := New(test.name)
// TODO: Move noescape into template/func.go
tmpl.Funcs(template.FuncMap{
tmpl.Funcs(FuncMap{
"noescape": func(a ...interface{}) string {
return fmt.Sprint(a...)
},
@ -792,7 +792,7 @@ func TestEscapeSet(t *testing.T) {
// pred is a template function that returns the predecessor of a
// natural number for testing recursive templates.
fns := template.FuncMap{"pred": func(a ...interface{}) (interface{}, error) {
fns := FuncMap{"pred": func(a ...interface{}) (interface{}, error) {
if len(a) == 1 {
if i, _ := a[0].(int); i > 0 {
return i - 1, nil

View file

@ -49,20 +49,28 @@ func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
// ExecuteTemplate applies the template associated with t that has the given
// name to the specified data object and writes the output to wr.
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) (err error) {
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
tmpl, err := t.lookupAndEscapeTemplate(wr, name)
if err != nil {
return err
}
return tmpl.text.Execute(wr, data)
}
// lookupAndEscapeTemplate guarantees that the template with the given name
// is escaped, or returns an error if it cannot be. It returns the named
// template.
func (t *Template) lookupAndEscapeTemplate(wr io.Writer, name string) (tmpl *Template, err error) {
t.nameSpace.mu.Lock()
tmpl := t.set[name]
defer t.nameSpace.mu.Unlock()
tmpl = t.set[name]
if (tmpl == nil) != (t.text.Lookup(name) == nil) {
panic("html/template internal error: template escaping out of sync")
}
if tmpl != nil && !tmpl.escaped {
err = escapeTemplates(tmpl, name)
}
t.nameSpace.mu.Unlock()
if err != nil {
return
}
return t.text.ExecuteTemplate(wr, name, data)
return tmpl, err
}
// Parse parses a string into a template. Nested template definitions
@ -146,12 +154,20 @@ func (t *Template) Name() string {
return t.text.Name()
}
// FuncMap is the type of the map defining the mapping from names to
// functions. Each function must have either a single return value, or two
// return values of which the second has type error. In that case, if the
// second (error) argument evaluates to non-nil during execution, execution
// terminates and Execute returns that error. FuncMap has the same base type
// as template.FuncMap, copied here so clients need not import "text/template".
type FuncMap map[string]interface{}
// Funcs adds the elements of the argument map to the template's function map.
// It panics if a value in the map is not a function with appropriate return
// type. However, it is legal to overwrite elements of the map. The return
// value is the template, so calls can be chained.
func (t *Template) Funcs(funcMap template.FuncMap) *Template {
t.text.Funcs(funcMap)
func (t *Template) Funcs(funcMap FuncMap) *Template {
t.text.Funcs(template.FuncMap(funcMap))
return t
}
@ -175,7 +191,9 @@ func (t *Template) Lookup(name string) *Template {
// Must panics if err is non-nil in the same way as template.Must.
func Must(t *Template, err error) *Template {
t.text = template.Must(t.text, err)
if err != nil {
panic(err)
}
return t
}

View file

@ -165,7 +165,7 @@ var pipeTests = []pipeTest{
}
func delayClose(t *testing.T, cl closer, ch chan int, tt pipeTest) {
time.Sleep(1e6) // 1 ms
time.Sleep(1 * time.Millisecond)
var err error
if tt.closeWithError {
err = cl.CloseWithError(tt.err)

View file

@ -9,7 +9,12 @@ package math
// Special cases are:
// Abs(±Inf) = +Inf
// Abs(NaN) = NaN
func libc_fabs(float64) float64 __asm__("fabs")
func Abs(x float64) float64 {
return libc_fabs(x)
}
func abs(x float64) float64 {
switch {
case x < 0:
return -x

View file

@ -1,7 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
func Abs(x float64) float64

View file

@ -36,6 +36,7 @@ package math
// Acosh(x) calculates the inverse hyperbolic cosine of x.
//
// Special cases are:
// Acosh(+Inf) = +Inf
// Acosh(x) = NaN if x < 1
// Acosh(NaN) = NaN
func Acosh(x float64) float64 {

View file

@ -958,6 +958,75 @@ var fabsSC = []float64{
NaN(),
}
var vffdimSC = [][2]float64{
{Inf(-1), Inf(-1)},
{Inf(-1), Inf(1)},
{Inf(-1), NaN()},
{Copysign(0, -1), Copysign(0, -1)},
{Copysign(0, -1), 0},
{0, Copysign(0, -1)},
{0, 0},
{Inf(1), Inf(-1)},
{Inf(1), Inf(1)},
{Inf(1), NaN()},
{NaN(), Inf(-1)},
{NaN(), Copysign(0, -1)},
{NaN(), 0},
{NaN(), Inf(1)},
{NaN(), NaN()},
}
var fdimSC = []float64{
NaN(),
0,
NaN(),
0,
0,
0,
0,
Inf(1),
NaN(),
NaN(),
NaN(),
NaN(),
NaN(),
NaN(),
NaN(),
}
var fmaxSC = []float64{
Inf(-1),
Inf(1),
NaN(),
Copysign(0, -1),
0,
0,
0,
Inf(1),
Inf(1),
Inf(1),
NaN(),
NaN(),
NaN(),
Inf(1),
NaN(),
}
var fminSC = []float64{
Inf(-1),
Inf(-1),
Inf(-1),
Copysign(0, -1),
Copysign(0, -1),
Copysign(0, -1),
0,
Inf(-1),
Inf(1),
NaN(),
Inf(-1),
NaN(),
NaN(),
NaN(),
NaN(),
}
var vffmodSC = [][2]float64{
{Inf(-1), Inf(-1)},
{Inf(-1), -Pi},
@ -1259,12 +1328,26 @@ var modfSC = [][2]float64{
}
var vfnextafterSC = [][2]float64{
{0, 0},
{0, Copysign(0, -1)},
{0, -1},
{0, NaN()},
{Copysign(0, -1), 1},
{Copysign(0, -1), 0},
{Copysign(0, -1), Copysign(0, -1)},
{Copysign(0, -1), -1},
{NaN(), 0},
{NaN(), NaN()},
}
var nextafterSC = []float64{
0,
0,
-4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
NaN(),
4.9406564584124654418e-324, // Float64frombits(0x0000000000000001)
Copysign(0, -1),
Copysign(0, -1),
-4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
NaN(),
NaN(),
}
@ -1875,6 +1958,11 @@ func TestDim(t *testing.T) {
t.Errorf("Dim(%g, %g) = %g, want %g", vf[i], 0.0, f, fdim[i])
}
}
for i := 0; i < len(vffdimSC); i++ {
if f := Dim(vffdimSC[i][0], vffdimSC[i][1]); !alike(fdimSC[i], f) {
t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i])
}
}
}
func TestFloor(t *testing.T) {
@ -1896,6 +1984,11 @@ func TestMax(t *testing.T) {
t.Errorf("Max(%g, %g) = %g, want %g", vf[i], ceil[i], f, ceil[i])
}
}
for i := 0; i < len(vffdimSC); i++ {
if f := Max(vffdimSC[i][0], vffdimSC[i][1]); !alike(fmaxSC[i], f) {
t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i])
}
}
}
func TestMin(t *testing.T) {
@ -1904,6 +1997,11 @@ func TestMin(t *testing.T) {
t.Errorf("Min(%g, %g) = %g, want %g", vf[i], floor[i], f, floor[i])
}
}
for i := 0; i < len(vffdimSC); i++ {
if f := Min(vffdimSC[i][0], vffdimSC[i][1]); !alike(fminSC[i], f) {
t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i])
}
}
}
func TestMod(t *testing.T) {
@ -1964,6 +2062,20 @@ func TestHypot(t *testing.T) {
}
}
func TestHypotGo(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := Abs(1e200 * tanh[i] * Sqrt(2))
if f := HypotGo(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
t.Errorf("HypotGo(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
}
}
for i := 0; i < len(vfhypotSC); i++ {
if f := HypotGo(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
t.Errorf("HypotGo(%g, %g) = %g, want %g", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
}
}
}
func TestIlogb(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := frexp[i].i - 1 // adjust because fr in the interval [½, 1)
@ -2175,7 +2287,7 @@ func TestNextafter(t *testing.T) {
t.Errorf("Nextafter(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter[i])
}
}
for i := 0; i < len(vfmodfSC); i++ {
for i := 0; i < len(vfnextafterSC); i++ {
if f := Nextafter(vfnextafterSC[i][0], vfnextafterSC[i][1]); !alike(nextafterSC[i], f) {
t.Errorf("Nextafter(%g, %g) = %g want %g", vfnextafterSC[i][0], vfnextafterSC[i][1], f, nextafterSC[i])
}

View file

@ -16,7 +16,12 @@ package math
// Special cases are:
// Asin(±0) = ±0
// Asin(x) = NaN if x < -1 or x > 1
func libc_asin(float64) float64 __asm__("asin")
func Asin(x float64) float64 {
return libc_asin(x)
}
func asin(x float64) float64 {
if x == 0 {
return x // special case
}
@ -46,4 +51,11 @@ func Asin(x float64) float64 {
//
// Special case is:
// Acos(x) = NaN if x < -1 or x > 1
func Acos(x float64) float64 { return Pi/2 - Asin(x) }
func libc_acos(float64) float64 __asm__("acos")
func Acos(x float64) float64 {
return libc_acos(x)
}
func acos(x float64) float64 {
return Pi/2 - Asin(x)
}

View file

@ -33,6 +33,7 @@ package math
// Asinh(x) calculates the inverse hyperbolic sine of x.
//
// Special cases are:
// Asinh(±0) = ±0
// Asinh(±Inf) = ±Inf
// Asinh(NaN) = NaN
func Asinh(x float64) float64 {

View file

@ -51,7 +51,12 @@ func satan(arg float64) float64 {
// Special cases are:
// Atan(±0) = ±0
// Atan(±Inf) = ±Pi/2
func libc_atan(float64) float64 __asm__("atan")
func Atan(x float64) float64 {
return libc_atan(x)
}
func atan(x float64) float64 {
if x == 0 {
return x
}

View file

@ -26,7 +26,12 @@ package math
// Atan2(y<0, -Inf) = -Pi
// Atan2(+Inf, x) = +Pi/2
// Atan2(-Inf, x) = -Pi/2
func libc_atan2(float64, float64) float64 __asm__("atan2")
func Atan2(y, x float64) float64 {
return libc_atan2(y, x)
}
func atan2(y, x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases

View file

@ -39,9 +39,10 @@ package math
// Atanh(x) calculates the inverse hyperbolic tangent of x.
//
// Special cases are:
// Atanh(x) = NaN if x < -1 or x > 1
// Atanh(1) = +Inf
// Atanh(±0) = ±0
// Atanh(-1) = -Inf
// Atanh(x) = NaN if x < -1 or x > 1
// Atanh(NaN) = NaN
func Atanh(x float64) float64 {
const NearZero = 1.0 / (1 << 28) // 2**-28

View file

@ -592,7 +592,7 @@ func (x nat) bitLen() int {
const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1
func hexValue(ch rune) Word {
d := MaxBase + 1 // illegal base
d := int(MaxBase + 1) // illegal base
switch {
case '0' <= ch && ch <= '9':
d = int(ch - '0')

View file

@ -49,5 +49,3 @@ const (
MaxUint32 = 1<<32 - 1
MaxUint64 = 1<<64 - 1
)
// BUG(rsc): The manual should define the special cases for all of these functions.

View file

@ -5,15 +5,45 @@
package math
// Dim returns the maximum of x-y or 0.
//
// Special cases are:
// Dim(+Inf, +Inf) = NaN
// Dim(-Inf, -Inf) = NaN
// Dim(x, NaN) = Dim(NaN, x) = NaN
func Dim(x, y float64) float64 {
if x > y {
return x - y
}
return 0
return dim(x, y)
}
func dim(x, y float64) float64 {
return max(x-y, 0)
}
// Max returns the larger of x or y.
//
// Special cases are:
// Max(x, +Inf) = Max(+Inf, x) = +Inf
// Max(x, NaN) = Max(NaN, x) = NaN
// Max(+0, ±0) = Max(±0, +0) = +0
// Max(-0, -0) = -0
func Max(x, y float64) float64 {
return max(x, y)
}
func max(x, y float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
switch {
case x > MaxFloat64 || y > MaxFloat64: // IsInf(x, 1) || IsInf(y, 1):
return Inf(1)
case x != x || y != y: // IsNaN(x) || IsNaN(y):
return NaN()
case x == 0 && x == y:
if Signbit(x) {
return y
}
return x
}
if x > y {
return x
}
@ -21,7 +51,30 @@ func Max(x, y float64) float64 {
}
// Min returns the smaller of x or y.
//
// Special cases are:
// Min(x, -Inf) = Min(-Inf, x) = -Inf
// Min(x, NaN) = Min(NaN, x) = NaN
// Min(-0, ±0) = Min(±0, -0) = -0
func Min(x, y float64) float64 {
return min(x, y)
}
func min(x, y float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
switch {
case x < -MaxFloat64 || y < -MaxFloat64: // IsInf(x, -1) || IsInf(y, -1):
return Inf(-1)
case x != x || y != y: // IsNaN(x) || IsNaN(y):
return NaN()
case x == 0 && x == y:
if Signbit(x) {
return x
}
return y
}
if x < y {
return x
}

View file

@ -1,9 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
func Dim(x, y float64) float64
func Max(x, y float64) float64
func Min(x, y float64) float64

View file

@ -11,4 +11,190 @@ package math
// Exp(NaN) = NaN
// Very large values overflow to 0 or +Inf.
// Very small values underflow to 1.
func Exp(x float64) float64 { return expGo(x) }
func libc_exp(float64) float64 __asm__("exp")
func Exp(x float64) float64 {
return libc_exp(x)
}
// The original C code, the long comment, and the constants
// below are from FreeBSD's /usr/src/lib/msun/src/e_exp.c
// and came with this notice. The go code is a simplified
// version of the original C.
//
// ====================================================
// Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
//
// Permission to use, copy, modify, and distribute this
// software is freely granted, provided that this notice
// is preserved.
// ====================================================
//
//
// exp(x)
// Returns the exponential of x.
//
// Method
// 1. Argument reduction:
// Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
// Given x, find r and integer k such that
//
// x = k*ln2 + r, |r| <= 0.5*ln2.
//
// Here r will be represented as r = hi-lo for better
// accuracy.
//
// 2. Approximation of exp(r) by a special rational function on
// the interval [0,0.34658]:
// Write
// R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
// We use a special Remes algorithm on [0,0.34658] to generate
// a polynomial of degree 5 to approximate R. The maximum error
// of this polynomial approximation is bounded by 2**-59. In
// other words,
// R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
// (where z=r*r, and the values of P1 to P5 are listed below)
// and
// | 5 | -59
// | 2.0+P1*z+...+P5*z - R(z) | <= 2
// | |
// The computation of exp(r) thus becomes
// 2*r
// exp(r) = 1 + -------
// R - r
// r*R1(r)
// = 1 + r + ----------- (for better accuracy)
// 2 - R1(r)
// where
// 2 4 10
// R1(r) = r - (P1*r + P2*r + ... + P5*r ).
//
// 3. Scale back to obtain exp(x):
// From step 1, we have
// exp(x) = 2**k * exp(r)
//
// Special cases:
// exp(INF) is INF, exp(NaN) is NaN;
// exp(-INF) is 0, and
// for finite argument, only exp(0)=1 is exact.
//
// Accuracy:
// according to an error analysis, the error is always less than
// 1 ulp (unit in the last place).
//
// Misc. info.
// For IEEE double
// if x > 7.09782712893383973096e+02 then exp(x) overflow
// if x < -7.45133219101941108420e+02 then exp(x) underflow
//
// Constants:
// The hexadecimal values are the intended ones for the following
// constants. The decimal values may be used, provided that the
// compiler will convert from decimal to binary accurately enough
// to produce the hexadecimal values shown.
func exp(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01
Ln2Lo = 1.90821492927058770002e-10
Log2e = 1.44269504088896338700e+00
Overflow = 7.09782712893383973096e+02
Underflow = -7.45133219101941108420e+02
NearZero = 1.0 / (1 << 28) // 2**-28
)
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
switch {
case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
return x
case x < -MaxFloat64: // IsInf(x, -1):
return 0
case x > Overflow:
return Inf(1)
case x < Underflow:
return 0
case -NearZero < x && x < NearZero:
return 1 + x
}
// reduce; computed as r = hi - lo for extra precision.
var k int
switch {
case x < 0:
k = int(Log2e*x - 0.5)
case x > 0:
k = int(Log2e*x + 0.5)
}
hi := x - float64(k)*Ln2Hi
lo := float64(k) * Ln2Lo
// compute
return expmulti(hi, lo, k)
}
// Exp2 returns 2**x, the base-2 exponential of x.
//
// Special cases are the same as Exp.
func Exp2(x float64) float64 {
return exp2(x)
}
func exp2(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01
Ln2Lo = 1.90821492927058770002e-10
Overflow = 1.0239999999999999e+03
Underflow = -1.0740e+03
)
// TODO: remove manual inlining of IsNaN and IsInf
// when compiler does it for us
// special cases
switch {
case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
return x
case x < -MaxFloat64: // IsInf(x, -1):
return 0
case x > Overflow:
return Inf(1)
case x < Underflow:
return 0
}
// argument reduction; x = r×lg(e) + k with |r| ≤ ln(2)/2.
// computed as r = hi - lo for extra precision.
var k int
switch {
case x > 0:
k = int(x + 0.5)
case x < 0:
k = int(x - 0.5)
}
t := x - float64(k)
hi := t * Ln2Hi
lo := -t * Ln2Lo
// compute
return expmulti(hi, lo, k)
}
// exp1 returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2.
func expmulti(hi, lo float64, k int) float64 {
const (
P1 = 1.66666666666666019037e-01 /* 0x3FC55555; 0x5555553E */
P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */
P3 = 6.61375632143793436117e-05 /* 0x3F11566A; 0xAF25DE2C */
P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08 /* 0x3E663769; 0x72BEA4D0 */
)
r := hi - lo
t := r * r
c := r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))))
y := 1 - ((lo - (r*c)/(2-c)) - hi)
// TODO(rsc): make sure Ldexp can handle boundary k
return Ldexp(y, k)
}

View file

@ -1,10 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
// Exp2 returns 2**x, the base-2 exponential of x.
//
// Special cases are the same as Exp.
func Exp2(x float64) float64 { return exp2Go(x) }

View file

@ -1,191 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
// The original C code, the long comment, and the constants
// below are from FreeBSD's /usr/src/lib/msun/src/e_exp.c
// and came with this notice. The go code is a simplified
// version of the original C.
//
// ====================================================
// Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
//
// Permission to use, copy, modify, and distribute this
// software is freely granted, provided that this notice
// is preserved.
// ====================================================
//
//
// exp(x)
// Returns the exponential of x.
//
// Method
// 1. Argument reduction:
// Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
// Given x, find r and integer k such that
//
// x = k*ln2 + r, |r| <= 0.5*ln2.
//
// Here r will be represented as r = hi-lo for better
// accuracy.
//
// 2. Approximation of exp(r) by a special rational function on
// the interval [0,0.34658]:
// Write
// R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
// We use a special Remes algorithm on [0,0.34658] to generate
// a polynomial of degree 5 to approximate R. The maximum error
// of this polynomial approximation is bounded by 2**-59. In
// other words,
// R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
// (where z=r*r, and the values of P1 to P5 are listed below)
// and
// | 5 | -59
// | 2.0+P1*z+...+P5*z - R(z) | <= 2
// | |
// The computation of exp(r) thus becomes
// 2*r
// exp(r) = 1 + -------
// R - r
// r*R1(r)
// = 1 + r + ----------- (for better accuracy)
// 2 - R1(r)
// where
// 2 4 10
// R1(r) = r - (P1*r + P2*r + ... + P5*r ).
//
// 3. Scale back to obtain exp(x):
// From step 1, we have
// exp(x) = 2**k * exp(r)
//
// Special cases:
// exp(INF) is INF, exp(NaN) is NaN;
// exp(-INF) is 0, and
// for finite argument, only exp(0)=1 is exact.
//
// Accuracy:
// according to an error analysis, the error is always less than
// 1 ulp (unit in the last place).
//
// Misc. info.
// For IEEE double
// if x > 7.09782712893383973096e+02 then exp(x) overflow
// if x < -7.45133219101941108420e+02 then exp(x) underflow
//
// Constants:
// The hexadecimal values are the intended ones for the following
// constants. The decimal values may be used, provided that the
// compiler will convert from decimal to binary accurately enough
// to produce the hexadecimal values shown.
// Exp returns e**x, the base-e exponential of x.
//
// Special cases are:
// Exp(+Inf) = +Inf
// Exp(NaN) = NaN
// Very large values overflow to 0 or +Inf.
// Very small values underflow to 1.
func expGo(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01
Ln2Lo = 1.90821492927058770002e-10
Log2e = 1.44269504088896338700e+00
Overflow = 7.09782712893383973096e+02
Underflow = -7.45133219101941108420e+02
NearZero = 1.0 / (1 << 28) // 2**-28
)
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
switch {
case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
return x
case x < -MaxFloat64: // IsInf(x, -1):
return 0
case x > Overflow:
return Inf(1)
case x < Underflow:
return 0
case -NearZero < x && x < NearZero:
return 1 + x
}
// reduce; computed as r = hi - lo for extra precision.
var k int
switch {
case x < 0:
k = int(Log2e*x - 0.5)
case x > 0:
k = int(Log2e*x + 0.5)
}
hi := x - float64(k)*Ln2Hi
lo := float64(k) * Ln2Lo
// compute
return exp(hi, lo, k)
}
// Exp2 returns 2**x, the base-2 exponential of x.
//
// Special cases are the same as Exp.
func exp2Go(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01
Ln2Lo = 1.90821492927058770002e-10
Overflow = 1.0239999999999999e+03
Underflow = -1.0740e+03
)
// TODO: remove manual inlining of IsNaN and IsInf
// when compiler does it for us
// special cases
switch {
case x != x || x > MaxFloat64: // IsNaN(x) || IsInf(x, 1):
return x
case x < -MaxFloat64: // IsInf(x, -1):
return 0
case x > Overflow:
return Inf(1)
case x < Underflow:
return 0
}
// argument reduction; x = r×lg(e) + k with |r| ≤ ln(2)/2.
// computed as r = hi - lo for extra precision.
var k int
switch {
case x > 0:
k = int(x + 0.5)
case x < 0:
k = int(x - 0.5)
}
t := x - float64(k)
hi := t * Ln2Hi
lo := -t * Ln2Lo
// compute
return exp(hi, lo, k)
}
// exp returns e**r × 2**k where r = hi - lo and |r| ≤ ln(2)/2.
func exp(hi, lo float64, k int) float64 {
const (
P1 = 1.66666666666666019037e-01 /* 0x3FC55555; 0x5555553E */
P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */
P3 = 6.61375632143793436117e-05 /* 0x3F11566A; 0xAF25DE2C */
P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08 /* 0x3E663769; 0x72BEA4D0 */
)
r := hi - lo
t := r * r
c := r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))))
y := 1 - ((lo - (r*c)/(2-c)) - hi)
// TODO(rsc): make sure Ldexp can handle boundary k
return Ldexp(y, k)
}

View file

@ -1,10 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
// Make expGo and exp2Go available for testing.
func ExpGo(x float64) float64 { return expGo(x) }
func Exp2Go(x float64) float64 { return exp2Go(x) }

View file

@ -121,7 +121,12 @@ package math
// Expm1(-Inf) = -1
// Expm1(NaN) = NaN
// Very large values overflow to -1 or +Inf.
func libc_expm1(float64) float64 __asm__("expm1")
func Expm1(x float64) float64 {
return libc_expm1(x)
}
func expm1(x float64) float64 {
const (
Othreshold = 7.09782712893383973096e+02 // 0x40862E42FEFA39EF
Ln2X56 = 3.88162421113569373274e+01 // 0x4043687a9f1af2b1

View file

@ -0,0 +1,11 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
// Export internal functions for testing.
var ExpGo = exp
var Exp2Go = exp2
var HypotGo = hypot
var SqrtGo = sqrt

View file

@ -7,9 +7,15 @@ package math
// Floor returns the greatest integer value less than or equal to x.
//
// Special cases are:
// Floor(±0) = ±0
// Floor(±Inf) = ±Inf
// Floor(NaN) = NaN
func libc_floor(float64) float64 __asm__("floor")
func Floor(x float64) float64 {
return libc_floor(x)
}
func floor(x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
if x == 0 || x != x || x > MaxFloat64 || x < -MaxFloat64 { // x == 0 || IsNaN(x) || IsInf(x, 0)
@ -29,16 +35,30 @@ func Floor(x float64) float64 {
// Ceil returns the least integer value greater than or equal to x.
//
// Special cases are:
// Ceil(±0) = ±0
// Ceil(±Inf) = ±Inf
// Ceil(NaN) = NaN
func Ceil(x float64) float64 { return -Floor(-x) }
func libc_ceil(float64) float64 __asm__("ceil")
func Ceil(x float64) float64 {
return libc_ceil(x)
}
func ceil(x float64) float64 {
return -Floor(-x)
}
// Trunc returns the integer value of x.
//
// Special cases are:
// Trunc(±0) = ±0
// Trunc(±Inf) = ±Inf
// Trunc(NaN) = NaN
func libc_trunc(float64) float64 __asm__("trunc")
func Trunc(x float64) float64 {
return libc_trunc(x)
}
func trunc(x float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
if x == 0 || x != x || x > MaxFloat64 || x < -MaxFloat64 { // x == 0 || IsNaN(x) || IsInf(x, 0)

View file

@ -14,6 +14,10 @@ package math
// Frexp(±Inf) = ±Inf, 0
// Frexp(NaN) = NaN, 0
func Frexp(f float64) (frac float64, exp int) {
return frexp(f)
}
func frexp(f float64) (frac float64, exp int) {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases

View file

@ -15,6 +15,10 @@ package math
// Hypot(p, q) = +Inf if p or q is infinite
// Hypot(p, q) = NaN if p or q is NaN
func Hypot(p, q float64) float64 {
return hypot(p, q)
}
func hypot(p, q float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases

View file

@ -1,63 +0,0 @@
// Copyright 2009-2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
/*
Hypot -- sqrt(p*p + q*q), but overflows only if the result does.
See:
Cleve Moler and Donald Morrison,
Replacing Square Roots by Pythagorean Sums
IBM Journal of Research and Development,
Vol. 27, Number 6, pp. 577-581, Nov. 1983
*/
// Hypot computes Sqrt(p*p + q*q), taking care to avoid
// unnecessary overflow and underflow.
//
// Special cases are:
// Hypot(p, q) = +Inf if p or q is infinite
// Hypot(p, q) = NaN if p or q is NaN
func hypotGo(p, q float64) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases
switch {
case p < -MaxFloat64 || p > MaxFloat64 || q < -MaxFloat64 || q > MaxFloat64: // IsInf(p, 0) || IsInf(q, 0):
return Inf(1)
case p != p || q != q: // IsNaN(p) || IsNaN(q):
return NaN()
}
if p < 0 {
p = -p
}
if q < 0 {
q = -q
}
if p < q {
p, q = q, p
}
if p == 0 {
return 0
}
pfac := p
q = q / p
r := q
p = 1
for {
r = r * r
s := r + 4
if s == 4 {
return p * pfac
}
r = r / s
p = p + 2*r*p
q = q * r
r = q / p
}
panic("unreachable")
}

View file

@ -1,9 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
// Make hypotGo available for testing.
func HypotGo(x, y float64) float64 { return hypotGo(x, y) }

View file

@ -11,7 +11,12 @@ package math
// Ldexp(±0, exp) = ±0
// Ldexp(±Inf, exp) = ±Inf
// Ldexp(NaN, exp) = NaN
func libc_ldexp(float64, int) float64 __asm__("ldexp")
func Ldexp(frac float64, exp int) float64 {
return libc_ldexp(frac, exp)
}
func ldexp(frac float64, exp int) float64 {
// TODO(rsc): Remove manual inlining of IsNaN, IsInf
// when compiler does it for us
// special cases

View file

@ -77,7 +77,12 @@ package math
// Log(0) = -Inf
// Log(x < 0) = NaN
// Log(NaN) = NaN
func libc_log(float64) float64 __asm__("log")
func Log(x float64) float64 {
return libc_log(x)
}
func log(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01 /* 3fe62e42 fee00000 */
Ln2Lo = 1.90821492927058770002e-10 /* 3dea39ef 35793c76 */

View file

@ -6,8 +6,22 @@ package math
// Log10 returns the decimal logarithm of x.
// The special cases are the same as for Log.
func Log10(x float64) float64 { return Log(x) * (1 / Ln10) }
func libc_log10(float64) float64 __asm__("log10")
func Log10(x float64) float64 {
return libc_log10(x)
}
func log10(x float64) float64 {
return Log(x) * (1 / Ln10)
}
// Log2 returns the binary logarithm of x.
// The special cases are the same as for Log.
func Log2(x float64) float64 { return Log(x) * (1 / Ln2) }
func libc_log2(float64) float64 __asm__("log2")
func Log2(x float64) float64 {
return libc_log2(x)
}
func log2(x float64) float64 {
return Log(x) * (1 / Ln2)
}

View file

@ -1,8 +0,0 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package math
func Log10(x float64) float64
func Log2(x float64) float64

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