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 15 package kati 16 17 import ( 18 "bytes" 19 "fmt" 20 "io" 21 "strings" 22 ) 23 24 // Var is an interface of make variable. 25 type Var interface { 26 Value 27 Append(*Evaluator, string) (Var, error) 28 AppendVar(*Evaluator, Value) (Var, error) 29 Flavor() string 30 Origin() string 31 IsDefined() bool 32 } 33 34 type targetSpecificVar struct { 35 v Var 36 op string 37 } 38 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 43 } 44 return &targetSpecificVar{ 45 v: nv, 46 op: v.op, 47 }, nil 48 } 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 53 } 54 return &targetSpecificVar{ 55 v: nv, 56 op: v.op, 57 }, nil 58 } 59 func (v *targetSpecificVar) Flavor() string { 60 return v.v.Flavor() 61 } 62 func (v *targetSpecificVar) Origin() string { 63 return v.v.Origin() 64 } 65 func (v *targetSpecificVar) IsDefined() bool { 66 return v.v.IsDefined() 67 } 68 func (v *targetSpecificVar) String() string { 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 } 74 func (v *targetSpecificVar) Eval(w evalWriter, ev *Evaluator) error { 75 return v.v.Eval(w, ev) 76 } 77 78 func (v *targetSpecificVar) serialize() serializableVar { 79 return serializableVar{ 80 Type: v.op, 81 Children: []serializableVar{v.v.serialize()}, 82 } 83 } 84 85 func (v *targetSpecificVar) dump(d *dumpbuf) { 86 d.Byte(valueTypeTSV) 87 d.Str(v.op) 88 v.v.dump(d) 89 } 90 91 type simpleVar struct { 92 // space separated. note that each string may contain spaces, so 93 // it is not word list. 94 value []string 95 origin string 96 } 97 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 } 101 102 func (v *simpleVar) String() string { return strings.Join(v.value, " ") } 103 func (v *simpleVar) Eval(w evalWriter, ev *Evaluator) error { 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 } 112 return nil 113 } 114 func (v *simpleVar) serialize() serializableVar { 115 return serializableVar{ 116 Type: "simple", 117 V: v.String(), 118 Origin: v.origin, 119 } 120 } 121 func (v *simpleVar) dump(d *dumpbuf) { 122 d.Byte(valueTypeSimple) 123 d.Int(len(v.value)) 124 for _, v := range v.value { 125 d.Str(v) 126 } 127 d.Str(v.origin) 128 } 129 130 func (v *simpleVar) Append(ev *Evaluator, s string) (Var, error) { 131 val, _, err := parseExpr([]byte(s), nil, parseOp{}) 132 if err != nil { 133 return nil, err 134 } 135 abuf := newEbuf() 136 err = val.Eval(abuf, ev) 137 if err != nil { 138 return nil, err 139 } 140 v.value = append(v.value, abuf.String()) 141 abuf.release() 142 return v, nil 143 } 144 145 func (v *simpleVar) AppendVar(ev *Evaluator, val Value) (Var, error) { 146 abuf := newEbuf() 147 err := val.Eval(abuf, ev) 148 if err != nil { 149 return nil, err 150 } 151 v.value = append(v.value, abuf.String()) 152 abuf.release() 153 return v, nil 154 } 155 156 type automaticVar struct { 157 value []byte 158 } 159 160 func (v *automaticVar) Flavor() string { return "simple" } 161 func (v *automaticVar) Origin() string { return "automatic" } 162 func (v *automaticVar) IsDefined() bool { return true } 163 164 func (v *automaticVar) String() string { return string(v.value) } 165 func (v *automaticVar) Eval(w evalWriter, ev *Evaluator) error { 166 w.Write(v.value) 167 return nil 168 } 169 func (v *automaticVar) serialize() serializableVar { 170 return serializableVar{Type: ""} 171 } 172 func (v *automaticVar) dump(d *dumpbuf) { 173 d.err = fmt.Errorf("cannnot dump automatic var:%s", v.value) 174 } 175 176 func (v *automaticVar) Append(ev *Evaluator, s string) (Var, error) { 177 val, _, err := parseExpr([]byte(s), nil, parseOp{}) 178 if err != nil { 179 return nil, err 180 } 181 abuf := newEbuf() 182 err = val.Eval(abuf, ev) 183 if err != nil { 184 return nil, err 185 } 186 value := []string{string(v.value), abuf.String()} 187 abuf.release() 188 return &simpleVar{ 189 value: value, 190 origin: "file", 191 }, nil 192 } 193 194 func (v *automaticVar) AppendVar(ev *Evaluator, val Value) (Var, error) { 195 abuf := newEbuf() 196 err := val.Eval(abuf, ev) 197 if err != nil { 198 return nil, err 199 } 200 value := []string{string(v.value), abuf.String()} 201 abuf.release() 202 return &simpleVar{ 203 value: value, 204 origin: "file", 205 }, nil 206 } 207 208 type recursiveVar struct { 209 expr Value 210 origin string 211 } 212 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 } 216 217 func (v *recursiveVar) String() string { return v.expr.String() } 218 func (v *recursiveVar) Eval(w evalWriter, ev *Evaluator) error { 219 v.expr.Eval(w, ev) 220 return nil 221 } 222 func (v *recursiveVar) serialize() serializableVar { 223 return serializableVar{ 224 Type: "recursive", 225 Children: []serializableVar{v.expr.serialize()}, 226 Origin: v.origin, 227 } 228 } 229 func (v *recursiveVar) dump(d *dumpbuf) { 230 d.Byte(valueTypeRecursive) 231 v.expr.dump(d) 232 d.Str(v.origin) 233 } 234 235 func (v *recursiveVar) Append(_ *Evaluator, s string) (Var, error) { 236 var exp expr 237 if e, ok := v.expr.(expr); ok { 238 exp = append(e, literal(" ")) 239 } else { 240 exp = expr{v.expr, literal(" ")} 241 } 242 sv, _, err := parseExpr([]byte(s), nil, parseOp{alloc: true}) 243 if err != nil { 244 return nil, err 245 } 246 if aexpr, ok := sv.(expr); ok { 247 exp = append(exp, aexpr...) 248 } else { 249 exp = append(exp, sv) 250 } 251 v.expr = exp 252 return v, nil 253 } 254 255 func (v *recursiveVar) AppendVar(ev *Evaluator, val Value) (Var, error) { 256 var buf bytes.Buffer 257 buf.WriteString(v.expr.String()) 258 buf.WriteByte(' ') 259 buf.WriteString(val.String()) 260 e, _, err := parseExpr(buf.Bytes(), nil, parseOp{alloc: true}) 261 if err != nil { 262 return nil, err 263 } 264 v.expr = e 265 return v, nil 266 } 267 268 type undefinedVar struct{} 269 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 "" } 274 func (undefinedVar) Eval(_ evalWriter, _ *Evaluator) error { 275 return nil 276 } 277 func (undefinedVar) serialize() serializableVar { 278 return serializableVar{Type: "undefined"} 279 } 280 func (undefinedVar) dump(d *dumpbuf) { 281 d.Byte(valueTypeUndefined) 282 } 283 284 func (undefinedVar) Append(*Evaluator, string) (Var, error) { 285 return undefinedVar{}, nil 286 } 287 288 func (undefinedVar) AppendVar(_ *Evaluator, val Value) (Var, error) { 289 return undefinedVar{}, nil 290 } 291 292 // Vars is a map for make variables. 293 type Vars map[string]Var 294 295 // usedEnvs tracks what environment variables are used. 296 var usedEnvs = map[string]bool{} 297 298 // Lookup looks up named make variable. 299 func (vt Vars) Lookup(name string) Var { 300 if v, ok := vt[name]; ok { 301 if strings.HasPrefix(v.Origin(), "environment") { 302 usedEnvs[name] = true 303 } 304 return v 305 } 306 return undefinedVar{} 307 } 308 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{ 317 "override": 4, 318 "environment override": 4, 319 "command line": 3, 320 "file": 2, 321 "environment": 2, 322 "default": 1, 323 "undefined": 0, 324 "automatic": 0, 325 } 326 327 // Assign assigns v to name. 328 func (vt Vars) Assign(name string, v Var) { 329 vo := v.Origin() 330 // assign automatic always win. 331 // assign new value to automatic always win. 332 if vo != "automatic" { 333 vp := originPrecedence[v.Origin()] 334 var op int 335 if ov, ok := vt[name]; ok { 336 op = originPrecedence[ov.Origin()] 337 } 338 if op > vp { 339 return 340 } 341 } 342 vt[name] = v 343 } 344 345 // NewVars creates new Vars. 346 func NewVars(vt Vars) Vars { 347 r := make(Vars) 348 r.Merge(vt) 349 return r 350 } 351 352 // Merge merges vt2 into vt. 353 func (vt Vars) Merge(vt2 Vars) { 354 for k, v := range vt2 { 355 vt[k] = v 356 } 357 } 358 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() { 363 if v, ok := vt[name]; ok { 364 return func() { 365 vt[name] = v 366 } 367 } 368 return func() { 369 delete(vt, name) 370 } 371 } 372