aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFumitoshi Ukai <fumitoshi.ukai@gmail.com>2015-07-07 17:31:05 +0900
committerFumitoshi Ukai <fumitoshi.ukai@gmail.com>2015-07-07 17:31:05 +0900
commit201df42f5df5f6a7f943dbb9f775ba857b261053 (patch)
tree7a4f9c7dc7cfcc385253bd85716d871e6952149d
parent9a17717fd5df84ece411c9284c944bb65f742668 (diff)
downloadandroid_build_kati-201df42f5df5f6a7f943dbb9f775ba857b261053.tar.gz
android_build_kati-201df42f5df5f6a7f943dbb9f775ba857b261053.tar.bz2
android_build_kati-201df42f5df5f6a7f943dbb9f775ba857b261053.zip
fix equal_in_target.mk
-rw-r--r--ast.go6
-rw-r--r--eval.go11
-rw-r--r--evalcmd.go2
-rw-r--r--expr.go3
-rw-r--r--parser.go58
-rw-r--r--rule_parser.go11
-rw-r--r--rule_parser_test.go36
-rw-r--r--testcase/equal_in_target.mk2
8 files changed, 115 insertions, 14 deletions
diff --git a/ast.go b/ast.go
index 665cffd..0831ec1 100644
--- a/ast.go
+++ b/ast.go
@@ -85,8 +85,10 @@ func (ast *assignAST) show() {
// are expanded.
type maybeRuleAST struct {
srcpos
- expr Value
- semi []byte // after ';' if ';' exists
+ isRule bool // found literal ':'
+ expr Value
+ assign *assignAST // target specific var
+ semi []byte // after ';' if ';' exists
}
func (ast *maybeRuleAST) eval(ev *Evaluator) error {
diff --git a/eval.go b/eval.go
index df6fc8d..b031cc0 100644
--- a/eval.go
+++ b/eval.go
@@ -255,6 +255,8 @@ func (ev *Evaluator) evalMaybeRule(ast *maybeRuleAST) error {
ev.lastRule = nil
ev.srcpos = ast.srcpos
+ logf("maybe rule %s: %q assign:%v", ev.srcpos, ast.expr, ast.assign)
+
abuf := newBuf()
aexpr := toExpr(ast.expr)
var rhs expr
@@ -267,10 +269,13 @@ func (ev *Evaluator) evalMaybeRule(ast *maybeRuleAST) error {
return err
}
b := buf.Bytes()
+ if ast.isRule {
+ abuf.Write(b)
+ continue
+ }
eq := findLiteralChar(b, []byte{'='}, true)
if eq >= 0 {
abuf.Write(b[:eq+1])
- rhs = expr{}
if eq+1 < len(b) {
rhs = append(rhs, tmpval(trimLeftSpaceBytes(b[eq+1:])))
}
@@ -293,13 +298,13 @@ func (ev *Evaluator) evalMaybeRule(ast *maybeRuleAST) error {
line := abuf.Bytes()
r := &rule{srcpos: ast.srcpos}
- assign, err := r.parse(line, rhs)
+ assign, err := r.parse(line, ast.assign, rhs)
if err != nil {
return ast.error(err)
}
freeBuf(abuf)
if LogFlag {
- logf("rule %q => outputs:%q, inputs:%q", ast.expr, r.outputs, r.inputs)
+ logf("rule %q assign:%v rhs:%v=> outputs:%q, inputs:%q", ast.expr, ast.assign, rhs, r.outputs, r.inputs)
}
// TODO: Pretty print.
diff --git a/evalcmd.go b/evalcmd.go
index fa704bf..7d15981 100644
--- a/evalcmd.go
+++ b/evalcmd.go
@@ -296,7 +296,7 @@ func createRunners(ctx *execContext, n *DepNode) ([]runner, bool, error) {
restore := ctx.ev.vars.save(k)
defer restore()
ctx.ev.vars[k] = v
- logf("tsv: %s=%s", k, v)
+ logf("set tsv: %s=%s", k, v)
}
ctx.ev.filename = n.Filename
diff --git a/expr.go b/expr.go
index 8bf2ac9..1a38eee 100644
--- a/expr.go
+++ b/expr.go
@@ -124,6 +124,9 @@ func compactExpr(e expr) Value {
return e
}
func toExpr(v Value) expr {
+ if v == nil {
+ return nil
+ }
if e, ok := v.(expr); ok {
return e
}
diff --git a/parser.go b/parser.go
index d8f2487..6b53f6f 100644
--- a/parser.go
+++ b/parser.go
@@ -162,7 +162,8 @@ func (p *parser) handleRuleOrAssign(line []byte) {
if p.handleAssign(line) {
return
}
- // not assignment
+ // not assignment.
+ // ie. no '=' found or ':' found before '=' (except ':=')
p.parseMaybeRule(rline, semi)
return
}
@@ -213,6 +214,54 @@ func (p *parser) parseMaybeRule(line, semi []byte) {
p.err = p.srcpos().errorf("*** commands commence before first target.")
return
}
+ var assign *assignAST
+ ci := findLiteralChar(line, []byte{':'}, true)
+ if ci >= 0 {
+ eqi := findLiteralChar(line[ci+1:], []byte{'='}, true)
+ if eqi == 0 {
+ panic(fmt.Sprintf("unexpected eq after colon: %q", line))
+ }
+ if eqi > 0 {
+ var lhsbytes []byte
+ op := "="
+ switch line[ci+1+eqi-1] {
+ case ':', '+', '?':
+ lhsbytes = append(lhsbytes, line[ci+1:ci+1+eqi-1]...)
+ op = string(line[ci+1+eqi-1 : ci+1+eqi+1])
+ default:
+ lhsbytes = append(lhsbytes, line[ci+1:ci+1+eqi]...)
+ }
+
+ lhsbytes = trimSpaceBytes(lhsbytes)
+ lhs, _, err := parseExpr(lhsbytes, nil, parseOp{})
+ if err != nil {
+ p.err = p.srcpos().error(err)
+ return
+ }
+ var rhsbytes []byte
+ rhsbytes = append(rhsbytes, line[ci+1+eqi+1:]...)
+ if semi != nil {
+ rhsbytes = append(rhsbytes, ';')
+ rhsbytes = append(rhsbytes, concatline(semi)...)
+ }
+ rhsbytes = trimLeftSpaceBytes(rhsbytes)
+ semi = nil
+ rhs, _, err := parseExpr(rhsbytes, nil, parseOp{})
+ if err != nil {
+ p.err = p.srcpos().error(err)
+ return
+ }
+
+ // TODO(ukai): support override, export in target specific var.
+ assign = &assignAST{
+ lhs: lhs,
+ rhs: rhs,
+ op: op,
+ }
+ assign.srcpos = p.srcpos()
+ line = line[:ci+1]
+ }
+ }
expr, _, err := parseExpr(line, nil, parseOp{})
if err != nil {
p.err = p.srcpos().error(err)
@@ -220,10 +269,13 @@ func (p *parser) parseMaybeRule(line, semi []byte) {
}
// TODO(ukai): remove ast, and eval here.
rast := &maybeRuleAST{
- expr: expr,
- semi: semi,
+ isRule: ci >= 0,
+ expr: expr,
+ assign: assign,
+ semi: semi,
}
rast.srcpos = p.srcpos()
+ logf("stmt: %#v", rast)
p.addStatement(rast)
}
diff --git a/rule_parser.go b/rule_parser.go
index 983358a..3b03bab 100644
--- a/rule_parser.go
+++ b/rule_parser.go
@@ -133,8 +133,9 @@ func (r *rule) parseVar(s []byte, rhs expr) (*assignAST, error) {
// parse parses rule line.
// line is rule line until '=', or before ';'
-// rhs is not nil, if line ended with '=' (target specific var)
-func (r *rule) parse(line []byte, rhs expr) (*assignAST, error) {
+// 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) {
var removed bool
line, removed = removeComment(line)
if removed {
@@ -178,6 +179,12 @@ func (r *rule) parse(line []byte, rhs expr) (*assignAST, error) {
}
rest := line[index:]
+ if assign != nil {
+ if len(rest) > 0 {
+ panic(fmt.Sprintf("pattern specific var? line:%q", line))
+ }
+ return assign, nil
+ }
if rhs != nil {
assign, err := r.parseVar(rest, rhs)
if err != nil {
diff --git a/rule_parser_test.go b/rule_parser_test.go
index 93065a3..be12041 100644
--- a/rule_parser_test.go
+++ b/rule_parser_test.go
@@ -22,6 +22,7 @@ import (
func TestRuleParser(t *testing.T) {
for _, tc := range []struct {
in string
+ tsv *assignAST
rhs expr
want rule
assign *assignAST
@@ -110,6 +111,22 @@ func TestRuleParser(t *testing.T) {
},
},
{
+ in: "foo:",
+ tsv: &assignAST{
+ lhs: literal("CFLAGS"),
+ rhs: literal("-g"),
+ op: "=",
+ },
+ want: rule{
+ outputs: []string{"foo"},
+ },
+ assign: &assignAST{
+ lhs: literal("CFLAGS"),
+ rhs: literal("-g"),
+ op: "=",
+ },
+ },
+ {
in: "foo: CFLAGS=",
rhs: expr{literal("-g")},
want: rule{
@@ -146,6 +163,23 @@ func TestRuleParser(t *testing.T) {
op: ":=",
},
},
+ {
+ in: "%.o:",
+ tsv: &assignAST{
+ lhs: literal("CFLAGS"),
+ rhs: literal("-g"),
+ op: ":=",
+ },
+ want: rule{
+ outputs: []string{},
+ outputPatterns: []pattern{pattern{suffix: ".o"}},
+ },
+ assign: &assignAST{
+ lhs: literal("CFLAGS"),
+ rhs: literal("-g"),
+ op: ":=",
+ },
+ },
/* TODO
{
in: "foo.o: %.c: %.c",
@@ -154,7 +188,7 @@ func TestRuleParser(t *testing.T) {
*/
} {
got := &rule{}
- assign, err := got.parse([]byte(tc.in), tc.rhs)
+ assign, err := got.parse([]byte(tc.in), tc.tsv, tc.rhs)
if tc.err != "" {
if err == nil {
t.Errorf(`r.parse(%q, %v)=_, <nil>, want _, %q`, tc.in, tc.rhs, tc.err)
diff --git a/testcase/equal_in_target.mk b/testcase/equal_in_target.mk
index 8aceb50..faf532c 100644
--- a/testcase/equal_in_target.mk
+++ b/testcase/equal_in_target.mk
@@ -1,5 +1,3 @@
-# TODO: Fix
-
TSV:=test: A=PASS
A_EQ_B:=A=B
EQ==