mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
Add support for unquoted config strings that start with number
Signed-off-by: Waldemar Quevedo <wally@synadia.com>
This commit is contained in:
28
conf/lex.go
28
conf/lex.go
@@ -547,7 +547,7 @@ func lexValue(lx *lexer) stateFn {
|
||||
return lexBlock
|
||||
case unicode.IsDigit(r):
|
||||
lx.backup() // avoid an extra state and use the same as above
|
||||
return lexNumberOrDateOrIPStart
|
||||
return lexNumberOrDateOrStringOrIPStart
|
||||
case r == '.': // special error case, be kind to users
|
||||
return lx.errorf("Floats must start with a digit")
|
||||
case isNL(r):
|
||||
@@ -948,9 +948,11 @@ func lexStringBinary(lx *lexer) stateFn {
|
||||
return lx.stringStateFn
|
||||
}
|
||||
|
||||
// lexNumberOrDateStart consumes either a (positive) integer, a float, a datetime, or IP.
|
||||
// It assumes that NO negative sign has been consumed, that is triggered above.
|
||||
func lexNumberOrDateOrIPStart(lx *lexer) stateFn {
|
||||
// lexNumberOrDateOrStringOrIPStart consumes either a (positive)
|
||||
// integer, a float, a datetime, or IP, or String that started with a
|
||||
// number. It assumes that NO negative sign has been consumed, that
|
||||
// is triggered above.
|
||||
func lexNumberOrDateOrStringOrIPStart(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
if !unicode.IsDigit(r) {
|
||||
if r == '.' {
|
||||
@@ -958,11 +960,13 @@ func lexNumberOrDateOrIPStart(lx *lexer) stateFn {
|
||||
}
|
||||
return lx.errorf("Expected a digit but got '%v'.", r)
|
||||
}
|
||||
return lexNumberOrDateOrIP
|
||||
return lexNumberOrDateOrStringOrIP
|
||||
}
|
||||
|
||||
// lexNumberOrDateOrIP consumes either a (positive) integer, float, datetime or IP.
|
||||
func lexNumberOrDateOrIP(lx *lexer) stateFn {
|
||||
// lexNumberOrDateOrStringOrIP consumes either a (positive) integer,
|
||||
// float, datetime, IP or string without quotes that starts with a
|
||||
// number.
|
||||
func lexNumberOrDateOrStringOrIP(lx *lexer) stateFn {
|
||||
r := lx.next()
|
||||
switch {
|
||||
case r == '-':
|
||||
@@ -971,13 +975,17 @@ func lexNumberOrDateOrIP(lx *lexer) stateFn {
|
||||
}
|
||||
return lexDateAfterYear
|
||||
case unicode.IsDigit(r):
|
||||
return lexNumberOrDateOrIP
|
||||
return lexNumberOrDateOrStringOrIP
|
||||
case r == '.':
|
||||
return lexFloatStart // Assume float at first, but could be IP
|
||||
// Assume float at first, but could be IP
|
||||
return lexFloatStart
|
||||
case isNumberSuffix(r):
|
||||
return lexConvenientNumber
|
||||
case !(isNL(r) || r == eof || r == mapEnd || r == optValTerm || r == mapValTerm || isWhitespace(r) || unicode.IsDigit(r)):
|
||||
// Treat it as a string value once we get a rune that
|
||||
// is not a number.
|
||||
return lexString
|
||||
}
|
||||
|
||||
lx.backup()
|
||||
lx.emit(itemInteger)
|
||||
return lx.pop()
|
||||
|
||||
@@ -87,6 +87,84 @@ func TestComplexStringValues(t *testing.T) {
|
||||
expect(t, lx, expectedItems)
|
||||
}
|
||||
|
||||
func TestStringStartingWithNumber(t *testing.T) {
|
||||
expectedItems := []item{
|
||||
{itemKey, "foo", 1, 0},
|
||||
{itemString, "3xyz", 1, 6},
|
||||
{itemEOF, "", 2, 0},
|
||||
}
|
||||
|
||||
lx := lex(`foo = 3xyz`)
|
||||
expect(t, lx, expectedItems)
|
||||
|
||||
lx = lex(`foo = 3xyz,`)
|
||||
expect(t, lx, expectedItems)
|
||||
|
||||
lx = lex(`foo = 3xyz;`)
|
||||
expect(t, lx, expectedItems)
|
||||
|
||||
expectedItems = []item{
|
||||
{itemKey, "foo", 2, 9},
|
||||
{itemString, "3xyz", 2, 15},
|
||||
{itemEOF, "", 2, 0},
|
||||
}
|
||||
content := `
|
||||
foo = 3xyz
|
||||
`
|
||||
lx = lex(content)
|
||||
expect(t, lx, expectedItems)
|
||||
|
||||
expectedItems = []item{
|
||||
{itemKey, "map", 2, 9},
|
||||
{itemMapStart, "", 2, 14},
|
||||
{itemKey, "foo", 3, 11},
|
||||
{itemString, "3xyz", 3, 17},
|
||||
{itemMapEnd, "", 3, 22},
|
||||
{itemEOF, "", 2, 0},
|
||||
}
|
||||
content = `
|
||||
map {
|
||||
foo = 3xyz}
|
||||
`
|
||||
lx = lex(content)
|
||||
expect(t, lx, expectedItems)
|
||||
|
||||
expectedItems = []item{
|
||||
{itemKey, "map", 2, 9},
|
||||
{itemMapStart, "", 2, 14},
|
||||
{itemKey, "foo", 3, 11},
|
||||
{itemString, "3xyz", 3, 17},
|
||||
{itemMapEnd, "", 4, 10},
|
||||
{itemEOF, "", 2, 0},
|
||||
}
|
||||
content = `
|
||||
map {
|
||||
foo = 3xyz;
|
||||
}
|
||||
`
|
||||
lx = lex(content)
|
||||
expect(t, lx, expectedItems)
|
||||
|
||||
expectedItems = []item{
|
||||
{itemKey, "map", 2, 9},
|
||||
{itemMapStart, "", 2, 14},
|
||||
{itemKey, "foo", 3, 11},
|
||||
{itemString, "3xyz", 3, 17},
|
||||
{itemKey, "bar", 4, 11},
|
||||
{itemString, "4wqs", 4, 17},
|
||||
{itemMapEnd, "", 5, 10},
|
||||
{itemEOF, "", 2, 0},
|
||||
}
|
||||
content = `
|
||||
map {
|
||||
foo = 3xyz,
|
||||
bar = 4wqs
|
||||
}
|
||||
`
|
||||
lx = lex(content)
|
||||
expect(t, lx, expectedItems)
|
||||
}
|
||||
|
||||
func TestBinaryString(t *testing.T) {
|
||||
expectedItems := []item{
|
||||
{itemKey, "foo", 1, 0},
|
||||
@@ -380,7 +458,7 @@ func TestRawString(t *testing.T) {
|
||||
}
|
||||
lx := lex("foo = bar")
|
||||
expect(t, lx, expectedItems)
|
||||
lx = lex(`foo = bar' `) //'single-quote for emacs TODO: Remove me
|
||||
lx = lex(`foo = bar' `)
|
||||
expect(t, lx, expectedItems)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user