aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.go9
-rw-r--r--parser.go8
-rw-r--r--rule_parser.go10
-rw-r--r--strutil.go11
4 files changed, 26 insertions, 12 deletions
diff --git a/eval.go b/eval.go
index 57716b5..6f8f160 100644
--- a/eval.go
+++ b/eval.go
@@ -259,7 +259,9 @@ func (ev *Evaluator) evalMaybeRule(ast *maybeRuleAST) error {
ev.lastRule = nil
ev.srcpos = ast.srcpos
- glog.V(1).Infof("maybe rule %s: %q assign:%v", ev.srcpos, ast.expr, ast.assign)
+ if glog.V(1) {
+ glog.Infof("maybe rule %s: %q assign:%v", ev.srcpos, ast.expr, ast.assign)
+ }
abuf := newEbuf()
aexpr := toExpr(ast.expr)
@@ -277,7 +279,7 @@ func (ev *Evaluator) evalMaybeRule(ast *maybeRuleAST) error {
abuf.Write(b)
continue
}
- eq := findLiteralChar(b, '=', 0)
+ eq := findLiteralChar(b, '=', 0, skipVar)
if eq >= 0 {
abuf.Write(b[:eq+1])
if eq+1 < len(b) {
@@ -302,6 +304,9 @@ func (ev *Evaluator) evalMaybeRule(ast *maybeRuleAST) error {
line := abuf.Bytes()
r := &rule{srcpos: ast.srcpos}
+ if glog.V(1) {
+ glog.Infof("rule? %s: %q assign:%v rhs:%s", r.srcpos, line, ast.assign, rhs)
+ }
assign, err := r.parse(line, ast.assign, rhs)
if err != nil {
ws := newWordScanner(line)
diff --git a/parser.go b/parser.go
index bd10185..7d64db2 100644
--- a/parser.go
+++ b/parser.go
@@ -154,7 +154,7 @@ func (p *parser) handleDirective(line []byte, directives map[string]directiveFun
func (p *parser) handleRuleOrAssign(line []byte) {
rline := line
var semi []byte
- if i := findLiteralChar(line, ';', 0); i >= 0 {
+ if i := findLiteralChar(line, ';', 0, skipVar); i >= 0 {
// preserve after semicolon
semi = append(semi, line[i+1:]...)
rline = concatline(line[:i])
@@ -177,7 +177,7 @@ func (p *parser) handleAssign(line []byte) bool {
return false
}
// fmt.Printf("assign: %q=>%q\n", line, aline)
- i := findLiteralChar(aline, ':', '=')
+ i := findLiteralChar(aline, ':', '=', skipVar)
if i >= 0 {
if aline[i] == '=' {
p.parseAssign(aline, i)
@@ -221,9 +221,9 @@ func (p *parser) parseMaybeRule(line, semi []byte) {
return
}
var assign *assignAST
- ci := findLiteralChar(line, ':', 0)
+ ci := findLiteralChar(line, ':', 0, skipVar)
if ci >= 0 {
- eqi := findLiteralChar(line[ci+1:], '=', 0)
+ eqi := findLiteralChar(line[ci+1:], '=', 0, skipVar)
if eqi == 0 {
panic(fmt.Sprintf("unexpected eq after colon: %q", line))
}
diff --git a/rule_parser.go b/rule_parser.go
index 92ab5fc..f43e8ac 100644
--- a/rule_parser.go
+++ b/rule_parser.go
@@ -77,7 +77,7 @@ func (r *rule) cmdpos() srcpos {
}
func isPatternRule(s []byte) (pattern, bool) {
- i := findLiteralChar(s, '%', 0)
+ i := findLiteralChar(s, '%', 0, noSkipVar)
if i < 0 {
return pattern{}, false
}
@@ -160,7 +160,9 @@ func (r *rule) parseVar(s []byte, rhs expr) (*assignAST, error) {
}
// parse parses rule line.
-// line is rule line until '=', or before ';'
+// line is rule line until '=', or before ';'.
+// line was already expaned, so probably no need to skip var $(xxx) when
+// finding literal char. i.e. $ is parsed as literal '$'.
// assign is not nil, if line was known as target specific var '<xxx>: <v>=<val>'
// rhs is not nil, if line ended with '=' (target specific var after evaluated)
func (r *rule) parse(line []byte, assign *assignAST, rhs expr) (*assignAST, error) {
@@ -177,7 +179,7 @@ func (r *rule) parse(line []byte, assign *assignAST, rhs expr) (*assignAST, erro
}
r.outputs = []string{}
- index := findLiteralChar(line, ':', 0)
+ index := findLiteralChar(line, ':', 0, noSkipVar)
if index < 0 {
return nil, errors.New("*** missing separator.")
}
@@ -226,7 +228,7 @@ func (r *rule) parse(line []byte, assign *assignAST, rhs expr) (*assignAST, erro
r.cmds = append(r.cmds, string(rest[index+1:]))
rest = rest[:index-1]
}
- index = findLiteralChar(rest, ':', 0)
+ index = findLiteralChar(rest, ':', 0, noSkipVar)
if index < 0 {
r.parseInputs(rest)
return nil, nil
diff --git a/strutil.go b/strutil.go
index d97ebd5..39d282b 100644
--- a/strutil.go
+++ b/strutil.go
@@ -281,7 +281,14 @@ func firstWord(line []byte) ([]byte, []byte) {
return line, nil
}
-func findLiteralChar(s []byte, stop1, stop2 byte) int {
+type findCharOption int
+
+const (
+ noSkipVar findCharOption = iota
+ skipVar
+)
+
+func findLiteralChar(s []byte, stop1, stop2 byte, op findCharOption) int {
i := 0
for {
var ch byte
@@ -297,7 +304,7 @@ func findLiteralChar(s []byte, stop1, stop2 byte) int {
if ch == stop2 {
break
}
- if ch == '$' {
+ if op == skipVar && ch == '$' {
break
}
i++