diff options
-rw-r--r-- | eval.go | 9 | ||||
-rw-r--r-- | parser.go | 8 | ||||
-rw-r--r-- | rule_parser.go | 10 | ||||
-rw-r--r-- | strutil.go | 11 |
4 files changed, 26 insertions, 12 deletions
@@ -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) @@ -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 @@ -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++ |