gofront 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/package.json +10 -38
- package/src/backend/js/expressions.js +2060 -389
- package/src/backend/js/index.js +586 -174
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +936 -1644
- package/src/backend/js/statements.js +1349 -132
- package/src/backend/js/stdlib/index.js +51 -94
- package/src/backend/js/templ.js +67 -118
- package/src/backend/js/type-info.js +436 -0
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +80 -0
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +753 -872
- package/src/backend/wasm/emit-builtins.js +914 -237
- package/src/backend/wasm/emit-exprs.js +1456 -195
- package/src/backend/wasm/emit-maps.js +78 -380
- package/src/backend/wasm/emit-stmts.js +1659 -214
- package/src/backend/wasm/emit.js +614 -88
- package/src/backend/wasm/encode.js +43 -13
- package/src/backend/wasm/globals.js +491 -0
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +406 -3195
- package/src/backend/wasm/method-expr.js +392 -0
- package/src/backend/wasm/module-emitter.js +1615 -0
- package/src/backend/wasm/monomorph.js +164 -9
- package/src/backend/wasm/natives.js +596 -0
- package/src/backend/wasm/prescan.js +249 -0
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -37
- package/src/backend/wasm/stdlib/simd.js +293 -28
- package/src/backend/wasm/types.js +260 -27
- package/src/backend/wasm/variadic.js +93 -0
- package/src/backend/wasm/wat.js +47 -20
- package/src/{cli-core.js → cli/cli-core.js} +241 -11
- package/src/{test-runner.js → cli/test-runner.js} +188 -122
- package/src/{vendor.js → cli/vendor.js} +3 -4
- package/src/compiler.js +202 -386
- package/src/index.js +15 -169
- package/src/{lexer.js → lexer/lexer.js} +203 -62
- package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
- package/src/{tokens.js → lexer/tokens.js} +2 -0
- package/src/link/sourcemap.js +97 -0
- package/src/link/stdlib.js +737 -0
- package/src/link/type-names.js +148 -0
- package/src/link/wasm.js +318 -0
- package/src/lower/bounds.js +547 -0
- package/src/lower/boxing.js +1 -1
- package/src/lower/captures.js +267 -64
- package/src/lower/embedding.js +32 -3
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +905 -0
- package/src/lower/functions.js +2 -0
- package/src/lower/gen-types.js +274 -0
- package/src/lower/index.js +33 -19
- package/src/lower/json-codecs.js +1379 -0
- package/src/lower/ownership.js +47 -8
- package/src/lower/range.js +86 -1
- package/src/lower/reachability.js +150 -0
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +83 -15
- package/src/parser/expressions.js +110 -18
- package/src/parser/index.js +2 -1
- package/src/parser/statements.js +38 -22
- package/src/{templ-parser.js → parser/templ.js} +179 -17
- package/src/parser/types.js +70 -9
- package/src/resolver.js +21 -1
- package/src/typechecker/assignability.js +291 -19
- package/src/typechecker/const-fold.js +399 -0
- package/src/typechecker/constants.js +282 -0
- package/src/typechecker/expressions.js +1220 -183
- package/src/typechecker/index.js +659 -92
- package/src/typechecker/init-order.js +426 -0
- package/src/typechecker/operand-text.js +40 -0
- package/src/typechecker/resolve.js +613 -62
- package/src/typechecker/statements.js +212 -20
- package/src/typechecker/stdlib/excluded.js +902 -0
- package/src/typechecker/stdlib/index.js +38 -0
- package/src/typechecker/stdlib/simd.js +65 -15
- package/src/typechecker/termination.js +11 -2
- package/src/typechecker/types.js +268 -514
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/cmp/cmp.go +65 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/errors.go +31 -0
- package/stdlib/encoding/json/indent.go +71 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/encoding/json/number.go +12 -0
- package/stdlib/encoding/json/stream.go +173 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/hash/hash.go +53 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +871 -0
- package/stdlib/internal/jsonrt/enc.go +516 -0
- package/stdlib/internal/jsonrt/indent.go +135 -0
- package/stdlib/internal/jsonrt/number.go +27 -0
- package/stdlib/internal/jsonrt/reader.go +73 -0
- package/stdlib/internal/jsonrt/scanner.go +658 -0
- package/stdlib/io/io.go +502 -0
- package/stdlib/iter/iter.go +18 -0
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +272 -0
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +500 -0
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +526 -0
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +250 -0
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -46
- package/src/backend/js/stdlib/builder.js +0 -63
- package/src/backend/js/stdlib/bytes.js +0 -122
- package/src/backend/js/stdlib/errors.js +0 -44
- package/src/backend/js/stdlib/fmt.js +0 -178
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -972
- package/src/backend/js/stdlib/maps.js +0 -45
- package/src/backend/js/stdlib/math.js +0 -69
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -24
- package/src/backend/js/stdlib/slices.js +0 -77
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -74
- package/src/backend/js/stdlib/strings.js +0 -222
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -34
- package/src/backend/js/stdlib/time.js +0 -128
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/const-fold.js +0 -205
- package/src/backend/wasm/emit-stdlib.js +0 -13
- package/src/backend/wasm/stdlib/bytes.js +0 -5039
- package/src/backend/wasm/stdlib/core.js +0 -8903
- package/src/backend/wasm/stdlib/io.js +0 -2161
- package/src/backend/wasm/stdlib/packages.js +0 -2400
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -1200
- package/src/typechecker/stdlib/core.js +0 -801
- package/src/typechecker/stdlib/extended.js +0 -914
- package/src/typechecker/stdlib.js +0 -22
- /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
- /package/src/{colors.js → cli/colors.js} +0 -0
- /package/src/{dev-server.js → cli/dev-server.js} +0 -0
- /package/src/{minifier.js → cli/minifier.js} +0 -0
- /package/src/{project-config.js → cli/project-config.js} +0 -0
- /package/src/{pwa.js → cli/pwa.js} +0 -0
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
// Copyright 2009 The Go Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
//go:build gofront
|
|
6
|
+
|
|
7
|
+
//gofront:target both
|
|
8
|
+
|
|
9
|
+
package fmt
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"strconv"
|
|
13
|
+
"unicode/utf8"
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
const (
|
|
17
|
+
ldigits = "0123456789abcdefx"
|
|
18
|
+
udigits = "0123456789ABCDEFX"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const (
|
|
22
|
+
signed = true
|
|
23
|
+
unsigned = false
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
// fmtFlags is the set of flags a verb carries.
|
|
27
|
+
type fmtFlags struct {
|
|
28
|
+
widPresent bool
|
|
29
|
+
precPresent bool
|
|
30
|
+
minus bool
|
|
31
|
+
plus bool
|
|
32
|
+
sharp bool
|
|
33
|
+
space bool
|
|
34
|
+
zero bool
|
|
35
|
+
|
|
36
|
+
// For the formats %+v %#v, we set the plusV/sharpV flags and clear the
|
|
37
|
+
// plus/sharp flags since %+v and %#v are in effect different, flagless
|
|
38
|
+
// formats set at the top level.
|
|
39
|
+
plusV bool
|
|
40
|
+
sharpV bool
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// fmtState is the part of the printer that lays out one value in a buffer. It
|
|
44
|
+
// holds the flags of fmtFlags directly: an embedded struct would be renamed
|
|
45
|
+
// with its type when the package is linked.
|
|
46
|
+
type fmtState struct {
|
|
47
|
+
// buf is the output buffer: its length is the capacity and n the bytes
|
|
48
|
+
// written, so an append is an indexed store, not a new slice value.
|
|
49
|
+
buf []byte
|
|
50
|
+
n int
|
|
51
|
+
|
|
52
|
+
widPresent bool
|
|
53
|
+
precPresent bool
|
|
54
|
+
minus bool
|
|
55
|
+
plus bool
|
|
56
|
+
sharp bool
|
|
57
|
+
space bool
|
|
58
|
+
zero bool
|
|
59
|
+
plusV bool
|
|
60
|
+
sharpV bool
|
|
61
|
+
|
|
62
|
+
wid int
|
|
63
|
+
prec int
|
|
64
|
+
intbuf []byte
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// grow makes room for need more bytes.
|
|
68
|
+
func (f *fmtState) grow(need int) {
|
|
69
|
+
size := 2 * len(f.buf)
|
|
70
|
+
if size < f.n+need {
|
|
71
|
+
size = f.n + need
|
|
72
|
+
}
|
|
73
|
+
nb := make([]byte, size)
|
|
74
|
+
copy(nb, f.buf[:f.n])
|
|
75
|
+
f.buf = nb
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// scratch returns the 68-byte buffer numbers and quotes are built in.
|
|
79
|
+
func (f *fmtState) scratch() []byte {
|
|
80
|
+
if f.intbuf == nil {
|
|
81
|
+
f.intbuf = make([]byte, 68)
|
|
82
|
+
}
|
|
83
|
+
return f.intbuf
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
func (f *fmtState) putByte(c byte) {
|
|
87
|
+
if f.n == len(f.buf) {
|
|
88
|
+
f.grow(1)
|
|
89
|
+
}
|
|
90
|
+
f.buf[f.n] = c
|
|
91
|
+
f.n++
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
func (f *fmtState) putBytes(b []byte) {
|
|
95
|
+
n := len(b)
|
|
96
|
+
if f.n+n > len(f.buf) {
|
|
97
|
+
f.grow(n)
|
|
98
|
+
}
|
|
99
|
+
buf, k := f.buf, f.n
|
|
100
|
+
for i := 0; i < n; i++ {
|
|
101
|
+
buf[k+i] = b[i]
|
|
102
|
+
}
|
|
103
|
+
f.n = k + n
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// putString appends s. An ASCII string is stored byte by byte; any other goes
|
|
107
|
+
// through the encoder.
|
|
108
|
+
func (f *fmtState) putString(s string) {
|
|
109
|
+
n := len(s)
|
|
110
|
+
if f.n+n > len(f.buf) {
|
|
111
|
+
f.grow(n)
|
|
112
|
+
}
|
|
113
|
+
buf, k := f.buf, f.n
|
|
114
|
+
for _, r := range s {
|
|
115
|
+
if r >= 0x80 {
|
|
116
|
+
f.putBytes([]byte(s))
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
buf[k] = byte(r)
|
|
120
|
+
k++
|
|
121
|
+
}
|
|
122
|
+
f.n = k
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// bytes returns what has been written.
|
|
126
|
+
func (f *fmtState) bytes() []byte {
|
|
127
|
+
return f.buf[:f.n]
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
func (f *fmtState) clearflags() {
|
|
131
|
+
f.restoreFlags(fmtFlags{})
|
|
132
|
+
f.wid = 0
|
|
133
|
+
f.prec = 0
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// saveFlags returns the flags of the verb being formatted.
|
|
137
|
+
func (f *fmtState) saveFlags() fmtFlags {
|
|
138
|
+
return fmtFlags{f.widPresent, f.precPresent, f.minus, f.plus, f.sharp, f.space, f.zero, f.plusV, f.sharpV}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// restoreFlags sets the flags saved by saveFlags.
|
|
142
|
+
func (f *fmtState) restoreFlags(s fmtFlags) {
|
|
143
|
+
f.widPresent = s.widPresent
|
|
144
|
+
f.precPresent = s.precPresent
|
|
145
|
+
f.minus = s.minus
|
|
146
|
+
f.plus = s.plus
|
|
147
|
+
f.sharp = s.sharp
|
|
148
|
+
f.space = s.space
|
|
149
|
+
f.zero = s.zero
|
|
150
|
+
f.plusV = s.plusV
|
|
151
|
+
f.sharpV = s.sharpV
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// writePadding appends n padding bytes.
|
|
155
|
+
func (f *fmtState) writePadding(n int) {
|
|
156
|
+
if n <= 0 {
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
padByte := byte(' ')
|
|
160
|
+
// Zero padding is allowed only to the left.
|
|
161
|
+
if f.zero && !f.minus {
|
|
162
|
+
padByte = byte('0')
|
|
163
|
+
}
|
|
164
|
+
for i := 0; i < n; i++ {
|
|
165
|
+
f.putByte(padByte)
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// pad appends b to f.buf, padded on left (!f.minus) or right (f.minus).
|
|
170
|
+
func (f *fmtState) pad(b []byte) {
|
|
171
|
+
if !f.widPresent || f.wid == 0 {
|
|
172
|
+
f.putBytes(b)
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
width := f.wid - utf8.RuneCount(b)
|
|
176
|
+
if !f.minus {
|
|
177
|
+
// left padding
|
|
178
|
+
f.writePadding(width)
|
|
179
|
+
f.putBytes(b)
|
|
180
|
+
} else {
|
|
181
|
+
// right padding
|
|
182
|
+
f.putBytes(b)
|
|
183
|
+
f.writePadding(width)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// padString appends s to f.buf, padded on left (!f.minus) or right (f.minus).
|
|
188
|
+
func (f *fmtState) padString(s string) {
|
|
189
|
+
if !f.widPresent || f.wid == 0 {
|
|
190
|
+
f.putString(s)
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
width := f.wid - utf8.RuneCountInString(s)
|
|
194
|
+
if !f.minus {
|
|
195
|
+
// left padding
|
|
196
|
+
f.writePadding(width)
|
|
197
|
+
f.putString(s)
|
|
198
|
+
} else {
|
|
199
|
+
// right padding
|
|
200
|
+
f.putString(s)
|
|
201
|
+
f.writePadding(width)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// fmtBoolean formats a boolean.
|
|
206
|
+
func (f *fmtState) fmtBoolean(v bool) {
|
|
207
|
+
if v {
|
|
208
|
+
f.padString("true")
|
|
209
|
+
} else {
|
|
210
|
+
f.padString("false")
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// fmtUnicode formats a uint64 as "U+0078" or with f.sharp set as "U+0078 'x'".
|
|
215
|
+
func (f *fmtState) fmtUnicode(u uint64) {
|
|
216
|
+
buf := f.scratch()[0:]
|
|
217
|
+
|
|
218
|
+
// With default precision set the maximum needed buf length is 18
|
|
219
|
+
// for formatting -1 with %#U ("U+FFFFFFFFFFFFFFFF") which fits
|
|
220
|
+
// into the already allocated intbuf with a capacity of 68 bytes.
|
|
221
|
+
prec := 4
|
|
222
|
+
if f.precPresent && f.prec > 4 {
|
|
223
|
+
prec = f.prec
|
|
224
|
+
// Compute space needed for "U+" , number, " '", character, "'".
|
|
225
|
+
width := 2 + prec + 2 + utf8.UTFMax + 1
|
|
226
|
+
if width > len(buf) {
|
|
227
|
+
buf = make([]byte, width)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Format into buf, ending at buf[i]. Building numbers is easier right-to-left.
|
|
232
|
+
i := len(buf)
|
|
233
|
+
|
|
234
|
+
// For %#U we want to add a space and a quoted character at the end of the buffer.
|
|
235
|
+
if f.sharp && u <= utf8.MaxRune && strconv.IsPrint(rune(u)) {
|
|
236
|
+
i--
|
|
237
|
+
buf[i] = '\''
|
|
238
|
+
i -= utf8.RuneLen(rune(u))
|
|
239
|
+
utf8.EncodeRune(buf[i:], rune(u))
|
|
240
|
+
i--
|
|
241
|
+
buf[i] = '\''
|
|
242
|
+
i--
|
|
243
|
+
buf[i] = ' '
|
|
244
|
+
}
|
|
245
|
+
// Format the Unicode code point u as a hexadecimal number.
|
|
246
|
+
for u >= 16 {
|
|
247
|
+
i--
|
|
248
|
+
buf[i] = udigits[u&0xF]
|
|
249
|
+
prec--
|
|
250
|
+
u >>= 4
|
|
251
|
+
}
|
|
252
|
+
i--
|
|
253
|
+
buf[i] = udigits[u]
|
|
254
|
+
prec--
|
|
255
|
+
// Add zeros in front of the number until requested precision is reached.
|
|
256
|
+
for prec > 0 {
|
|
257
|
+
i--
|
|
258
|
+
buf[i] = '0'
|
|
259
|
+
prec--
|
|
260
|
+
}
|
|
261
|
+
// Add a leading "U+".
|
|
262
|
+
i--
|
|
263
|
+
buf[i] = '+'
|
|
264
|
+
i--
|
|
265
|
+
buf[i] = 'U'
|
|
266
|
+
|
|
267
|
+
oldZero := f.zero
|
|
268
|
+
f.zero = false
|
|
269
|
+
f.pad(buf[i:])
|
|
270
|
+
f.zero = oldZero
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// fmtInteger formats signed and unsigned integers.
|
|
274
|
+
func (f *fmtState) fmtInteger(u uint64, base int, isSigned bool, verb rune, digits string) {
|
|
275
|
+
negative := isSigned && int64(u) < 0
|
|
276
|
+
if negative {
|
|
277
|
+
u = -u
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
buf := f.scratch()[0:]
|
|
281
|
+
// The already allocated f.intbuf with a capacity of 68 bytes
|
|
282
|
+
// is large enough for integer formatting when no precision or width is set.
|
|
283
|
+
if f.widPresent || f.precPresent {
|
|
284
|
+
// Account 3 extra bytes for possible addition of a sign and "0x".
|
|
285
|
+
width := 3 + f.wid + f.prec // wid and prec are always positive.
|
|
286
|
+
if width > len(buf) {
|
|
287
|
+
// We're going to need a bigger boat.
|
|
288
|
+
buf = make([]byte, width)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Two ways to ask for extra leading zero digits: %.3d or %03d.
|
|
293
|
+
// If both are specified the f.zero flag is ignored and
|
|
294
|
+
// padding with spaces is used instead.
|
|
295
|
+
prec := 0
|
|
296
|
+
if f.precPresent {
|
|
297
|
+
prec = f.prec
|
|
298
|
+
// Precision of 0 and value of 0 means "print nothing" but padding.
|
|
299
|
+
if prec == 0 && u == 0 {
|
|
300
|
+
oldZero := f.zero
|
|
301
|
+
f.zero = false
|
|
302
|
+
f.writePadding(f.wid)
|
|
303
|
+
f.zero = oldZero
|
|
304
|
+
return
|
|
305
|
+
}
|
|
306
|
+
} else if f.zero && !f.minus && f.widPresent { // Zero padding is allowed only to the left.
|
|
307
|
+
prec = f.wid
|
|
308
|
+
if negative || f.plus || f.space {
|
|
309
|
+
prec-- // leave room for sign
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Because printing is easier right-to-left: format u into buf, ending at buf[i].
|
|
314
|
+
i := len(buf)
|
|
315
|
+
switch base {
|
|
316
|
+
case 10:
|
|
317
|
+
if u < 1<<31 {
|
|
318
|
+
// Small values divide as int: a 64-bit division is much slower
|
|
319
|
+
// where uint64 is a BigInt.
|
|
320
|
+
n := int(u)
|
|
321
|
+
for n >= 10 {
|
|
322
|
+
i--
|
|
323
|
+
next := n / 10
|
|
324
|
+
buf[i] = byte('0' + n - next*10)
|
|
325
|
+
n = next
|
|
326
|
+
}
|
|
327
|
+
u = uint64(n)
|
|
328
|
+
}
|
|
329
|
+
for u >= 10 {
|
|
330
|
+
i--
|
|
331
|
+
next := u / 10
|
|
332
|
+
buf[i] = byte('0' + u - next*10)
|
|
333
|
+
u = next
|
|
334
|
+
}
|
|
335
|
+
case 16:
|
|
336
|
+
for u >= 16 {
|
|
337
|
+
i--
|
|
338
|
+
buf[i] = digits[u&0xF]
|
|
339
|
+
u >>= 4
|
|
340
|
+
}
|
|
341
|
+
case 8:
|
|
342
|
+
for u >= 8 {
|
|
343
|
+
i--
|
|
344
|
+
buf[i] = byte('0' + u&7)
|
|
345
|
+
u >>= 3
|
|
346
|
+
}
|
|
347
|
+
case 2:
|
|
348
|
+
for u >= 2 {
|
|
349
|
+
i--
|
|
350
|
+
buf[i] = byte('0' + u&1)
|
|
351
|
+
u >>= 1
|
|
352
|
+
}
|
|
353
|
+
default:
|
|
354
|
+
panic("fmt: unknown base; can't happen")
|
|
355
|
+
}
|
|
356
|
+
i--
|
|
357
|
+
buf[i] = digits[u]
|
|
358
|
+
for i > 0 && prec > len(buf)-i {
|
|
359
|
+
i--
|
|
360
|
+
buf[i] = '0'
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Various prefixes: 0x, -, etc.
|
|
364
|
+
if f.sharp {
|
|
365
|
+
switch base {
|
|
366
|
+
case 2:
|
|
367
|
+
// Add a leading 0b.
|
|
368
|
+
i--
|
|
369
|
+
buf[i] = 'b'
|
|
370
|
+
i--
|
|
371
|
+
buf[i] = '0'
|
|
372
|
+
case 8:
|
|
373
|
+
if buf[i] != '0' {
|
|
374
|
+
i--
|
|
375
|
+
buf[i] = '0'
|
|
376
|
+
}
|
|
377
|
+
case 16:
|
|
378
|
+
// Add a leading 0x or 0X.
|
|
379
|
+
i--
|
|
380
|
+
buf[i] = digits[16]
|
|
381
|
+
i--
|
|
382
|
+
buf[i] = '0'
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if verb == 'O' {
|
|
386
|
+
i--
|
|
387
|
+
buf[i] = 'o'
|
|
388
|
+
i--
|
|
389
|
+
buf[i] = '0'
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if negative {
|
|
393
|
+
i--
|
|
394
|
+
buf[i] = '-'
|
|
395
|
+
} else if f.plus {
|
|
396
|
+
i--
|
|
397
|
+
buf[i] = '+'
|
|
398
|
+
} else if f.space {
|
|
399
|
+
i--
|
|
400
|
+
buf[i] = ' '
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Left padding with zeros has already been handled like precision earlier
|
|
404
|
+
// or the f.zero flag is ignored due to an explicit precision.
|
|
405
|
+
oldZero := f.zero
|
|
406
|
+
f.zero = false
|
|
407
|
+
f.pad(buf[i:])
|
|
408
|
+
f.zero = oldZero
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// truncateString truncates the string s to the specified precision, if present.
|
|
412
|
+
func (f *fmtState) truncateString(s string) string {
|
|
413
|
+
if f.precPresent {
|
|
414
|
+
n := f.prec
|
|
415
|
+
for i := range s {
|
|
416
|
+
n--
|
|
417
|
+
if n < 0 {
|
|
418
|
+
return s[:i]
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return s
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// truncate truncates the byte slice b as a string of the specified precision, if present.
|
|
426
|
+
func (f *fmtState) truncate(b []byte) []byte {
|
|
427
|
+
if f.precPresent {
|
|
428
|
+
n := f.prec
|
|
429
|
+
for i := 0; i < len(b); {
|
|
430
|
+
n--
|
|
431
|
+
if n < 0 {
|
|
432
|
+
return b[:i]
|
|
433
|
+
}
|
|
434
|
+
wid := 1
|
|
435
|
+
if b[i] >= utf8.RuneSelf {
|
|
436
|
+
_, wid = utf8.DecodeRune(b[i:])
|
|
437
|
+
}
|
|
438
|
+
i += wid
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return b
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// fmtS formats a string.
|
|
445
|
+
func (f *fmtState) fmtS(s string) {
|
|
446
|
+
s = f.truncateString(s)
|
|
447
|
+
f.padString(s)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// fmtBs formats the byte slice b as if it was formatted as string with fmtS.
|
|
451
|
+
func (f *fmtState) fmtBs(b []byte) {
|
|
452
|
+
b = f.truncate(b)
|
|
453
|
+
f.pad(b)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// fmtSbx formats a string or byte slice as a hexadecimal encoding of its bytes.
|
|
457
|
+
func (f *fmtState) fmtSbx(s string, b []byte, digits string) {
|
|
458
|
+
length := len(b)
|
|
459
|
+
if b == nil {
|
|
460
|
+
// No byte slice present. Assume string s should be encoded.
|
|
461
|
+
length = len(s)
|
|
462
|
+
}
|
|
463
|
+
// Set length to not process more bytes than the precision demands.
|
|
464
|
+
if f.precPresent && f.prec < length {
|
|
465
|
+
length = f.prec
|
|
466
|
+
}
|
|
467
|
+
// Compute width of the encoding taking into account the f.sharp and f.space flag.
|
|
468
|
+
width := 2 * length
|
|
469
|
+
if width > 0 {
|
|
470
|
+
if f.space {
|
|
471
|
+
// Each element encoded by two hexadecimals will get a leading 0x or 0X.
|
|
472
|
+
if f.sharp {
|
|
473
|
+
width *= 2
|
|
474
|
+
}
|
|
475
|
+
// Elements will be separated by a space.
|
|
476
|
+
width += length - 1
|
|
477
|
+
} else if f.sharp {
|
|
478
|
+
// Only a leading 0x or 0X will be added for the whole string.
|
|
479
|
+
width += 2
|
|
480
|
+
}
|
|
481
|
+
} else { // The byte slice or string that should be encoded is empty.
|
|
482
|
+
if f.widPresent {
|
|
483
|
+
f.writePadding(f.wid)
|
|
484
|
+
}
|
|
485
|
+
return
|
|
486
|
+
}
|
|
487
|
+
// Handle padding to the left.
|
|
488
|
+
if f.widPresent && f.wid > width && !f.minus {
|
|
489
|
+
f.writePadding(f.wid - width)
|
|
490
|
+
}
|
|
491
|
+
// Write the encoding directly into the output buffer.
|
|
492
|
+
if f.sharp {
|
|
493
|
+
// Add leading 0x or 0X.
|
|
494
|
+
f.putByte('0')
|
|
495
|
+
f.putByte(digits[16])
|
|
496
|
+
}
|
|
497
|
+
for i := 0; i < length; i++ {
|
|
498
|
+
if f.space && i > 0 {
|
|
499
|
+
// Separate elements with a space.
|
|
500
|
+
f.putByte(' ')
|
|
501
|
+
if f.sharp {
|
|
502
|
+
// Add leading 0x or 0X for each element.
|
|
503
|
+
f.putByte('0')
|
|
504
|
+
f.putByte(digits[16])
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
var c byte
|
|
508
|
+
if b != nil {
|
|
509
|
+
c = b[i] // Take a byte from the input byte slice.
|
|
510
|
+
} else {
|
|
511
|
+
c = s[i] // Take a byte from the input string.
|
|
512
|
+
}
|
|
513
|
+
// Encode each byte as two hexadecimal digits.
|
|
514
|
+
f.putByte(digits[c>>4])
|
|
515
|
+
f.putByte(digits[c&0xF])
|
|
516
|
+
}
|
|
517
|
+
// Handle padding to the right.
|
|
518
|
+
if f.widPresent && f.wid > width && f.minus {
|
|
519
|
+
f.writePadding(f.wid - width)
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// fmtSx formats a string as a hexadecimal encoding of its bytes.
|
|
524
|
+
func (f *fmtState) fmtSx(s, digits string) {
|
|
525
|
+
f.fmtSbx(s, nil, digits)
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// fmtBx formats a byte slice as a hexadecimal encoding of its bytes.
|
|
529
|
+
func (f *fmtState) fmtBx(b []byte, digits string) {
|
|
530
|
+
f.fmtSbx("", b, digits)
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// fmtQ formats a string as a double-quoted, escaped Go string constant.
|
|
534
|
+
// If f.sharp is set a raw (backquoted) string may be returned instead
|
|
535
|
+
// if the string does not contain any control characters other than tab.
|
|
536
|
+
func (f *fmtState) fmtQ(s string) {
|
|
537
|
+
s = f.truncateString(s)
|
|
538
|
+
if f.sharp && strconv.CanBackquote(s) {
|
|
539
|
+
f.padString("`" + s + "`")
|
|
540
|
+
return
|
|
541
|
+
}
|
|
542
|
+
if !f.plus && plainQuotable(s) {
|
|
543
|
+
f.padString("\"" + s + "\"")
|
|
544
|
+
return
|
|
545
|
+
}
|
|
546
|
+
buf := f.scratch()[:0]
|
|
547
|
+
if f.plus {
|
|
548
|
+
f.pad(strconv.AppendQuoteToASCII(buf, s))
|
|
549
|
+
} else {
|
|
550
|
+
f.pad(strconv.AppendQuote(buf, s))
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
// plainQuotable reports whether Quote leaves s as it is between the quotes:
|
|
555
|
+
// printable ASCII without a quote or backslash.
|
|
556
|
+
func plainQuotable(s string) bool {
|
|
557
|
+
for i := 0; i < len(s); i++ {
|
|
558
|
+
c := s[i]
|
|
559
|
+
if c < ' ' || c > '~' || c == '"' || c == '\\' {
|
|
560
|
+
return false
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return true
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// fixedFloat formats f, a finite float64 of at least zero, with prec digits
|
|
567
|
+
// after the point; "" when the host cannot, in which case the caller formats
|
|
568
|
+
// it with strconv.
|
|
569
|
+
//
|
|
570
|
+
//gofront:native strconv.fixed
|
|
571
|
+
func fixedFloat(f float64, prec int) string {
|
|
572
|
+
return ""
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// fmtFixed is fmtFloat for the plain %f of a float64: it reports false when it
|
|
576
|
+
// wrote nothing.
|
|
577
|
+
func (f *fmtState) fmtFixed(v float64, prec int) bool {
|
|
578
|
+
neg := v < 0 || (v == 0 && 1/v < 0)
|
|
579
|
+
if neg {
|
|
580
|
+
v = -v
|
|
581
|
+
}
|
|
582
|
+
s := fixedFloat(v, prec)
|
|
583
|
+
if s == "" {
|
|
584
|
+
return false
|
|
585
|
+
}
|
|
586
|
+
sign := ""
|
|
587
|
+
if neg {
|
|
588
|
+
sign = "-"
|
|
589
|
+
} else if f.plus {
|
|
590
|
+
sign = "+"
|
|
591
|
+
} else if f.space {
|
|
592
|
+
sign = " "
|
|
593
|
+
}
|
|
594
|
+
if sign == "" {
|
|
595
|
+
f.padString(s)
|
|
596
|
+
} else if f.zero && !f.minus && f.widPresent && f.wid > len(s)+1 {
|
|
597
|
+
// Zero padding goes between the sign and the digits.
|
|
598
|
+
f.putString(sign)
|
|
599
|
+
f.writePadding(f.wid - len(s) - 1)
|
|
600
|
+
f.putString(s)
|
|
601
|
+
} else {
|
|
602
|
+
f.padString(sign + s)
|
|
603
|
+
}
|
|
604
|
+
return true
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// fmtC formats an integer as a Unicode character.
|
|
608
|
+
// If the character is not valid Unicode, it will print '�'.
|
|
609
|
+
func (f *fmtState) fmtC(c uint64) {
|
|
610
|
+
// Explicitly check whether c exceeds utf8.MaxRune since the conversion
|
|
611
|
+
// of a uint64 to a rune may lose precision that indicates an overflow.
|
|
612
|
+
r := rune(c)
|
|
613
|
+
if c > utf8.MaxRune {
|
|
614
|
+
r = utf8.RuneError
|
|
615
|
+
}
|
|
616
|
+
buf := f.scratch()[:0]
|
|
617
|
+
f.pad(utf8.AppendRune(buf, r))
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// fmtQc formats an integer as a single-quoted, escaped Go character constant.
|
|
621
|
+
// If the character is not valid Unicode, it will print '�'.
|
|
622
|
+
func (f *fmtState) fmtQc(c uint64) {
|
|
623
|
+
r := rune(c)
|
|
624
|
+
if c > utf8.MaxRune {
|
|
625
|
+
r = utf8.RuneError
|
|
626
|
+
}
|
|
627
|
+
buf := f.scratch()[:0]
|
|
628
|
+
if f.plus {
|
|
629
|
+
f.pad(strconv.AppendQuoteRuneToASCII(buf, r))
|
|
630
|
+
} else {
|
|
631
|
+
f.pad(strconv.AppendQuoteRune(buf, r))
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// fmtFloat formats floats. The default precision for each verb
|
|
636
|
+
// is specified as last argument in the call to fmt_float.
|
|
637
|
+
func (f *fmtState) fmtFloat(v float64, size int, verb rune, prec int) {
|
|
638
|
+
// Format number, reserving space for leading + sign if needed.
|
|
639
|
+
if f.precPresent {
|
|
640
|
+
prec = f.prec
|
|
641
|
+
}
|
|
642
|
+
if verb == 'f' && size == 64 && !f.sharp && prec >= 0 && prec <= 60 && v-v == 0 && f.fmtFixed(v, prec) {
|
|
643
|
+
return
|
|
644
|
+
}
|
|
645
|
+
num := strconv.AppendFloat(append(f.scratch()[:0], '+'), v, byte(verb), prec, size)
|
|
646
|
+
if num[1] == '-' || num[1] == '+' {
|
|
647
|
+
num = num[1:]
|
|
648
|
+
} else {
|
|
649
|
+
num[0] = '+'
|
|
650
|
+
}
|
|
651
|
+
// f.space means to add a leading space instead of a "+" sign unless f.plus is used.
|
|
652
|
+
if f.space && num[0] == '+' && !f.plus {
|
|
653
|
+
num[0] = ' '
|
|
654
|
+
}
|
|
655
|
+
// Special handling for infinities and NaN,
|
|
656
|
+
// which don't look like a number so shouldn't be padded with zeros.
|
|
657
|
+
if num[1] == 'I' || num[1] == 'N' {
|
|
658
|
+
oldZero := f.zero
|
|
659
|
+
f.zero = false
|
|
660
|
+
if num[1] == 'N' && !f.space && !f.plus {
|
|
661
|
+
num = num[1:]
|
|
662
|
+
}
|
|
663
|
+
f.pad(num)
|
|
664
|
+
f.zero = oldZero
|
|
665
|
+
return
|
|
666
|
+
}
|
|
667
|
+
// The sharp flag forces printing a decimal point but removes
|
|
668
|
+
// trailing zeros for %e, %f with the shortest flag.
|
|
669
|
+
if f.sharp && verb != 'b' {
|
|
670
|
+
digits := 0
|
|
671
|
+
switch verb {
|
|
672
|
+
case 'v', 'g', 'G', 'x':
|
|
673
|
+
digits = prec
|
|
674
|
+
// If no precision is set explicitly use a precision of 6.
|
|
675
|
+
if digits == -1 {
|
|
676
|
+
digits = 6
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Buffer pre-allocated with enough room for
|
|
681
|
+
// exponent notations of the form "e+123" or "p-1023".
|
|
682
|
+
tail := make([]byte, 0, 6)
|
|
683
|
+
hasDecimalPoint := false
|
|
684
|
+
sawNonzeroDigit := false
|
|
685
|
+
// Starting from i = 1 to skip sign at num[0].
|
|
686
|
+
for i := 1; i < len(num); i++ {
|
|
687
|
+
c := num[i]
|
|
688
|
+
if c == '.' {
|
|
689
|
+
hasDecimalPoint = true
|
|
690
|
+
} else if c == 'p' || c == 'P' || ((c == 'e' || c == 'E') && verb != 'x' && verb != 'X') {
|
|
691
|
+
tail = append(tail, num[i:]...)
|
|
692
|
+
num = num[:i]
|
|
693
|
+
} else {
|
|
694
|
+
// Count significant digits after the first non-zero digit.
|
|
695
|
+
if c != '0' {
|
|
696
|
+
sawNonzeroDigit = true
|
|
697
|
+
}
|
|
698
|
+
if sawNonzeroDigit {
|
|
699
|
+
digits--
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if !hasDecimalPoint {
|
|
704
|
+
// Leading digit 0 should contribute once to digits.
|
|
705
|
+
if len(num) == 2 && num[1] == '0' {
|
|
706
|
+
digits--
|
|
707
|
+
}
|
|
708
|
+
num = append(num, '.')
|
|
709
|
+
}
|
|
710
|
+
for digits > 0 {
|
|
711
|
+
num = append(num, '0')
|
|
712
|
+
digits--
|
|
713
|
+
}
|
|
714
|
+
num = append(num, tail...)
|
|
715
|
+
}
|
|
716
|
+
// We want a sign if asked for and if the sign is not positive.
|
|
717
|
+
if f.plus || num[0] != '+' {
|
|
718
|
+
// If we're zero padding to the left we want the sign before the leading zeros.
|
|
719
|
+
// Achieve this by writing the sign out and then padding the unsigned number.
|
|
720
|
+
// Zero padding is allowed only to the left.
|
|
721
|
+
if f.zero && !f.minus && f.widPresent && f.wid > len(num) {
|
|
722
|
+
f.putByte(num[0])
|
|
723
|
+
f.writePadding(f.wid - len(num))
|
|
724
|
+
f.putBytes(num[1:])
|
|
725
|
+
return
|
|
726
|
+
}
|
|
727
|
+
f.pad(num)
|
|
728
|
+
return
|
|
729
|
+
}
|
|
730
|
+
// No sign to show and the number is positive; just print the unsigned number.
|
|
731
|
+
f.pad(num[1:])
|
|
732
|
+
}
|