From 8de48af6dead4b25ce6a679af50e815b3cec4522 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 9 May 2017 10:03:00 -0700 Subject: [PATCH] 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 --- ninja_strings.go | 16 ++++++++++++++-- ninja_strings_test.go | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ninja_strings.go b/ninja_strings.go index 5bdddea..a52f174 100644 --- a/ninja_strings.go +++ b/ninja_strings.go @@ -54,6 +54,7 @@ func simpleNinjaString(str string) *ninjaString { type parseState struct { scope scope str string + pendingStr string stringStart int varStart int result *ninjaString @@ -64,6 +65,9 @@ func (ps *parseState) pushVariable(v Variable) { // Last push was a variable, we need a blank string separator 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) } @@ -71,7 +75,8 @@ func (ps *parseState) pushString(s string) { if len(ps.result.strings) != len(ps.result.variables) { 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) @@ -93,7 +98,7 @@ func parseNinjaString(scope scope, str string) (*ninjaString, error) { result: result, } - state := parseStringState + state := parseFirstRuneState var err error for i := 0; i < len(str); i++ { r := rune(str[i]) @@ -111,6 +116,13 @@ func parseNinjaString(scope scope, str string) (*ninjaString, error) { 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) { switch { case r == '$': diff --git a/ninja_strings_test.go b/ninja_strings_test.go index b417335..6227ea6 100644 --- a/ninja_strings_test.go +++ b/ninja_strings_test.go @@ -70,6 +70,11 @@ var ninjaParseTestCases = []struct { vars: nil, strs: []string{"foo bar"}, }, + { + input: " foo ", + vars: nil, + strs: []string{"$ foo "}, + }, { input: "foo $ bar", err: "invalid character after '$' at byte offset 5",