Merge pull request #18 from colincross/ninjastring
Fix bug in parseNinjaString
diff --git a/ninja_strings.go b/ninja_strings.go
index 950518d..3c3b444 100644
--- a/ninja_strings.go
+++ b/ninja_strings.go
@@ -59,6 +59,21 @@
result *ninjaString
}
+func (ps *parseState) pushVariable(v Variable) {
+ if len(ps.result.variables) == len(ps.result.strings) {
+ // Last push was a variable, we need a blank string separator
+ ps.result.strings = append(ps.result.strings, "")
+ }
+ ps.result.variables = append(ps.result.variables, v)
+}
+
+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)
+}
+
type stateFunc func(*parseState, int, rune) (stateFunc, error)
// parseNinjaString parses an unescaped ninja string (i.e. all $<something>
@@ -98,7 +113,7 @@
return parseDollarStartState, nil
case r == eof:
- state.result.strings = append(state.result.strings, state.str[state.stringStart:i])
+ state.pushString(state.str[state.stringStart:i])
return nil, nil
default:
@@ -112,7 +127,7 @@
r >= '0' && r <= '9', r == '_', r == '-':
// The beginning of a of the variable name. Output the string and
// keep going.
- state.result.strings = append(state.result.strings, state.str[state.stringStart:i-1])
+ state.pushString(state.str[state.stringStart:i-1])
return parseDollarState, nil
case r == '$':
@@ -123,7 +138,7 @@
case r == '{':
// This is a bracketted variable name (e.g. "${blah.blah}"). Output
// the string and keep going.
- state.result.strings = append(state.result.strings, state.str[state.stringStart:i-1])
+ state.pushString(state.str[state.stringStart:i-1])
state.varStart = i + 1
return parseBracketsState, nil
@@ -153,14 +168,11 @@
return nil, err
}
- state.result.variables = append(state.result.variables, v)
+ state.pushVariable(v)
state.varStart = i + 1
+ state.stringStart = i
- // We always have a string in between variables, even if it's an
- // empty one.
- state.result.strings = append(state.result.strings, "")
-
- return parseDollarState, nil
+ return parseDollarStartState, nil
case r == eof:
// This is the end of the variable name.
@@ -169,10 +181,10 @@
return nil, err
}
- state.result.variables = append(state.result.variables, v)
+ state.pushVariable(v)
// We always end with a string, even if it's an empty one.
- state.result.strings = append(state.result.strings, "")
+ state.pushString("")
return nil, nil
@@ -184,7 +196,7 @@
return nil, err
}
- state.result.variables = append(state.result.variables, v)
+ state.pushVariable(v)
state.stringStart = i
return parseStringState, nil
}
@@ -210,7 +222,7 @@
return nil, err
}
- state.result.variables = append(state.result.variables, v)
+ state.pushVariable(v)
state.stringStart = i + 1
return parseStringState, nil
diff --git a/ninja_strings_test.go b/ninja_strings_test.go
index 55651ff..b35c8b4 100644
--- a/ninja_strings_test.go
+++ b/ninja_strings_test.go
@@ -56,6 +56,16 @@
strs: []string{"foo $$ bar"},
},
{
+ input: "$foo${bar}",
+ vars: []string{"foo", "bar"},
+ strs: []string{"","", ""},
+ },
+ {
+ input: "$foo$$",
+ vars: []string{"foo"},
+ strs: []string{"","$$"},
+ },
+ {
input: "foo $ bar",
err: "invalid character after '$' at byte offset 5",
},