Skip to content

Commit 5253492

Browse files
authored
Enable TOML 1.1 by default (#457)
1 parent e954445 commit 5253492

5 files changed

Lines changed: 35 additions & 105 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
22
reflection interface similar to Go's standard library `json` and `xml` packages.
33

4-
Compatible with TOML version [v1.0.0](https://toml.io/en/v1.0.0).
4+
Compatible with TOML version [v1.1.0](https://toml.io/en/v1.1.0).
55

66
Documentation: https://pkg.go.dev/github.com/BurntSushi/toml
77

decode_test.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ import (
1818
"github.com/BurntSushi/toml/internal"
1919
)
2020

21-
func WithTomlNext(f func()) {
22-
os.Setenv("BURNTSUSHI_TOML_110", "")
23-
defer func() { os.Unsetenv("BURNTSUSHI_TOML_110") }()
24-
f()
25-
}
26-
2721
func TestDecodeReader(t *testing.T) {
2822
var i struct{ A int }
2923
meta, err := DecodeReader(strings.NewReader("a = 42"), &i)

lex.go

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@ func (p Position) String() string {
4646
}
4747

4848
type lexer struct {
49-
input string
50-
start int
51-
pos int
52-
line int
53-
state stateFn
54-
items chan item
55-
tomlNext bool
56-
esc bool
49+
input string
50+
start int
51+
pos int
52+
line int
53+
state stateFn
54+
items chan item
55+
esc bool
5756

5857
// Allow for backing up up to 4 runes. This is necessary because TOML
5958
// contains 3-rune tokens (""" and ''').
@@ -89,14 +88,13 @@ func (lx *lexer) nextItem() item {
8988
}
9089
}
9190

92-
func lex(input string, tomlNext bool) *lexer {
91+
func lex(input string) *lexer {
9392
lx := &lexer{
94-
input: input,
95-
state: lexTop,
96-
items: make(chan item, 10),
97-
stack: make([]stateFn, 0, 10),
98-
line: 1,
99-
tomlNext: tomlNext,
93+
input: input,
94+
state: lexTop,
95+
items: make(chan item, 10),
96+
stack: make([]stateFn, 0, 10),
97+
line: 1,
10098
}
10199
return lx
102100
}
@@ -411,7 +409,7 @@ func lexTableNameEnd(lx *lexer) stateFn {
411409
// Lexes only one part, e.g. only 'a' inside 'a.b'.
412410
func lexBareName(lx *lexer) stateFn {
413411
r := lx.next()
414-
if isBareKeyChar(r, lx.tomlNext) {
412+
if isBareKeyChar(r) {
415413
return lexBareName
416414
}
417415
lx.backup()
@@ -629,10 +627,7 @@ func lexInlineTableValue(lx *lexer) stateFn {
629627
case isWhitespace(r):
630628
return lexSkip(lx, lexInlineTableValue)
631629
case isNL(r):
632-
if lx.tomlNext {
633-
return lexSkip(lx, lexInlineTableValue)
634-
}
635-
return lx.errorPrevLine(errLexInlineTableNL{})
630+
return lexSkip(lx, lexInlineTableValue)
636631
case r == '#':
637632
lx.push(lexInlineTableValue)
638633
return lexCommentStart
@@ -654,21 +649,15 @@ func lexInlineTableValueEnd(lx *lexer) stateFn {
654649
case isWhitespace(r):
655650
return lexSkip(lx, lexInlineTableValueEnd)
656651
case isNL(r):
657-
if lx.tomlNext {
658-
return lexSkip(lx, lexInlineTableValueEnd)
659-
}
660-
return lx.errorPrevLine(errLexInlineTableNL{})
652+
return lexSkip(lx, lexInlineTableValueEnd)
661653
case r == '#':
662654
lx.push(lexInlineTableValueEnd)
663655
return lexCommentStart
664656
case r == ',':
665657
lx.ignore()
666658
lx.skip(isWhitespace)
667659
if lx.peek() == '}' {
668-
if lx.tomlNext {
669-
return lexInlineTableValueEnd
670-
}
671-
return lx.errorf("trailing comma not allowed in inline tables")
660+
return lexInlineTableValueEnd
672661
}
673662
return lexInlineTableValue
674663
case r == '}':
@@ -856,9 +845,6 @@ func lexStringEscape(lx *lexer) stateFn {
856845
r := lx.next()
857846
switch r {
858847
case 'e':
859-
if !lx.tomlNext {
860-
return lx.error(errLexEscape{r})
861-
}
862848
fallthrough
863849
case 'b':
864850
fallthrough
@@ -879,9 +865,6 @@ func lexStringEscape(lx *lexer) stateFn {
879865
case '\\':
880866
return lx.pop()
881867
case 'x':
882-
if !lx.tomlNext {
883-
return lx.error(errLexEscape{r})
884-
}
885868
return lexHexEscape
886869
case 'u':
887870
return lexShortUnicodeEscape
@@ -1259,7 +1242,7 @@ func isDigit(r rune) bool { return r >= '0' && r <= '9' }
12591242
func isBinary(r rune) bool { return r == '0' || r == '1' }
12601243
func isOctal(r rune) bool { return r >= '0' && r <= '7' }
12611244
func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') }
1262-
func isBareKeyChar(r rune, tomlNext bool) bool {
1245+
func isBareKeyChar(r rune) bool {
12631246
return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') ||
12641247
(r >= '0' && r <= '9') || r == '_' || r == '-'
12651248
}

parse.go

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package toml
33
import (
44
"fmt"
55
"math"
6-
"os"
76
"strconv"
87
"strings"
98
"time"
@@ -17,7 +16,6 @@ type parser struct {
1716
context Key // Full key for the current hash in scope.
1817
currentKey string // Base key name for everything except hashes.
1918
pos Position // Current position in the TOML file.
20-
tomlNext bool
2119

2220
ordered []Key // List of keys in the order that they appear in the TOML data.
2321

@@ -32,8 +30,6 @@ type keyInfo struct {
3230
}
3331

3432
func parse(data string) (p *parser, err error) {
35-
_, tomlNext := os.LookupEnv("BURNTSUSHI_TOML_110")
36-
3733
defer func() {
3834
if r := recover(); r != nil {
3935
if pErr, ok := r.(ParseError); ok {
@@ -73,10 +69,9 @@ func parse(data string) (p *parser, err error) {
7369
p = &parser{
7470
keyInfo: make(map[string]keyInfo),
7571
mapping: make(map[string]any),
76-
lx: lex(data, tomlNext),
72+
lx: lex(data),
7773
ordered: make([]Key, 0),
7874
implicits: make(map[string]struct{}),
79-
tomlNext: tomlNext,
8075
}
8176
for {
8277
item := p.next()
@@ -350,17 +345,14 @@ func (p *parser) valueFloat(it item) (any, tomlType) {
350345
var dtTypes = []struct {
351346
fmt string
352347
zone *time.Location
353-
next bool
354348
}{
355-
{time.RFC3339Nano, time.Local, false},
356-
{"2006-01-02T15:04:05.999999999", internal.LocalDatetime, false},
357-
{"2006-01-02", internal.LocalDate, false},
358-
{"15:04:05.999999999", internal.LocalTime, false},
359-
360-
// tomlNext
361-
{"2006-01-02T15:04Z07:00", time.Local, true},
362-
{"2006-01-02T15:04", internal.LocalDatetime, true},
363-
{"15:04", internal.LocalTime, true},
349+
{time.RFC3339Nano, time.Local},
350+
{"2006-01-02T15:04:05.999999999", internal.LocalDatetime},
351+
{"2006-01-02", internal.LocalDate},
352+
{"15:04:05.999999999", internal.LocalTime},
353+
{"2006-01-02T15:04Z07:00", time.Local},
354+
{"2006-01-02T15:04", internal.LocalDatetime},
355+
{"15:04", internal.LocalTime},
364356
}
365357

366358
func (p *parser) valueDatetime(it item) (any, tomlType) {
@@ -371,9 +363,6 @@ func (p *parser) valueDatetime(it item) (any, tomlType) {
371363
err error
372364
)
373365
for _, dt := range dtTypes {
374-
if dt.next && !p.tomlNext {
375-
continue
376-
}
377366
t, err = time.ParseInLocation(dt.fmt, it.val, dt.zone)
378367
if err == nil {
379368
if missingLeadingZero(it.val, dt.fmt) {
@@ -807,10 +796,8 @@ func (p *parser) replaceEscapes(it item, str string) string {
807796
b.WriteByte(0x0d)
808797
skip = 1
809798
case 'e':
810-
if p.tomlNext {
811-
b.WriteByte(0x1b)
812-
skip = 1
813-
}
799+
b.WriteByte(0x1b)
800+
skip = 1
814801
case '"':
815802
b.WriteByte(0x22)
816803
skip = 1
@@ -820,11 +807,9 @@ func (p *parser) replaceEscapes(it item, str string) string {
820807
// The lexer guarantees the correct number of characters are present;
821808
// don't need to check here.
822809
case 'x':
823-
if p.tomlNext {
824-
escaped := p.asciiEscapeToUnicode(it, str[i+2:i+4])
825-
b.WriteRune(escaped)
826-
skip = 3
827-
}
810+
escaped := p.asciiEscapeToUnicode(it, str[i+2:i+4])
811+
b.WriteRune(escaped)
812+
skip = 3
828813
case 'u':
829814
escaped := p.asciiEscapeToUnicode(it, str[i+2:i+6])
830815
b.WriteRune(escaped)

toml_test.go

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,7 @@ var metaTests = map[string]string{
257257
`,
258258
}
259259

260-
// TOML 1.0
261260
func TestToml(t *testing.T) {
262-
runTomlTest(t, false)
263-
}
264-
265-
// TOML 1.1
266-
func TestTomlNext(t *testing.T) {
267-
toml.WithTomlNext(func() {
268-
runTomlTest(t, true)
269-
})
270-
}
271-
272-
func runTomlTest(t *testing.T, includeNext bool, wantFail ...string) {
273261
for k := range errorTests { // Make sure patterns are valid.
274262
_, err := filepath.Match(k, "")
275263
if err != nil {
@@ -310,6 +298,7 @@ func runTomlTest(t *testing.T, includeNext bool, wantFail ...string) {
310298

311299
run := func(t *testing.T, enc bool) {
312300
r := tomltest.Runner{
301+
Version: "1.1.0",
313302
Files: tomltest.EmbeddedTests(),
314303
Encoder: enc,
315304
Parser: parser{},
@@ -351,26 +340,15 @@ func runTomlTest(t *testing.T, includeNext bool, wantFail ...string) {
351340
"invalid/table/redefine-03",
352341
},
353342
}
354-
if includeNext {
355-
r.Version = "1.1.0"
356-
}
357343

358344
tests, err := r.Run()
359345
if err != nil {
360346
t.Fatal(err)
361347
}
362348

363-
failed := make(map[string]struct{})
364349
for _, test := range tests.Tests {
365350
t.Run(test.Path, func(t *testing.T) {
366351
if test.Failed() {
367-
for _, f := range wantFail {
368-
if f == test.Path {
369-
failed[test.Path] = struct{}{}
370-
return
371-
}
372-
}
373-
374352
t.Fatalf("\nError:\n%s\n\nInput:\n%s\nOutput:\n%s\nWant:\n%s\n",
375353
test.Failure, test.Input, test.Output, test.Want)
376354
return
@@ -383,15 +361,10 @@ func runTomlTest(t *testing.T, includeNext bool, wantFail ...string) {
383361
// Test metadata
384362
if !enc && test.Type() == tomltest.TypeValid {
385363
delete(shouldExistValid, test.Path)
386-
testMeta(t, test, includeNext)
364+
testMeta(t, test)
387365
}
388366
})
389367
}
390-
for _, f := range wantFail {
391-
if _, ok := failed[f]; !ok {
392-
t.Errorf("expected test %q to fail but it didn't", f)
393-
}
394-
}
395368

396369
t.Logf(" valid: passed %d; failed %d", tests.PassedValid, tests.FailedValid)
397370
t.Logf("invalid: passed %d; failed %d", tests.PassedInvalid, tests.FailedInvalid)
@@ -419,17 +392,12 @@ func runTomlTest(t *testing.T, includeNext bool, wantFail ...string) {
419392

420393
var reCollapseSpace = regexp.MustCompile(` +`)
421394

422-
func testMeta(t *testing.T, test tomltest.Test, includeNext bool) {
395+
func testMeta(t *testing.T, test tomltest.Test) {
423396
want, ok := metaTests[strings.TrimPrefix(test.Path, "valid/")]
424397
if !ok {
425398
return
426399
}
427400

428-
// Output is slightly different due to different quoting; just skip for now.
429-
if includeNext && (test.Path == "valid/table/names" || test.Path == "valid/key/case-sensitive") {
430-
return
431-
}
432-
433401
var s any
434402
meta, err := toml.Decode(test.Input, &s)
435403
if err != nil {

0 commit comments

Comments
 (0)