gofront 1.8.0 → 1.9.1
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 +3 -3
- package/package.json +6 -5
- package/src/backend/js/expressions.js +1157 -408
- package/src/backend/js/index.js +327 -153
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +559 -2552
- package/src/backend/js/statements.js +670 -158
- package/src/backend/js/stdlib/index.js +45 -93
- package/src/backend/js/templ.js +32 -45
- package/src/backend/js/type-info.js +298 -19
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +91 -170
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +490 -965
- package/src/backend/wasm/emit-builtins.js +884 -256
- package/src/backend/wasm/emit-exprs.js +185 -77
- package/src/backend/wasm/emit-maps.js +17 -367
- package/src/backend/wasm/emit-shared.js +4 -1
- package/src/backend/wasm/emit-stmts.js +524 -240
- package/src/backend/wasm/emit.js +176 -38
- package/src/backend/wasm/globals.js +48 -8
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +44 -530
- package/src/backend/wasm/method-expr.js +12 -1
- package/src/backend/wasm/module-emitter.js +299 -770
- package/src/backend/wasm/monomorph.js +139 -8
- package/src/backend/wasm/natives.js +600 -0
- package/src/backend/wasm/prescan.js +5 -153
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -32
- package/src/backend/wasm/types.js +97 -20
- package/src/backend/wasm/variadic.js +9 -4
- package/src/cli/cli-core.js +5 -1
- package/src/cli/test-runner.js +115 -342
- package/src/compiler.js +113 -130
- package/src/lexer/lexer.js +106 -11
- package/src/lexer/templ-lexer.js +61 -18
- package/src/lexer/tokens.js +1 -0
- package/src/link/stdlib.js +355 -132
- package/src/link/type-names.js +204 -0
- package/src/link/wasm.js +30 -6
- package/src/lower/bounds.js +153 -0
- package/src/lower/captures.js +92 -33
- package/src/lower/embedding.js +62 -5
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +929 -0
- package/src/lower/functions.js +225 -7
- package/src/lower/gen-types.js +293 -0
- package/src/lower/index.js +14 -2
- package/src/lower/json-codecs.js +334 -245
- package/src/lower/ownership.js +25 -7
- package/src/lower/reachability.js +69 -51
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +30 -5
- package/src/parser/expressions.js +111 -57
- package/src/parser/statements.js +108 -0
- package/src/parser/templ.js +44 -5
- package/src/parser/types.js +12 -0
- package/src/resolver.js +1 -2
- package/src/typechecker/assignability.js +214 -19
- package/src/typechecker/const-fold.js +70 -27
- package/src/typechecker/constants.js +156 -8
- package/src/typechecker/expressions.js +490 -108
- package/src/typechecker/index.js +346 -42
- package/src/typechecker/init-order.js +136 -40
- package/src/typechecker/operand-text.js +41 -0
- package/src/typechecker/resolve.js +490 -65
- package/src/typechecker/statements.js +288 -27
- package/src/typechecker/stdlib/excluded.js +9 -5
- package/src/typechecker/stdlib/index.js +25 -9
- package/src/typechecker/termination.js +10 -1
- package/src/typechecker/types.js +287 -575
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -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/json.go +62 -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/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +171 -38
- package/stdlib/internal/jsonrt/enc.go +186 -36
- package/stdlib/internal/jsonrt/scanner.go +17 -8
- package/stdlib/io/io.go +157 -1
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +16 -14
- 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 +391 -452
- 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 +235 -50
- 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 +141 -3
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/fmt-runtime.js +0 -573
- 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 -119
- package/src/backend/js/stdlib/builder.js +0 -98
- package/src/backend/js/stdlib/bytes.js +0 -368
- package/src/backend/js/stdlib/errors.js +0 -45
- package/src/backend/js/stdlib/fmt.js +0 -517
- 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 -1167
- package/src/backend/js/stdlib/maps.js +0 -37
- package/src/backend/js/stdlib/math.js +0 -85
- 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 -34
- package/src/backend/js/stdlib/slices.js +0 -107
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -79
- package/src/backend/js/stdlib/strings.js +0 -301
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -41
- package/src/backend/js/stdlib/time.js +0 -152
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/stdlib/bytes.js +0 -6716
- package/src/backend/wasm/stdlib/core.js +0 -10278
- package/src/backend/wasm/stdlib/io.js +0 -3578
- package/src/backend/wasm/stdlib/packages.js +0 -2402
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -2229
- package/src/typechecker/stdlib/core.js +0 -1079
- package/src/typechecker/stdlib/extended.js +0 -1210
- package/stdlib/bytes/iter.go +0 -192
- package/stdlib/bytes/search.go +0 -240
- package/stdlib/bytes/split.go +0 -218
- package/stdlib/errors/overlay.go +0 -12
- package/stdlib/maps/iter.go +0 -65
- package/stdlib/slices/extra.go +0 -73
- package/stdlib/slices/iter.go +0 -113
- package/stdlib/strings/extra.go +0 -35
- package/stdlib/strings/iter.go +0 -122
- package/stdlib/sync/extra.go +0 -105
- package/stdlib/unicode/utf8/bytes.go +0 -239
package/stdlib/strconv/quote.go
CHANGED
|
@@ -4,45 +4,95 @@
|
|
|
4
4
|
|
|
5
5
|
package strconv
|
|
6
6
|
|
|
7
|
-
import
|
|
8
|
-
"unicode"
|
|
9
|
-
"unicode/utf8"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
// IntSize is the size in bits of an int or uint value.
|
|
13
|
-
const IntSize = 64
|
|
7
|
+
import "unicode/utf8"
|
|
14
8
|
|
|
15
9
|
const lowerhex = "0123456789abcdef"
|
|
16
10
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
func bsearch16(s []uint16, v uint16) (int, bool) {
|
|
12
|
+
n := len(s)
|
|
13
|
+
i, j := 0, n
|
|
14
|
+
for i < j {
|
|
15
|
+
h := i + (j-i)>>1
|
|
16
|
+
if s[h] < v {
|
|
17
|
+
i = h + 1
|
|
18
|
+
} else {
|
|
19
|
+
j = h
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return i, i < n && s[i] == v
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
func (
|
|
25
|
-
|
|
25
|
+
func bsearch32(s []uint32, v uint32) (int, bool) {
|
|
26
|
+
n := len(s)
|
|
27
|
+
i, j := 0, n
|
|
28
|
+
for i < j {
|
|
29
|
+
h := i + (j-i)>>1
|
|
30
|
+
if s[h] < v {
|
|
31
|
+
i = h + 1
|
|
32
|
+
} else {
|
|
33
|
+
j = h
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return i, i < n && s[i] == v
|
|
26
37
|
}
|
|
27
38
|
|
|
28
|
-
func (e *NumError) Unwrap() error { return e.Err }
|
|
29
|
-
|
|
30
39
|
// IsPrint reports whether the rune is defined as printable by Go, with
|
|
31
|
-
// the same definition as unicode.IsPrint: letters, numbers, punctuation,
|
|
40
|
+
// the same definition as [unicode.IsPrint]: letters, numbers, punctuation,
|
|
32
41
|
// symbols and ASCII space.
|
|
33
42
|
func IsPrint(r rune) bool {
|
|
34
|
-
|
|
43
|
+
// Fast check for Latin-1
|
|
44
|
+
if r <= 0xFF {
|
|
45
|
+
if 0x20 <= r && r <= 0x7E {
|
|
46
|
+
// All the ASCII is printable from space through DEL-1.
|
|
47
|
+
return true
|
|
48
|
+
}
|
|
49
|
+
if 0xA1 <= r && r <= 0xFF {
|
|
50
|
+
// Similarly for ¡ through ÿ...
|
|
51
|
+
return r != 0xAD // ...except for the bizarre soft hyphen.
|
|
52
|
+
}
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// First, find first i such that isPrint[i] >= x.
|
|
57
|
+
// This is the index of either the start or end of a pair that might span x.
|
|
58
|
+
// The start is even (isPrint[i&^1]) and the end is odd (isPrint[i|1]).
|
|
59
|
+
// If we find x in a range, make sure x is not in isNotPrint list.
|
|
60
|
+
if 0 <= r && r < 1<<16 {
|
|
61
|
+
rr := uint16(r)
|
|
62
|
+
i, _ := bsearch16(isPrint16, rr)
|
|
63
|
+
if i >= len(isPrint16) || rr < isPrint16[i&^1] || isPrint16[i|1] < rr {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
66
|
+
_, found := bsearch16(isNotPrint16, rr)
|
|
67
|
+
return !found
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
rr := uint32(r)
|
|
71
|
+
i, _ := bsearch32(isPrint32, rr)
|
|
72
|
+
if i >= len(isPrint32) || rr < isPrint32[i&^1] || isPrint32[i|1] < rr {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
if r >= 0x20000 {
|
|
35
76
|
return true
|
|
36
77
|
}
|
|
37
|
-
|
|
78
|
+
r -= 0x10000
|
|
79
|
+
_, found := bsearch16(isNotPrint32, uint16(r))
|
|
80
|
+
return !found
|
|
38
81
|
}
|
|
39
82
|
|
|
40
|
-
// IsGraphic reports whether the rune is defined as a Graphic by Unicode.
|
|
83
|
+
// IsGraphic reports whether the rune is defined as a Graphic by Unicode. Such
|
|
84
|
+
// characters include letters, marks, numbers, punctuation, symbols, and
|
|
85
|
+
// spaces, from categories L, M, N, P, S, and Zs.
|
|
41
86
|
func IsGraphic(r rune) bool {
|
|
42
|
-
if
|
|
87
|
+
if IsPrint(r) {
|
|
43
88
|
return true
|
|
44
89
|
}
|
|
45
|
-
|
|
90
|
+
// We know r must fit in 16 bits - see makeisprint.go.
|
|
91
|
+
if r > 0xFFFF {
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
_, found := bsearch16(isGraphic, uint16(r))
|
|
95
|
+
return found
|
|
46
96
|
}
|
|
47
97
|
|
|
48
98
|
func quoteWith(s string, quote byte, ASCIIonly, graphicOnly bool) string {
|
|
@@ -61,7 +111,9 @@ func appendQuotedWith(buf []byte, s string, quote byte, ASCIIonly, graphicOnly b
|
|
|
61
111
|
buf = append(buf, quote)
|
|
62
112
|
for len(s) > 0 {
|
|
63
113
|
r, width := utf8.DecodeRuneInString(s)
|
|
64
|
-
|
|
114
|
+
// A U+FFFD that is in the string, not an invalid byte, has width 1 where
|
|
115
|
+
// a string is made of UTF-16 units.
|
|
116
|
+
if width == 1 && r == utf8.RuneError && rune(s[0]) != utf8.RuneError {
|
|
65
117
|
b0 := int(byte(s[0]))
|
|
66
118
|
buf = append(buf, byte('\\'), byte('x'), hexDigit(b0>>4), hexDigit(b0))
|
|
67
119
|
s = s[1:]
|
|
@@ -138,6 +190,13 @@ func appendEscapedRune(buf []byte, r rune, quote byte, ASCIIonly, graphicOnly bo
|
|
|
138
190
|
return buf
|
|
139
191
|
}
|
|
140
192
|
|
|
193
|
+
// Quote returns a double-quoted Go string literal representing s. The
|
|
194
|
+
// returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
|
|
195
|
+
// control characters and non-printable characters as defined by [IsPrint].
|
|
196
|
+
func Quote(s string) string {
|
|
197
|
+
return quoteWith(s, byte('"'), false, false)
|
|
198
|
+
}
|
|
199
|
+
|
|
141
200
|
// QuoteRune returns a single-quoted Go character literal representing the rune.
|
|
142
201
|
func QuoteRune(r rune) string {
|
|
143
202
|
return quoteRuneWith(r, byte('\''), false, false)
|
|
@@ -178,10 +237,10 @@ func CanBackquote(s string) bool {
|
|
|
178
237
|
for len(s) > 0 {
|
|
179
238
|
r, wid := utf8.DecodeRuneInString(s)
|
|
180
239
|
s = s[wid:]
|
|
240
|
+
if r == '\ufeff' {
|
|
241
|
+
return false
|
|
242
|
+
}
|
|
181
243
|
if wid > 1 {
|
|
182
|
-
if r == '\ufeff' {
|
|
183
|
-
return false
|
|
184
|
-
}
|
|
185
244
|
continue
|
|
186
245
|
}
|
|
187
246
|
if r == utf8.RuneError {
|
|
@@ -221,6 +280,9 @@ func unquoteHex(c byte, s string) (rune, bool, string, error) {
|
|
|
221
280
|
}
|
|
222
281
|
var v rune
|
|
223
282
|
for j := 0; j < n; j++ {
|
|
283
|
+
if s[j] >= utf8.RuneSelf {
|
|
284
|
+
return 0, false, "", ErrSyntax
|
|
285
|
+
}
|
|
224
286
|
x, ok := unhex(byte(s[j]))
|
|
225
287
|
if !ok {
|
|
226
288
|
return 0, false, "", ErrSyntax
|
|
@@ -243,6 +305,9 @@ func unquoteOctal(c byte, s string) (rune, string, error) {
|
|
|
243
305
|
return 0, "", ErrSyntax
|
|
244
306
|
}
|
|
245
307
|
for j := 0; j < 2; j++ {
|
|
308
|
+
if s[j] >= utf8.RuneSelf {
|
|
309
|
+
return 0, "", ErrSyntax
|
|
310
|
+
}
|
|
246
311
|
b := byte(s[j])
|
|
247
312
|
if b < byte('0') || b > byte('7') {
|
|
248
313
|
return 0, "", ErrSyntax
|
|
@@ -260,20 +325,24 @@ func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string,
|
|
|
260
325
|
if len(s) == 0 {
|
|
261
326
|
return 0, false, "", ErrSyntax
|
|
262
327
|
}
|
|
328
|
+
// A string index is a UTF-16 unit: decide on it before narrowing to a byte.
|
|
329
|
+
if s[0] >= utf8.RuneSelf {
|
|
330
|
+
r, size := utf8.DecodeRuneInString(s)
|
|
331
|
+
return r, true, s[size:], nil
|
|
332
|
+
}
|
|
263
333
|
c := byte(s[0])
|
|
264
334
|
if c == quote && (quote == byte('\'') || quote == byte('"')) {
|
|
265
335
|
return 0, false, "", ErrSyntax
|
|
266
336
|
}
|
|
267
|
-
if rune(c) >= utf8.RuneSelf {
|
|
268
|
-
r, size := utf8.DecodeRuneInString(s)
|
|
269
|
-
return r, true, s[size:], nil
|
|
270
|
-
}
|
|
271
337
|
if c != byte('\\') {
|
|
272
338
|
return rune(c), false, s[1:], nil
|
|
273
339
|
}
|
|
274
340
|
if len(s) <= 1 {
|
|
275
341
|
return 0, false, "", ErrSyntax
|
|
276
342
|
}
|
|
343
|
+
if s[1] >= utf8.RuneSelf {
|
|
344
|
+
return 0, false, "", ErrSyntax
|
|
345
|
+
}
|
|
277
346
|
esc := byte(s[1])
|
|
278
347
|
s = s[2:]
|
|
279
348
|
switch esc {
|
|
@@ -309,33 +378,149 @@ func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string,
|
|
|
309
378
|
}
|
|
310
379
|
}
|
|
311
380
|
|
|
312
|
-
// QuotedPrefix returns the quoted string at the prefix of s.
|
|
381
|
+
// QuotedPrefix returns the quoted string (as understood by [Unquote]) at the prefix of s.
|
|
382
|
+
// If s does not start with a valid quoted string, QuotedPrefix returns an error.
|
|
313
383
|
func QuotedPrefix(s string) (string, error) {
|
|
314
|
-
|
|
384
|
+
out, _, err := unquote(s, false)
|
|
385
|
+
return out, err
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Unquote interprets s as a single-quoted, double-quoted,
|
|
389
|
+
// or backquoted Go string literal, returning the string value
|
|
390
|
+
// that s quotes. (If s is single-quoted, it would be a Go
|
|
391
|
+
// character literal; Unquote returns the corresponding
|
|
392
|
+
// one-character string. For an empty character literal
|
|
393
|
+
// Unquote returns the empty string.)
|
|
394
|
+
func Unquote(s string) (string, error) {
|
|
395
|
+
out, rem, err := unquote(s, true)
|
|
396
|
+
if len(rem) > 0 {
|
|
315
397
|
return "", ErrSyntax
|
|
316
398
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
399
|
+
return out, err
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// unquote parses a quoted string at the start of the input,
|
|
403
|
+
// returning the parsed prefix, the remaining suffix, and any parse errors.
|
|
404
|
+
// If unescape is true, the parsed prefix is unescaped,
|
|
405
|
+
// otherwise the input prefix is provided verbatim.
|
|
406
|
+
func unquote(in string, unescape bool) (out, rem string, err error) {
|
|
407
|
+
// Determine the quote form and optimistically find the terminating quote.
|
|
408
|
+
if len(in) < 2 {
|
|
409
|
+
return "", in, ErrSyntax
|
|
410
|
+
}
|
|
411
|
+
if in[0] > 0x7F {
|
|
412
|
+
return "", in, ErrSyntax
|
|
320
413
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
414
|
+
quote := byte(in[0])
|
|
415
|
+
end := indexByte(in[1:], quote)
|
|
416
|
+
if end < 0 {
|
|
417
|
+
return "", in, ErrSyntax
|
|
418
|
+
}
|
|
419
|
+
end += 2 // position after terminating quote; may be wrong if escape sequences are present
|
|
420
|
+
|
|
421
|
+
switch quote {
|
|
422
|
+
case '`':
|
|
423
|
+
switch {
|
|
424
|
+
case !unescape:
|
|
425
|
+
out = in[:end] // include quotes
|
|
426
|
+
case !containsByte(in[:end], '\r'):
|
|
427
|
+
out = in[len("`") : end-len("`")] // exclude quotes
|
|
428
|
+
default:
|
|
429
|
+
// Carriage return characters ('\r') inside raw string literals
|
|
430
|
+
// are discarded from the raw string value.
|
|
431
|
+
// Built as a string: GoFront strings are indexed by UTF-16 unit, so
|
|
432
|
+
// a byte buffer would split multi-byte text.
|
|
433
|
+
out = ""
|
|
434
|
+
start := len("`")
|
|
435
|
+
for i := len("`"); i < end-len("`"); i++ {
|
|
436
|
+
if in[i] == '\r' {
|
|
437
|
+
out += in[start:i]
|
|
438
|
+
start = i + 1
|
|
439
|
+
}
|
|
325
440
|
}
|
|
441
|
+
out += in[start : end-len("`")]
|
|
326
442
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
443
|
+
// NOTE: Prior implementations did not verify that raw strings consist
|
|
444
|
+
// of valid UTF-8 characters and we continue to not verify it as such.
|
|
445
|
+
// The Go specification does not explicitly require valid UTF-8,
|
|
446
|
+
// but only mention that it is implicitly valid for Go source code
|
|
447
|
+
// (which must be valid UTF-8).
|
|
448
|
+
return out, in[end:], nil
|
|
449
|
+
case '"', '\'':
|
|
450
|
+
// Handle quoted strings without any escape sequences.
|
|
451
|
+
if !containsByte(in[:end], '\\') && !containsByte(in[:end], '\n') {
|
|
452
|
+
var valid bool
|
|
453
|
+
switch quote {
|
|
454
|
+
case '"':
|
|
455
|
+
valid = utf8.ValidString(in[len(`"`) : end-len(`"`)])
|
|
456
|
+
case '\'':
|
|
457
|
+
r, n := utf8.DecodeRuneInString(in[len("'") : end-len("'")])
|
|
458
|
+
valid = len("'")+n+len("'") == end && (r != utf8.RuneError || n != 1)
|
|
459
|
+
}
|
|
460
|
+
if valid {
|
|
461
|
+
out = in[:end]
|
|
462
|
+
if unescape {
|
|
463
|
+
out = out[1 : end-1] // exclude quotes
|
|
464
|
+
}
|
|
465
|
+
return out, in[end:], nil
|
|
466
|
+
}
|
|
333
467
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
468
|
+
|
|
469
|
+
// Handle quoted strings with escape sequences.
|
|
470
|
+
var buf []byte
|
|
471
|
+
in0 := in
|
|
472
|
+
in = in[1:] // skip starting quote
|
|
473
|
+
if unescape {
|
|
474
|
+
buf = make([]byte, 0, 3*end/2) // try to avoid more allocations
|
|
475
|
+
}
|
|
476
|
+
for len(in) > 0 && in[0] != quote {
|
|
477
|
+
// Process the next character,
|
|
478
|
+
// rejecting any unescaped newline characters which are invalid.
|
|
479
|
+
r, multibyte, rem, err := UnquoteChar(in, quote)
|
|
480
|
+
if in[0] == '\n' || err != nil {
|
|
481
|
+
return "", in0, ErrSyntax
|
|
482
|
+
}
|
|
483
|
+
in = rem
|
|
484
|
+
|
|
485
|
+
// Append the character if unescaping the input.
|
|
486
|
+
if unescape {
|
|
487
|
+
if r < utf8.RuneSelf || !multibyte {
|
|
488
|
+
buf = append(buf, byte(r))
|
|
489
|
+
} else {
|
|
490
|
+
buf = utf8.AppendRune(buf, r)
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Single quoted strings must be a single character.
|
|
495
|
+
if quote == '\'' {
|
|
496
|
+
break
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Verify that the string ends with a terminating quote.
|
|
501
|
+
if !(len(in) > 0 && in[0] == quote) {
|
|
502
|
+
return "", in0, ErrSyntax
|
|
503
|
+
}
|
|
504
|
+
in = in[1:] // skip terminating quote
|
|
505
|
+
|
|
506
|
+
if unescape {
|
|
507
|
+
return string(buf), in, nil
|
|
508
|
+
}
|
|
509
|
+
return in0[:len(in0)-len(in)], in, nil
|
|
510
|
+
default:
|
|
511
|
+
return "", in, ErrSyntax
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
func indexByte(s string, c byte) int {
|
|
516
|
+
for i := 0; i < len(s); i++ {
|
|
517
|
+
if s[i] == c {
|
|
518
|
+
return i
|
|
337
519
|
}
|
|
338
|
-
rem = next
|
|
339
520
|
}
|
|
340
|
-
return
|
|
521
|
+
return -1
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
func containsByte(s string, c byte) bool {
|
|
525
|
+
return indexByte(s, c) >= 0
|
|
341
526
|
}
|