blob: c7ee1bd21aeaca00ab391dccd45319c91275f4f0 [file] [log] [blame]
Shinichiro Hamaji04932612015-03-31 23:46:56 +09001package main
2
3import (
4 "strings"
5)
6
7type Rule struct {
Shinichiro Hamaji5c53b572015-04-02 05:36:42 +09008 outputs []string
9 inputs []string
10 orderOnlyInputs []string
11 outputPatterns []string
12 isDoubleColon bool
13 isSuffixRule bool
14 cmds []string
15 filename string
16 lineno int
17 cmdLineno int
Shinichiro Hamaji04932612015-03-31 23:46:56 +090018}
19
Shinichiro Hamaji21a9b5f2015-04-01 02:42:59 +090020func isPatternRule(s string) bool {
21 return strings.IndexByte(s, '%') >= 0
22}
23
Shinichiro Hamaji5c53b572015-04-02 05:36:42 +090024func (r *Rule) parseInputs(s string) {
25 inputs := splitSpaces(s)
26 isOrderOnly := false
27 for _, input := range inputs {
28 if input == "|" {
29 isOrderOnly = true
30 continue
31 }
32 if isOrderOnly {
33 r.orderOnlyInputs = append(r.orderOnlyInputs, input)
34 } else {
35 r.inputs = append(r.inputs, input)
36 }
37 }
38}
39
Shinichiro Hamaji21a9b5f2015-04-01 02:42:59 +090040func (r *Rule) parse(line string) string {
41 index := strings.IndexByte(line, ':')
42 if index < 0 {
43 return "*** missing separator."
Shinichiro Hamaji04932612015-03-31 23:46:56 +090044 }
45
Shinichiro Hamaji21a9b5f2015-04-01 02:42:59 +090046 first := line[:index]
47 outputs := splitSpaces(first)
48 isFirstPattern := isPatternRule(first)
49 if isFirstPattern {
50 if len(outputs) > 1 {
51 return "*** mixed implicit and normal rules: deprecated syntax"
52 }
53 r.outputPatterns = outputs
54 } else {
55 r.outputs = outputs
56 }
57
58 index++
59 if index < len(line) && line[index] == ':' {
60 r.isDoubleColon = true
61 index++
62 }
63
64 rest := line[index:]
65 index = strings.IndexByte(rest, ':')
66 if index < 0 {
Shinichiro Hamaji5c53b572015-04-02 05:36:42 +090067 r.parseInputs(rest)
Shinichiro Hamaji21a9b5f2015-04-01 02:42:59 +090068 return ""
69 }
70
71 // %.x: %.y: %.z
72 if isFirstPattern {
73 return "*** mixed implicit and normal rules: deprecated syntax"
74 }
75
76 second := rest[:index]
77 third := rest[index+1:]
78
79 r.outputs = outputs
80 r.outputPatterns = splitSpaces(second)
81 if len(r.outputPatterns) == 0 {
82 return "*** missing target pattern."
83 }
84 if len(r.outputPatterns) > 1 {
85 return "*** multiple target patterns."
86 }
87 if !isPatternRule(r.outputPatterns[0]) {
88 return "*** target pattern contains no '%'."
89 }
Shinichiro Hamaji5c53b572015-04-02 05:36:42 +090090 r.parseInputs(third)
Shinichiro Hamaji21a9b5f2015-04-01 02:42:59 +090091
92 return ""
Shinichiro Hamaji04932612015-03-31 23:46:56 +090093}