Escape leading space in ninja strings
Spaces normally don't need to be escaped, but leading spaces are trimmed. Escape leading space to allow setting a variable to a value with leading spaces. Test: ninja_string_test.go Change-Id: Ic0ffb076dbd603b7c0203720b9c1ea635c5ded75
This commit is contained in:
parent
7aa318f83d
commit
8de48af6de
2 changed files with 19 additions and 2 deletions
|
@ -54,6 +54,7 @@ func simpleNinjaString(str string) *ninjaString {
|
||||||
type parseState struct {
|
type parseState struct {
|
||||||
scope scope
|
scope scope
|
||||||
str string
|
str string
|
||||||
|
pendingStr string
|
||||||
stringStart int
|
stringStart int
|
||||||
varStart int
|
varStart int
|
||||||
result *ninjaString
|
result *ninjaString
|
||||||
|
@ -64,6 +65,9 @@ func (ps *parseState) pushVariable(v Variable) {
|
||||||
// Last push was a variable, we need a blank string separator
|
// Last push was a variable, we need a blank string separator
|
||||||
ps.result.strings = append(ps.result.strings, "")
|
ps.result.strings = append(ps.result.strings, "")
|
||||||
}
|
}
|
||||||
|
if ps.pendingStr != "" {
|
||||||
|
panic("oops, pushed variable with pending string")
|
||||||
|
}
|
||||||
ps.result.variables = append(ps.result.variables, v)
|
ps.result.variables = append(ps.result.variables, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +75,8 @@ func (ps *parseState) pushString(s string) {
|
||||||
if len(ps.result.strings) != len(ps.result.variables) {
|
if len(ps.result.strings) != len(ps.result.variables) {
|
||||||
panic("oops, pushed string after string")
|
panic("oops, pushed string after string")
|
||||||
}
|
}
|
||||||
ps.result.strings = append(ps.result.strings, s)
|
ps.result.strings = append(ps.result.strings, ps.pendingStr+s)
|
||||||
|
ps.pendingStr = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
type stateFunc func(*parseState, int, rune) (stateFunc, error)
|
type stateFunc func(*parseState, int, rune) (stateFunc, error)
|
||||||
|
@ -93,7 +98,7 @@ func parseNinjaString(scope scope, str string) (*ninjaString, error) {
|
||||||
result: result,
|
result: result,
|
||||||
}
|
}
|
||||||
|
|
||||||
state := parseStringState
|
state := parseFirstRuneState
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < len(str); i++ {
|
for i := 0; i < len(str); i++ {
|
||||||
r := rune(str[i])
|
r := rune(str[i])
|
||||||
|
@ -111,6 +116,13 @@ func parseNinjaString(scope scope, str string) (*ninjaString, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseFirstRuneState(state *parseState, i int, r rune) (stateFunc, error) {
|
||||||
|
if r == ' ' {
|
||||||
|
state.pendingStr += "$"
|
||||||
|
}
|
||||||
|
return parseStringState(state, i, r)
|
||||||
|
}
|
||||||
|
|
||||||
func parseStringState(state *parseState, i int, r rune) (stateFunc, error) {
|
func parseStringState(state *parseState, i int, r rune) (stateFunc, error) {
|
||||||
switch {
|
switch {
|
||||||
case r == '$':
|
case r == '$':
|
||||||
|
|
|
@ -70,6 +70,11 @@ var ninjaParseTestCases = []struct {
|
||||||
vars: nil,
|
vars: nil,
|
||||||
strs: []string{"foo bar"},
|
strs: []string{"foo bar"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: " foo ",
|
||||||
|
vars: nil,
|
||||||
|
strs: []string{"$ foo "},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: "foo $ bar",
|
input: "foo $ bar",
|
||||||
err: "invalid character after '$' at byte offset 5",
|
err: "invalid character after '$' at byte offset 5",
|
||||||
|
|
Loading…
Reference in a new issue