Fix support for CRLF line ending
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
# This is a TOML document. Boom.
|
||||||
|
|
||||||
|
title = "TOML Example"
|
||||||
|
|
||||||
|
[owner]
|
||||||
|
name = "Tom Preston-Werner"
|
||||||
|
organization = "GitHub"
|
||||||
|
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
||||||
|
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
||||||
|
|
||||||
|
[database]
|
||||||
|
server = "192.168.1.1"
|
||||||
|
ports = [ 8001, 8001, 8002 ]
|
||||||
|
connection_max = 5000
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[servers]
|
||||||
|
|
||||||
|
# You can indent as you please. Tabs or spaces. TOML don't care.
|
||||||
|
[servers.alpha]
|
||||||
|
ip = "10.0.0.1"
|
||||||
|
dc = "eqdc10"
|
||||||
|
|
||||||
|
[servers.beta]
|
||||||
|
ip = "10.0.0.2"
|
||||||
|
dc = "eqdc10"
|
||||||
|
|
||||||
|
[clients]
|
||||||
|
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
|
||||||
@@ -132,6 +132,8 @@ func (l *tomlLexer) lexVoid() tomlLexStateFn {
|
|||||||
return l.lexComment
|
return l.lexComment
|
||||||
case '=':
|
case '=':
|
||||||
return l.lexEqual
|
return l.lexEqual
|
||||||
|
case '\r':
|
||||||
|
fallthrough
|
||||||
case '\n':
|
case '\n':
|
||||||
l.skip()
|
l.skip()
|
||||||
continue
|
continue
|
||||||
@@ -185,6 +187,8 @@ func (l *tomlLexer) lexRvalue() tomlLexStateFn {
|
|||||||
return l.lexLiteralString
|
return l.lexLiteralString
|
||||||
case ',':
|
case ',':
|
||||||
return l.lexComma
|
return l.lexComma
|
||||||
|
case '\r':
|
||||||
|
fallthrough
|
||||||
case '\n':
|
case '\n':
|
||||||
l.skip()
|
l.skip()
|
||||||
if l.depth == 0 {
|
if l.depth == 0 {
|
||||||
@@ -277,7 +281,7 @@ func (l *tomlLexer) lexComma() tomlLexStateFn {
|
|||||||
|
|
||||||
func (l *tomlLexer) lexKey() tomlLexStateFn {
|
func (l *tomlLexer) lexKey() tomlLexStateFn {
|
||||||
inQuotes := false
|
inQuotes := false
|
||||||
for r := l.peek(); isKeyChar(r) || r == '\n'; r = l.peek() {
|
for r := l.peek(); isKeyChar(r) || r == '\n' || r == '\r'; r = l.peek() {
|
||||||
if r == '"' {
|
if r == '"' {
|
||||||
inQuotes = !inQuotes
|
inQuotes = !inQuotes
|
||||||
} else if r == '\n' {
|
} else if r == '\n' {
|
||||||
@@ -295,6 +299,9 @@ func (l *tomlLexer) lexKey() tomlLexStateFn {
|
|||||||
|
|
||||||
func (l *tomlLexer) lexComment() tomlLexStateFn {
|
func (l *tomlLexer) lexComment() tomlLexStateFn {
|
||||||
for next := l.peek(); next != '\n' && next != eof; next = l.peek() {
|
for next := l.peek(); next != '\n' && next != eof; next = l.peek() {
|
||||||
|
if (next == '\r' && l.follow("\r\n")) {
|
||||||
|
break
|
||||||
|
}
|
||||||
l.next()
|
l.next()
|
||||||
}
|
}
|
||||||
l.ignore()
|
l.ignore()
|
||||||
@@ -319,7 +326,10 @@ func (l *tomlLexer) lexLiteralString() tomlLexStateFn {
|
|||||||
terminator = "'''"
|
terminator = "'''"
|
||||||
|
|
||||||
// special case: discard leading newline
|
// special case: discard leading newline
|
||||||
if l.peek() == '\n' {
|
if l.follow("\r\n") {
|
||||||
|
l.skip()
|
||||||
|
l.skip()
|
||||||
|
} else if l.peek() == '\n' {
|
||||||
l.skip()
|
l.skip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,7 +365,10 @@ func (l *tomlLexer) lexString() tomlLexStateFn {
|
|||||||
terminator = "\"\"\""
|
terminator = "\"\"\""
|
||||||
|
|
||||||
// special case: discard leading newline
|
// special case: discard leading newline
|
||||||
if l.peek() == '\n' {
|
if l.follow("\r\n") {
|
||||||
|
l.skip()
|
||||||
|
l.skip()
|
||||||
|
} else if l.peek() == '\n' {
|
||||||
l.skip()
|
l.skip()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,19 @@ func TestMultipleKeyGroupsComment(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestSimpleWindowsCRLF(t *testing.T) {
|
||||||
|
testFlow(t, "a=4\r\nb=2", []token{
|
||||||
|
token{Position{1, 1}, tokenKey, "a"},
|
||||||
|
token{Position{1, 2}, tokenEqual, "="},
|
||||||
|
token{Position{1, 3}, tokenInteger, "4"},
|
||||||
|
token{Position{2, 1}, tokenKey, "b"},
|
||||||
|
token{Position{2, 2}, tokenEqual, "="},
|
||||||
|
token{Position{2, 3}, tokenInteger, "2"},
|
||||||
|
token{Position{2, 4}, tokenEOF, ""},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestBasicKey(t *testing.T) {
|
func TestBasicKey(t *testing.T) {
|
||||||
testFlow(t, "hello", []token{
|
testFlow(t, "hello", []token{
|
||||||
token{Position{1, 1}, tokenKey, "hello"},
|
token{Position{1, 1}, tokenKey, "hello"},
|
||||||
|
|||||||
@@ -494,6 +494,42 @@ func TestParseFile(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseFileCRLF(t *testing.T) {
|
||||||
|
tree, err := LoadFile("example-crlf.toml")
|
||||||
|
|
||||||
|
assertTree(t, tree, err, map[string]interface{}{
|
||||||
|
"title": "TOML Example",
|
||||||
|
"owner": map[string]interface{}{
|
||||||
|
"name": "Tom Preston-Werner",
|
||||||
|
"organization": "GitHub",
|
||||||
|
"bio": "GitHub Cofounder & CEO\nLikes tater tots and beer.",
|
||||||
|
"dob": time.Date(1979, time.May, 27, 7, 32, 0, 0, time.UTC),
|
||||||
|
},
|
||||||
|
"database": map[string]interface{}{
|
||||||
|
"server": "192.168.1.1",
|
||||||
|
"ports": []int64{8001, 8001, 8002},
|
||||||
|
"connection_max": 5000,
|
||||||
|
"enabled": true,
|
||||||
|
},
|
||||||
|
"servers": map[string]interface{}{
|
||||||
|
"alpha": map[string]interface{}{
|
||||||
|
"ip": "10.0.0.1",
|
||||||
|
"dc": "eqdc10",
|
||||||
|
},
|
||||||
|
"beta": map[string]interface{}{
|
||||||
|
"ip": "10.0.0.2",
|
||||||
|
"dc": "eqdc10",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"clients": map[string]interface{}{
|
||||||
|
"data": []interface{}{
|
||||||
|
[]string{"gamma", "delta"},
|
||||||
|
[]int64{1, 2},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseKeyGroupArray(t *testing.T) {
|
func TestParseKeyGroupArray(t *testing.T) {
|
||||||
tree, err := Load("[[foo.bar]] a = 42\n[[foo.bar]] a = 69")
|
tree, err := Load("[[foo.bar]] a = 42\n[[foo.bar]] a = 69")
|
||||||
assertTree(t, tree, err, map[string]interface{}{
|
assertTree(t, tree, err, map[string]interface{}{
|
||||||
|
|||||||
Reference in New Issue
Block a user