Shinichiro Hamaji | b69bf8a | 2015-06-10 14:52:06 +0900 | [diff] [blame] | 1 | // Copyright 2015 Google Inc. All rights reserved |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Fumitoshi Ukai | 744bb2b | 2015-06-25 00:10:52 +0900 | [diff] [blame] | 15 | package kati |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 16 | |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 17 | import ( |
| 18 | "bytes" |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 19 | "fmt" |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 20 | "io" |
Fumitoshi Ukai | b5612a8 | 2015-07-14 13:22:17 +0900 | [diff] [blame] | 21 | "strings" |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 22 | ) |
| 23 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 24 | // Var is an interface of make variable. |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 25 | type Var interface { |
| 26 | Value |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 27 | Append(*Evaluator, string) (Var, error) |
| 28 | AppendVar(*Evaluator, Value) (Var, error) |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 29 | Flavor() string |
| 30 | Origin() string |
| 31 | IsDefined() bool |
| 32 | } |
| 33 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 34 | type targetSpecificVar struct { |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 35 | v Var |
| 36 | op string |
| 37 | } |
| 38 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 39 | func (v *targetSpecificVar) Append(ev *Evaluator, s string) (Var, error) { |
| 40 | nv, err := v.v.Append(ev, s) |
| 41 | if err != nil { |
| 42 | return nil, err |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 43 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 44 | return &targetSpecificVar{ |
| 45 | v: nv, |
| 46 | op: v.op, |
| 47 | }, nil |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 48 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 49 | func (v *targetSpecificVar) AppendVar(ev *Evaluator, v2 Value) (Var, error) { |
| 50 | nv, err := v.v.AppendVar(ev, v2) |
| 51 | if err != nil { |
| 52 | return nil, err |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 53 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 54 | return &targetSpecificVar{ |
| 55 | v: nv, |
| 56 | op: v.op, |
| 57 | }, nil |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 58 | } |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 59 | func (v *targetSpecificVar) Flavor() string { |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 60 | return v.v.Flavor() |
| 61 | } |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 62 | func (v *targetSpecificVar) Origin() string { |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 63 | return v.v.Origin() |
| 64 | } |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 65 | func (v *targetSpecificVar) IsDefined() bool { |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 66 | return v.v.IsDefined() |
| 67 | } |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 68 | func (v *targetSpecificVar) String() string { |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 69 | // TODO: If we add the info of |op| a test starts |
| 70 | // failing. Shouldn't we use this only for debugging? |
| 71 | return v.v.String() |
| 72 | // return v.v.String() + " (op=" + v.op + ")" |
| 73 | } |
Fumitoshi Ukai | b44b12d | 2015-07-07 14:19:32 +0900 | [diff] [blame] | 74 | func (v *targetSpecificVar) Eval(w evalWriter, ev *Evaluator) error { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 75 | return v.v.Eval(w, ev) |
Shinichiro Hamaji | a485d2f | 2015-04-16 14:03:24 +0900 | [diff] [blame] | 76 | } |
| 77 | |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 78 | func (v *targetSpecificVar) serialize() serializableVar { |
| 79 | return serializableVar{ |
Shinichiro Hamaji | 3d6d0aa | 2015-04-28 16:18:44 +0900 | [diff] [blame] | 80 | Type: v.op, |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 81 | Children: []serializableVar{v.v.serialize()}, |
Shinichiro Hamaji | 8c9d0e3 | 2015-04-28 03:30:19 +0900 | [diff] [blame] | 82 | } |
Shinichiro Hamaji | c8bc731 | 2015-04-28 02:48:03 +0900 | [diff] [blame] | 83 | } |
| 84 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 85 | func (v *targetSpecificVar) dump(d *dumpbuf) { |
| 86 | d.Byte(valueTypeTSV) |
| 87 | d.Str(v.op) |
| 88 | v.v.dump(d) |
Shinichiro Hamaji | 723f56a | 2015-05-15 17:12:55 +0900 | [diff] [blame] | 89 | } |
| 90 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 91 | type simpleVar struct { |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 92 | // space separated. note that each string may contain spaces, so |
| 93 | // it is not word list. |
| 94 | value []string |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 95 | origin string |
| 96 | } |
| 97 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 98 | func (v *simpleVar) Flavor() string { return "simple" } |
| 99 | func (v *simpleVar) Origin() string { return v.origin } |
| 100 | func (v *simpleVar) IsDefined() bool { return true } |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 101 | |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 102 | func (v *simpleVar) String() string { return strings.Join(v.value, " ") } |
Fumitoshi Ukai | b44b12d | 2015-07-07 14:19:32 +0900 | [diff] [blame] | 103 | func (v *simpleVar) Eval(w evalWriter, ev *Evaluator) error { |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 104 | space := false |
| 105 | for _, v := range v.value { |
| 106 | if space { |
| 107 | writeByte(w, ' ') |
| 108 | } |
| 109 | io.WriteString(w, v) |
| 110 | space = true |
| 111 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 112 | return nil |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 113 | } |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 114 | func (v *simpleVar) serialize() serializableVar { |
| 115 | return serializableVar{ |
Shinichiro Hamaji | 3d6d0aa | 2015-04-28 16:18:44 +0900 | [diff] [blame] | 116 | Type: "simple", |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 117 | V: v.String(), |
Shinichiro Hamaji | c8bc731 | 2015-04-28 02:48:03 +0900 | [diff] [blame] | 118 | Origin: v.origin, |
| 119 | } |
| 120 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 121 | func (v *simpleVar) dump(d *dumpbuf) { |
| 122 | d.Byte(valueTypeSimple) |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 123 | d.Int(len(v.value)) |
| 124 | for _, v := range v.value { |
| 125 | d.Str(v) |
| 126 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 127 | d.Str(v.origin) |
Shinichiro Hamaji | 723f56a | 2015-05-15 17:12:55 +0900 | [diff] [blame] | 128 | } |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 129 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 130 | func (v *simpleVar) Append(ev *Evaluator, s string) (Var, error) { |
Fumitoshi Ukai | e9aa380 | 2015-07-03 11:33:23 +0900 | [diff] [blame] | 131 | val, _, err := parseExpr([]byte(s), nil, parseOp{}) |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 132 | if err != nil { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 133 | return nil, err |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 134 | } |
Fumitoshi Ukai | a4a0225 | 2015-07-09 14:25:18 +0900 | [diff] [blame] | 135 | abuf := newEbuf() |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 136 | err = val.Eval(abuf, ev) |
| 137 | if err != nil { |
| 138 | return nil, err |
| 139 | } |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 140 | v.value = append(v.value, abuf.String()) |
Fumitoshi Ukai | a4a0225 | 2015-07-09 14:25:18 +0900 | [diff] [blame] | 141 | abuf.release() |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 142 | return v, nil |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 143 | } |
| 144 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 145 | func (v *simpleVar) AppendVar(ev *Evaluator, val Value) (Var, error) { |
Fumitoshi Ukai | a4a0225 | 2015-07-09 14:25:18 +0900 | [diff] [blame] | 146 | abuf := newEbuf() |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 147 | err := val.Eval(abuf, ev) |
| 148 | if err != nil { |
| 149 | return nil, err |
| 150 | } |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 151 | v.value = append(v.value, abuf.String()) |
Fumitoshi Ukai | a4a0225 | 2015-07-09 14:25:18 +0900 | [diff] [blame] | 152 | abuf.release() |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 153 | return v, nil |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 154 | } |
| 155 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 156 | type automaticVar struct { |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 157 | value []byte |
| 158 | } |
| 159 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 160 | func (v *automaticVar) Flavor() string { return "simple" } |
| 161 | func (v *automaticVar) Origin() string { return "automatic" } |
| 162 | func (v *automaticVar) IsDefined() bool { return true } |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 163 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 164 | func (v *automaticVar) String() string { return string(v.value) } |
Fumitoshi Ukai | b44b12d | 2015-07-07 14:19:32 +0900 | [diff] [blame] | 165 | func (v *automaticVar) Eval(w evalWriter, ev *Evaluator) error { |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 166 | w.Write(v.value) |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 167 | return nil |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 168 | } |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 169 | func (v *automaticVar) serialize() serializableVar { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 170 | return serializableVar{Type: ""} |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 171 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 172 | func (v *automaticVar) dump(d *dumpbuf) { |
| 173 | d.err = fmt.Errorf("cannnot dump automatic var:%s", v.value) |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 174 | } |
| 175 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 176 | func (v *automaticVar) Append(ev *Evaluator, s string) (Var, error) { |
Fumitoshi Ukai | e9aa380 | 2015-07-03 11:33:23 +0900 | [diff] [blame] | 177 | val, _, err := parseExpr([]byte(s), nil, parseOp{}) |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 178 | if err != nil { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 179 | return nil, err |
Fumitoshi Ukai | dd248f2 | 2015-06-18 23:04:28 +0900 | [diff] [blame] | 180 | } |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 181 | abuf := newEbuf() |
| 182 | err = val.Eval(abuf, ev) |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 183 | if err != nil { |
| 184 | return nil, err |
| 185 | } |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 186 | value := []string{string(v.value), abuf.String()} |
| 187 | abuf.release() |
Fumitoshi Ukai | 2142617 | 2015-06-30 18:02:45 +0900 | [diff] [blame] | 188 | return &simpleVar{ |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 189 | value: value, |
Fumitoshi Ukai | 2142617 | 2015-06-30 18:02:45 +0900 | [diff] [blame] | 190 | origin: "file", |
| 191 | }, nil |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 192 | } |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 193 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 194 | func (v *automaticVar) AppendVar(ev *Evaluator, val Value) (Var, error) { |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 195 | abuf := newEbuf() |
| 196 | err := val.Eval(abuf, ev) |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 197 | if err != nil { |
| 198 | return nil, err |
| 199 | } |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 200 | value := []string{string(v.value), abuf.String()} |
| 201 | abuf.release() |
Fumitoshi Ukai | 2142617 | 2015-06-30 18:02:45 +0900 | [diff] [blame] | 202 | return &simpleVar{ |
Fumitoshi Ukai | 7655f18 | 2015-07-15 14:05:41 +0900 | [diff] [blame] | 203 | value: value, |
Fumitoshi Ukai | 2142617 | 2015-06-30 18:02:45 +0900 | [diff] [blame] | 204 | origin: "file", |
| 205 | }, nil |
Shinichiro Hamaji | ea170b1 | 2015-04-15 10:02:33 +0900 | [diff] [blame] | 206 | } |
| 207 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 208 | type recursiveVar struct { |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 209 | expr Value |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 210 | origin string |
| 211 | } |
| 212 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 213 | func (v *recursiveVar) Flavor() string { return "recursive" } |
| 214 | func (v *recursiveVar) Origin() string { return v.origin } |
| 215 | func (v *recursiveVar) IsDefined() bool { return true } |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 216 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 217 | func (v *recursiveVar) String() string { return v.expr.String() } |
Fumitoshi Ukai | b44b12d | 2015-07-07 14:19:32 +0900 | [diff] [blame] | 218 | func (v *recursiveVar) Eval(w evalWriter, ev *Evaluator) error { |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 219 | v.expr.Eval(w, ev) |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 220 | return nil |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 221 | } |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 222 | func (v *recursiveVar) serialize() serializableVar { |
| 223 | return serializableVar{ |
Shinichiro Hamaji | 3d6d0aa | 2015-04-28 16:18:44 +0900 | [diff] [blame] | 224 | Type: "recursive", |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 225 | Children: []serializableVar{v.expr.serialize()}, |
Shinichiro Hamaji | 3d6d0aa | 2015-04-28 16:18:44 +0900 | [diff] [blame] | 226 | Origin: v.origin, |
Shinichiro Hamaji | c8bc731 | 2015-04-28 02:48:03 +0900 | [diff] [blame] | 227 | } |
| 228 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 229 | func (v *recursiveVar) dump(d *dumpbuf) { |
| 230 | d.Byte(valueTypeRecursive) |
| 231 | v.expr.dump(d) |
| 232 | d.Str(v.origin) |
Shinichiro Hamaji | 723f56a | 2015-05-15 17:12:55 +0900 | [diff] [blame] | 233 | } |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 234 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 235 | func (v *recursiveVar) Append(_ *Evaluator, s string) (Var, error) { |
Fumitoshi Ukai | 55c8fa9 | 2015-06-25 15:56:10 +0900 | [diff] [blame] | 236 | var exp expr |
| 237 | if e, ok := v.expr.(expr); ok { |
| 238 | exp = append(e, literal(" ")) |
Fumitoshi Ukai | f360910 | 2015-04-19 23:06:54 +0900 | [diff] [blame] | 239 | } else { |
Fumitoshi Ukai | 55c8fa9 | 2015-06-25 15:56:10 +0900 | [diff] [blame] | 240 | exp = expr{v.expr, literal(" ")} |
Fumitoshi Ukai | f360910 | 2015-04-19 23:06:54 +0900 | [diff] [blame] | 241 | } |
Fumitoshi Ukai | e9aa380 | 2015-07-03 11:33:23 +0900 | [diff] [blame] | 242 | sv, _, err := parseExpr([]byte(s), nil, parseOp{alloc: true}) |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 243 | if err != nil { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 244 | return nil, err |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 245 | } |
Fumitoshi Ukai | 55c8fa9 | 2015-06-25 15:56:10 +0900 | [diff] [blame] | 246 | if aexpr, ok := sv.(expr); ok { |
| 247 | exp = append(exp, aexpr...) |
Fumitoshi Ukai | f360910 | 2015-04-19 23:06:54 +0900 | [diff] [blame] | 248 | } else { |
Fumitoshi Ukai | 55c8fa9 | 2015-06-25 15:56:10 +0900 | [diff] [blame] | 249 | exp = append(exp, sv) |
Fumitoshi Ukai | f360910 | 2015-04-19 23:06:54 +0900 | [diff] [blame] | 250 | } |
Fumitoshi Ukai | 55c8fa9 | 2015-06-25 15:56:10 +0900 | [diff] [blame] | 251 | v.expr = exp |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 252 | return v, nil |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 253 | } |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 254 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 255 | func (v *recursiveVar) AppendVar(ev *Evaluator, val Value) (Var, error) { |
Shinichiro Hamaji | ea170b1 | 2015-04-15 10:02:33 +0900 | [diff] [blame] | 256 | var buf bytes.Buffer |
| 257 | buf.WriteString(v.expr.String()) |
| 258 | buf.WriteByte(' ') |
| 259 | buf.WriteString(val.String()) |
Fumitoshi Ukai | e9aa380 | 2015-07-03 11:33:23 +0900 | [diff] [blame] | 260 | e, _, err := parseExpr(buf.Bytes(), nil, parseOp{alloc: true}) |
Shinichiro Hamaji | ea170b1 | 2015-04-15 10:02:33 +0900 | [diff] [blame] | 261 | if err != nil { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 262 | return nil, err |
Shinichiro Hamaji | ea170b1 | 2015-04-15 10:02:33 +0900 | [diff] [blame] | 263 | } |
| 264 | v.expr = e |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 265 | return v, nil |
Shinichiro Hamaji | ea170b1 | 2015-04-15 10:02:33 +0900 | [diff] [blame] | 266 | } |
| 267 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 268 | type undefinedVar struct{} |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 269 | |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 270 | func (undefinedVar) Flavor() string { return "undefined" } |
| 271 | func (undefinedVar) Origin() string { return "undefined" } |
| 272 | func (undefinedVar) IsDefined() bool { return false } |
| 273 | func (undefinedVar) String() string { return "" } |
Fumitoshi Ukai | b44b12d | 2015-07-07 14:19:32 +0900 | [diff] [blame] | 274 | func (undefinedVar) Eval(_ evalWriter, _ *Evaluator) error { |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 275 | return nil |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 276 | } |
Fumitoshi Ukai | a045ccb | 2015-06-25 12:57:25 +0900 | [diff] [blame] | 277 | func (undefinedVar) serialize() serializableVar { |
| 278 | return serializableVar{Type: "undefined"} |
Shinichiro Hamaji | c8bc731 | 2015-04-28 02:48:03 +0900 | [diff] [blame] | 279 | } |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 280 | func (undefinedVar) dump(d *dumpbuf) { |
| 281 | d.Byte(valueTypeUndefined) |
Shinichiro Hamaji | 723f56a | 2015-05-15 17:12:55 +0900 | [diff] [blame] | 282 | } |
Fumitoshi Ukai | b36f387 | 2015-04-10 15:06:38 +0900 | [diff] [blame] | 283 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 284 | func (undefinedVar) Append(*Evaluator, string) (Var, error) { |
| 285 | return undefinedVar{}, nil |
Fumitoshi Ukai | c184760 | 2015-04-02 16:18:02 +0900 | [diff] [blame] | 286 | } |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 287 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 288 | func (undefinedVar) AppendVar(_ *Evaluator, val Value) (Var, error) { |
| 289 | return undefinedVar{}, nil |
Shinichiro Hamaji | ea170b1 | 2015-04-15 10:02:33 +0900 | [diff] [blame] | 290 | } |
| 291 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 292 | // Vars is a map for make variables. |
Shinichiro Hamaji | cc919ae | 2015-04-09 17:23:30 +0900 | [diff] [blame] | 293 | type Vars map[string]Var |
| 294 | |
Fumitoshi Ukai | b5612a8 | 2015-07-14 13:22:17 +0900 | [diff] [blame] | 295 | // usedEnvs tracks what environment variables are used. |
| 296 | var usedEnvs = map[string]bool{} |
| 297 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 298 | // Lookup looks up named make variable. |
Shinichiro Hamaji | cc919ae | 2015-04-09 17:23:30 +0900 | [diff] [blame] | 299 | func (vt Vars) Lookup(name string) Var { |
| 300 | if v, ok := vt[name]; ok { |
Fumitoshi Ukai | b5612a8 | 2015-07-14 13:22:17 +0900 | [diff] [blame] | 301 | if strings.HasPrefix(v.Origin(), "environment") { |
| 302 | usedEnvs[name] = true |
| 303 | } |
Shinichiro Hamaji | cc919ae | 2015-04-09 17:23:30 +0900 | [diff] [blame] | 304 | return v |
| 305 | } |
Fumitoshi Ukai | 7bf992d | 2015-06-25 12:42:19 +0900 | [diff] [blame] | 306 | return undefinedVar{} |
Shinichiro Hamaji | cc919ae | 2015-04-09 17:23:30 +0900 | [diff] [blame] | 307 | } |
| 308 | |
Fumitoshi Ukai | 38c46a7 | 2015-06-30 17:25:14 +0900 | [diff] [blame] | 309 | // origin precedence |
| 310 | // override / environment override |
| 311 | // command line |
| 312 | // file |
| 313 | // environment |
| 314 | // default |
| 315 | // TODO(ukai): is this correct order? |
| 316 | var originPrecedence = map[string]int{ |
Fumitoshi Ukai | 38c46a7 | 2015-06-30 17:25:14 +0900 | [diff] [blame] | 317 | "override": 4, |
| 318 | "environment override": 4, |
| 319 | "command line": 3, |
| 320 | "file": 2, |
| 321 | "environment": 2, |
| 322 | "default": 1, |
| 323 | "undefined": 0, |
Fumitoshi Ukai | 2142617 | 2015-06-30 18:02:45 +0900 | [diff] [blame] | 324 | "automatic": 0, |
Fumitoshi Ukai | 38c46a7 | 2015-06-30 17:25:14 +0900 | [diff] [blame] | 325 | } |
| 326 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 327 | // Assign assigns v to name. |
Shinichiro Hamaji | cc919ae | 2015-04-09 17:23:30 +0900 | [diff] [blame] | 328 | func (vt Vars) Assign(name string, v Var) { |
Fumitoshi Ukai | 38c46a7 | 2015-06-30 17:25:14 +0900 | [diff] [blame] | 329 | vo := v.Origin() |
Fumitoshi Ukai | 2142617 | 2015-06-30 18:02:45 +0900 | [diff] [blame] | 330 | // assign automatic always win. |
| 331 | // assign new value to automatic always win. |
Fumitoshi Ukai | 38c46a7 | 2015-06-30 17:25:14 +0900 | [diff] [blame] | 332 | if vo != "automatic" { |
| 333 | vp := originPrecedence[v.Origin()] |
| 334 | var op int |
Fumitoshi Ukai | f59f9f9 | 2015-06-18 15:51:55 +0900 | [diff] [blame] | 335 | if ov, ok := vt[name]; ok { |
Fumitoshi Ukai | 38c46a7 | 2015-06-30 17:25:14 +0900 | [diff] [blame] | 336 | op = originPrecedence[ov.Origin()] |
| 337 | } |
| 338 | if op > vp { |
| 339 | return |
Fumitoshi Ukai | 8ae323b | 2015-04-08 17:44:38 +0900 | [diff] [blame] | 340 | } |
| 341 | } |
Shinichiro Hamaji | cc919ae | 2015-04-09 17:23:30 +0900 | [diff] [blame] | 342 | vt[name] = v |
| 343 | } |
| 344 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 345 | // NewVars creates new Vars. |
Shinichiro Hamaji | 63a77d4 | 2015-04-12 01:04:07 +0900 | [diff] [blame] | 346 | func NewVars(vt Vars) Vars { |
| 347 | r := make(Vars) |
| 348 | r.Merge(vt) |
| 349 | return r |
Fumitoshi Ukai | 8edcb79 | 2015-04-02 11:23:23 +0900 | [diff] [blame] | 350 | } |
Shinichiro Hamaji | 03a6f6d | 2015-04-07 03:59:41 +0900 | [diff] [blame] | 351 | |
Fumitoshi Ukai | 65c7233 | 2015-06-26 21:32:50 +0900 | [diff] [blame] | 352 | // Merge merges vt2 into vt. |
Shinichiro Hamaji | 63a77d4 | 2015-04-12 01:04:07 +0900 | [diff] [blame] | 353 | func (vt Vars) Merge(vt2 Vars) { |
| 354 | for k, v := range vt2 { |
| 355 | vt[k] = v |
| 356 | } |
Shinichiro Hamaji | 03a6f6d | 2015-04-07 03:59:41 +0900 | [diff] [blame] | 357 | } |
Shinichiro Hamaji | 4e9ab1a | 2015-04-12 01:31:58 +0900 | [diff] [blame] | 358 | |
Fumitoshi Ukai | 9b10ecf | 2015-04-15 17:45:50 +0900 | [diff] [blame] | 359 | // save saves value of the variable named name. |
| 360 | // calling returned value will restore to the old value at the time |
| 361 | // when save called. |
| 362 | func (vt Vars) save(name string) func() { |
Fumitoshi Ukai | 5a37459 | 2015-06-18 22:40:45 +0900 | [diff] [blame] | 363 | if v, ok := vt[name]; ok { |
Fumitoshi Ukai | 9b10ecf | 2015-04-15 17:45:50 +0900 | [diff] [blame] | 364 | return func() { |
| 365 | vt[name] = v |
| 366 | } |
Shinichiro Hamaji | 4e9ab1a | 2015-04-12 01:31:58 +0900 | [diff] [blame] | 367 | } |
Fumitoshi Ukai | 9b10ecf | 2015-04-15 17:45:50 +0900 | [diff] [blame] | 368 | return func() { |
| 369 | delete(vt, name) |
Shinichiro Hamaji | 4e9ab1a | 2015-04-12 01:31:58 +0900 | [diff] [blame] | 370 | } |
Shinichiro Hamaji | 4e9ab1a | 2015-04-12 01:31:58 +0900 | [diff] [blame] | 371 | } |