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 15package kati 16 17import ( 18 "bytes" 19 "fmt" 20 "io" 21 "strings" 22) 23 24// Var is an interface of make variable. 25type 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 34type targetSpecificVar struct { 35 v Var 36 op string 37} 38 39func (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} 49func (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} 59func (v *targetSpecificVar) Flavor() string { 60 return v.v.Flavor() 61} 62func (v *targetSpecificVar) Origin() string { 63 return v.v.Origin() 64} 65func (v *targetSpecificVar) IsDefined() bool { 66 return v.v.IsDefined() 67} 68func (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} 74func (v *targetSpecificVar) Eval(w evalWriter, ev *Evaluator) error { 75 return v.v.Eval(w, ev) 76} 77 78func (v *targetSpecificVar) serialize() serializableVar { 79 return serializableVar{ 80 Type: v.op, 81 Children: []serializableVar{v.v.serialize()}, 82 } 83} 84 85func (v *targetSpecificVar) dump(d *dumpbuf) { 86 d.Byte(valueTypeTSV) 87 d.Str(v.op) 88 v.v.dump(d) 89} 90 91type 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 98func (v *simpleVar) Flavor() string { return "simple" } 99func (v *simpleVar) Origin() string { return v.origin } 100func (v *simpleVar) IsDefined() bool { return true } 101 102func (v *simpleVar) String() string { return strings.Join(v.value, " ") } 103func (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} 114func (v *simpleVar) serialize() serializableVar { 115 return serializableVar{ 116 Type: "simple", 117 V: v.String(), 118 Origin: v.origin, 119 } 120} 121func (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 130func (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 145func (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 156type automaticVar struct { 157 value []byte 158} 159 160func (v *automaticVar) Flavor() string { return "simple" } 161func (v *automaticVar) Origin() string { return "automatic" } 162func (v *automaticVar) IsDefined() bool { return true } 163 164func (v *automaticVar) String() string { return string(v.value) } 165func (v *automaticVar) Eval(w evalWriter, ev *Evaluator) error { 166 w.Write(v.value) 167 return nil 168} 169func (v *automaticVar) serialize() serializableVar { 170 return serializableVar{Type: ""} 171} 172func (v *automaticVar) dump(d *dumpbuf) { 173 d.err = fmt.Errorf("cannnot dump automatic var:%s", v.value) 174} 175 176func (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 194func (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 208type recursiveVar struct { 209 expr Value 210 origin string 211} 212 213func (v *recursiveVar) Flavor() string { return "recursive" } 214func (v *recursiveVar) Origin() string { return v.origin } 215func (v *recursiveVar) IsDefined() bool { return true } 216 217func (v *recursiveVar) String() string { return v.expr.String() } 218func (v *recursiveVar) Eval(w evalWriter, ev *Evaluator) error { 219 v.expr.Eval(w, ev) 220 return nil 221} 222func (v *recursiveVar) serialize() serializableVar { 223 return serializableVar{ 224 Type: "recursive", 225 Children: []serializableVar{v.expr.serialize()}, 226 Origin: v.origin, 227 } 228} 229func (v *recursiveVar) dump(d *dumpbuf) { 230 d.Byte(valueTypeRecursive) 231 v.expr.dump(d) 232 d.Str(v.origin) 233} 234 235func (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 255func (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 268type undefinedVar struct{} 269 270func (undefinedVar) Flavor() string { return "undefined" } 271func (undefinedVar) Origin() string { return "undefined" } 272func (undefinedVar) IsDefined() bool { return false } 273func (undefinedVar) String() string { return "" } 274func (undefinedVar) Eval(_ evalWriter, _ *Evaluator) error { 275 return nil 276} 277func (undefinedVar) serialize() serializableVar { 278 return serializableVar{Type: "undefined"} 279} 280func (undefinedVar) dump(d *dumpbuf) { 281 d.Byte(valueTypeUndefined) 282} 283 284func (undefinedVar) Append(*Evaluator, string) (Var, error) { 285 return undefinedVar{}, nil 286} 287 288func (undefinedVar) AppendVar(_ *Evaluator, val Value) (Var, error) { 289 return undefinedVar{}, nil 290} 291 292// Vars is a map for make variables. 293type Vars map[string]Var 294 295// usedEnvs tracks what environment variables are used. 296var usedEnvs = map[string]bool{} 297 298// Lookup looks up named make variable. 299func (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? 316var 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. 328func (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. 346func NewVars(vt Vars) Vars { 347 r := make(Vars) 348 r.Merge(vt) 349 return r 350} 351 352// Merge merges vt2 into vt. 353func (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. 362func (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