Improve whitespace handling.
diff --git a/lex.go b/lex.go index 67205dd..b33e3de 100644 --- a/lex.go +++ b/lex.go
@@ -53,6 +53,8 @@ const eof = -1 +const whitespace = " \f\t" + // stateFn represents the state of the scanner as a function that returns the next state. type stateFn func(*lexer) stateFn @@ -197,6 +199,11 @@ l.ignore() return lexBeforeKey + case isWhitespace(r): + l.acceptRun(whitespace) + l.ignore() + return lexKey + default: l.backup() return lexKey @@ -250,8 +257,8 @@ // lexValue scans text until the end of the line. We expect to be just after the delimiter. func lexValue(l *lexer) stateFn { - // ignore leading spaces - l.acceptRun(" ") + // ignore leading whitespace + l.acceptRun(whitespace) l.ignore() // TODO: handle multiline with indent on subsequent lines @@ -261,7 +268,7 @@ r := l.peek() if isEOL(r) { l.next() - l.acceptRun(" \t") + l.acceptRun(whitespace) } else { err := l.scanEscapeSequence() if err != nil { @@ -377,6 +384,9 @@ return strings.ContainsRune(" :=", r) } +// isWhitespace reports whether the rune is a whitespace character. +func isWhitespace(r rune) bool { + return strings.ContainsRune(whitespace, r) // isUnicodeLiteral reports whether we are at a unicode literal. // The escape character has already been consumed. func isUnicodeLiteral(r rune) bool {
diff --git a/properties_test.go b/properties_test.go index 2420da5..613e0d2 100644 --- a/properties_test.go +++ b/properties_test.go
@@ -32,6 +32,13 @@ testKeyValue(c, "\n\nkey=value\n\n", "key", "value") } +func (l *LoadSuite) TestKeyWithWhitespacePrefix(c *C) { + testKeyValue(c, " key=value", "key", "value") + testKeyValue(c, "\fkey=value", "key", "value") + testKeyValue(c, "\tkey=value", "key", "value") + testKeyValue(c, " \f\tkey=value", "key", "value") +} + func (l *LoadSuite) TestWithComments(c *C) { input := ` # this is a comment @@ -64,6 +71,8 @@ func (l *LoadSuite) TestMultilineValue(c *C) { testKeyValue(c, "key = valueA,\\\n valueB", "key", "valueA,valueB") + testKeyValue(c, "key = valueA,\\\n\fvalueB", "key", "valueA,valueB") + testKeyValue(c, "key = valueA,\\\n\tvalueB", "key", "valueA,valueB") } func (l *LoadSuite) TestFailWithPrematureEOF(c *C) {