diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | loader/goroot.go | 1 | ||||
-rw-r--r-- | src/internal/itoa/README.md | 2 | ||||
-rw-r--r-- | src/internal/itoa/itoa.go | 33 | ||||
-rw-r--r-- | src/internal/itoa/itoa_test.go | 40 | ||||
-rw-r--r-- | src/net/ip.go | 7 | ||||
-rw-r--r-- | src/net/parse.go | 18 | ||||
-rw-r--r-- | src/syscall/errno.go | 4 | ||||
-rw-r--r-- | src/syscall/str.go | 19 |
9 files changed, 85 insertions, 40 deletions
@@ -216,6 +216,7 @@ TEST_PACKAGES = \ hash/crc64 \ html \ index/suffixarray \ + internal/itoa \ math \ math/cmplx \ net/mail \ diff --git a/loader/goroot.go b/loader/goroot.go index 8f0acf1b8..88b467605 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -228,6 +228,7 @@ func pathsToOverride(needsSyscallPackage bool) map[string]bool { "internal/bytealg/": false, "internal/reflectlite/": false, "internal/task/": false, + "internal/itoa/": false, // TODO: Remove when we drop support for go 1.16 "machine/": false, "net/": true, "os/": true, diff --git a/src/internal/itoa/README.md b/src/internal/itoa/README.md new file mode 100644 index 000000000..6b666d121 --- /dev/null +++ b/src/internal/itoa/README.md @@ -0,0 +1,2 @@ +internal/itoa is new to go as of 1.17. +This directory should be removed when tinygo drops support for go 1.16. diff --git a/src/internal/itoa/itoa.go b/src/internal/itoa/itoa.go new file mode 100644 index 000000000..c6062d9fe --- /dev/null +++ b/src/internal/itoa/itoa.go @@ -0,0 +1,33 @@ +// Copyright 2021 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. + +// Simple conversions to avoid depending on strconv. + +package itoa + +// Itoa converts val to a decimal string. +func Itoa(val int) string { + if val < 0 { + return "-" + Uitoa(uint(-val)) + } + return Uitoa(uint(val)) +} + +// Uitoa converts val to a decimal string. +func Uitoa(val uint) string { + if val == 0 { // avoid string allocation + return "0" + } + var buf [20]byte // big enough for 64bit value base 10 + i := len(buf) - 1 + for val >= 10 { + q := val / 10 + buf[i] = byte('0' + val - q*10) + i-- + val = q + } + // val < 10 + buf[i] = byte('0' + val) + return string(buf[i:]) +} diff --git a/src/internal/itoa/itoa_test.go b/src/internal/itoa/itoa_test.go new file mode 100644 index 000000000..71931c1e3 --- /dev/null +++ b/src/internal/itoa/itoa_test.go @@ -0,0 +1,40 @@ +// Copyright 2021 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 itoa_test + +import ( + "fmt" + "internal/itoa" + "math" + "testing" +) + +var ( + minInt64 int64 = math.MinInt64 + maxInt64 int64 = math.MaxInt64 + maxUint64 uint64 = math.MaxUint64 +) + +func TestItoa(t *testing.T) { + tests := []int{int(minInt64), math.MinInt32, -999, -100, -1, 0, 1, 100, 999, math.MaxInt32, int(maxInt64)} + for _, tt := range tests { + got := itoa.Itoa(tt) + want := fmt.Sprint(tt) + if want != got { + t.Fatalf("Itoa(%d) = %s, want %s", tt, got, want) + } + } +} + +func TestUitoa(t *testing.T) { + tests := []uint{0, 1, 100, 999, math.MaxUint32, uint(maxUint64)} + for _, tt := range tests { + got := itoa.Uitoa(tt) + want := fmt.Sprint(tt) + if want != got { + t.Fatalf("Uitoa(%d) = %s, want %s", tt, got, want) + } + } +} diff --git a/src/net/ip.go b/src/net/ip.go index c672ff490..5f78fcc3a 100644 --- a/src/net/ip.go +++ b/src/net/ip.go @@ -14,7 +14,10 @@ package net -import "internal/bytealg" +import ( + "internal/bytealg" + "internal/itoa" +) // IP address lengths (bytes). const ( @@ -533,7 +536,7 @@ func (n *IPNet) String() string { if l == -1 { return nn.String() + "/" + m.String() } - return nn.String() + "/" + uitoa(uint(l)) + return nn.String() + "/" + itoa.Uitoa(uint(l)) } // Parse IPv4 address (d.d.d.d). diff --git a/src/net/parse.go b/src/net/parse.go index 2a840c854..f1f2ccb5c 100644 --- a/src/net/parse.go +++ b/src/net/parse.go @@ -64,24 +64,6 @@ func xtoi2(s string, e byte) (byte, bool) { return byte(n), ok && ei == 2 } -// Convert unsigned integer to decimal string. -func uitoa(val uint) string { - if val == 0 { // avoid string allocation - return "0" - } - var buf [20]byte // big enough for 64bit value base 10 - i := len(buf) - 1 - for val >= 10 { - q := val / 10 - buf[i] = byte('0' + val - q*10) - i-- - val = q - } - // val < 10 - buf[i] = byte('0' + val) - return string(buf[i:]) -} - // Convert i to a hexadecimal string. Leading zeros are not printed. func appendHex(dst []byte, i uint32) []byte { if i == 0 { diff --git a/src/syscall/errno.go b/src/syscall/errno.go index b67a685c8..ec6cc1fb8 100644 --- a/src/syscall/errno.go +++ b/src/syscall/errno.go @@ -1,5 +1,7 @@ package syscall +import "internal/itoa" + // Most code here has been copied from the Go sources: // https://github.com/golang/go/blob/go1.12/src/syscall/syscall_js.go // It has the following copyright note: @@ -18,7 +20,7 @@ package syscall type Errno uintptr func (e Errno) Error() string { - return "errno " + itoa(int(e)) + return "errno " + itoa.Itoa(int(e)) } func (e Errno) Temporary() bool { diff --git a/src/syscall/str.go b/src/syscall/str.go index ea5356d0e..b73490a20 100644 --- a/src/syscall/str.go +++ b/src/syscall/str.go @@ -4,25 +4,6 @@ package syscall -func itoa(val int) string { // do it here rather than with fmt to avoid dependency - if val < 0 { - return "-" + uitoa(uint(-val)) - } - return uitoa(uint(val)) -} - -func uitoa(val uint) string { - var buf [32]byte // big enough for int64 - i := len(buf) - 1 - for val >= 10 { - buf[i] = byte(val%10 + '0') - i-- - val /= 10 - } - buf[i] = byte(val + '0') - return string(buf[i:]) -} - // clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte. func clen(n []byte) int { for i := 0; i < len(n); i++ { |