blob: 5e7e996f2a2f8cde03c85a91b87829e27ca7d7c1 [file] [log] [blame]
Shinichiro Hamajib69bf8a2015-06-10 14:52:06 +09001// 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 Ukai744bb2b2015-06-25 00:10:52 +090015package kati
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090016
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090017import (
18 "bytes"
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +090019 "fmt"
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090020 "io"
Fumitoshi Ukaib5612a82015-07-14 13:22:17 +090021 "strings"
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090022)
23
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090024// Var is an interface of make variable.
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090025type Var interface {
26 Value
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090027 Append(*Evaluator, string) (Var, error)
28 AppendVar(*Evaluator, Value) (Var, error)
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090029 Flavor() string
30 Origin() string
31 IsDefined() bool
32}
33
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090034type targetSpecificVar struct {
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090035 v Var
36 op string
37}
38
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090039func (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 Hamajia485d2f2015-04-16 14:03:24 +090043 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090044 return &targetSpecificVar{
45 v: nv,
46 op: v.op,
47 }, nil
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090048}
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090049func (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 Hamajia485d2f2015-04-16 14:03:24 +090053 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090054 return &targetSpecificVar{
55 v: nv,
56 op: v.op,
57 }, nil
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090058}
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090059func (v *targetSpecificVar) Flavor() string {
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090060 return v.v.Flavor()
61}
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090062func (v *targetSpecificVar) Origin() string {
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090063 return v.v.Origin()
64}
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090065func (v *targetSpecificVar) IsDefined() bool {
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090066 return v.v.IsDefined()
67}
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090068func (v *targetSpecificVar) String() string {
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090069 // 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 Ukaib44b12d2015-07-07 14:19:32 +090074func (v *targetSpecificVar) Eval(w evalWriter, ev *Evaluator) error {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090075 return v.v.Eval(w, ev)
Shinichiro Hamajia485d2f2015-04-16 14:03:24 +090076}
77
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +090078func (v *targetSpecificVar) serialize() serializableVar {
79 return serializableVar{
Shinichiro Hamaji3d6d0aa2015-04-28 16:18:44 +090080 Type: v.op,
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +090081 Children: []serializableVar{v.v.serialize()},
Shinichiro Hamaji8c9d0e32015-04-28 03:30:19 +090082 }
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +090083}
84
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090085func (v *targetSpecificVar) dump(d *dumpbuf) {
86 d.Byte(valueTypeTSV)
87 d.Str(v.op)
88 v.v.dump(d)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +090089}
90
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090091type simpleVar struct {
Fumitoshi Ukai7655f182015-07-15 14:05:41 +090092 // space separated. note that each string may contain spaces, so
93 // it is not word list.
94 value []string
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +090095 origin string
96}
97
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090098func (v *simpleVar) Flavor() string { return "simple" }
99func (v *simpleVar) Origin() string { return v.origin }
100func (v *simpleVar) IsDefined() bool { return true }
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900101
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900102func (v *simpleVar) String() string { return strings.Join(v.value, " ") }
Fumitoshi Ukaib44b12d2015-07-07 14:19:32 +0900103func (v *simpleVar) Eval(w evalWriter, ev *Evaluator) error {
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900104 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 Ukai65c72332015-06-26 21:32:50 +0900112 return nil
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900113}
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900114func (v *simpleVar) serialize() serializableVar {
115 return serializableVar{
Shinichiro Hamaji3d6d0aa2015-04-28 16:18:44 +0900116 Type: "simple",
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900117 V: v.String(),
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +0900118 Origin: v.origin,
119 }
120}
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900121func (v *simpleVar) dump(d *dumpbuf) {
122 d.Byte(valueTypeSimple)
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900123 d.Int(len(v.value))
124 for _, v := range v.value {
125 d.Str(v)
126 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900127 d.Str(v.origin)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +0900128}
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900129
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900130func (v *simpleVar) Append(ev *Evaluator, s string) (Var, error) {
Fumitoshi Ukaie9aa3802015-07-03 11:33:23 +0900131 val, _, err := parseExpr([]byte(s), nil, parseOp{})
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900132 if err != nil {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900133 return nil, err
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900134 }
Fumitoshi Ukaia4a02252015-07-09 14:25:18 +0900135 abuf := newEbuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900136 err = val.Eval(abuf, ev)
137 if err != nil {
138 return nil, err
139 }
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900140 v.value = append(v.value, abuf.String())
Fumitoshi Ukaia4a02252015-07-09 14:25:18 +0900141 abuf.release()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900142 return v, nil
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900143}
144
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900145func (v *simpleVar) AppendVar(ev *Evaluator, val Value) (Var, error) {
Fumitoshi Ukaia4a02252015-07-09 14:25:18 +0900146 abuf := newEbuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900147 err := val.Eval(abuf, ev)
148 if err != nil {
149 return nil, err
150 }
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900151 v.value = append(v.value, abuf.String())
Fumitoshi Ukaia4a02252015-07-09 14:25:18 +0900152 abuf.release()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900153 return v, nil
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900154}
155
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900156type automaticVar struct {
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900157 value []byte
158}
159
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900160func (v *automaticVar) Flavor() string { return "simple" }
161func (v *automaticVar) Origin() string { return "automatic" }
162func (v *automaticVar) IsDefined() bool { return true }
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900163
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900164func (v *automaticVar) String() string { return string(v.value) }
Fumitoshi Ukaib44b12d2015-07-07 14:19:32 +0900165func (v *automaticVar) Eval(w evalWriter, ev *Evaluator) error {
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900166 w.Write(v.value)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900167 return nil
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900168}
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900169func (v *automaticVar) serialize() serializableVar {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900170 return serializableVar{Type: ""}
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900171}
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900172func (v *automaticVar) dump(d *dumpbuf) {
173 d.err = fmt.Errorf("cannnot dump automatic var:%s", v.value)
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900174}
175
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900176func (v *automaticVar) Append(ev *Evaluator, s string) (Var, error) {
Fumitoshi Ukaie9aa3802015-07-03 11:33:23 +0900177 val, _, err := parseExpr([]byte(s), nil, parseOp{})
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900178 if err != nil {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900179 return nil, err
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +0900180 }
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900181 abuf := newEbuf()
182 err = val.Eval(abuf, ev)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900183 if err != nil {
184 return nil, err
185 }
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900186 value := []string{string(v.value), abuf.String()}
187 abuf.release()
Fumitoshi Ukai21426172015-06-30 18:02:45 +0900188 return &simpleVar{
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900189 value: value,
Fumitoshi Ukai21426172015-06-30 18:02:45 +0900190 origin: "file",
191 }, nil
Fumitoshi Ukaic1847602015-04-02 16:18:02 +0900192}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900193
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900194func (v *automaticVar) AppendVar(ev *Evaluator, val Value) (Var, error) {
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900195 abuf := newEbuf()
196 err := val.Eval(abuf, ev)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900197 if err != nil {
198 return nil, err
199 }
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900200 value := []string{string(v.value), abuf.String()}
201 abuf.release()
Fumitoshi Ukai21426172015-06-30 18:02:45 +0900202 return &simpleVar{
Fumitoshi Ukai7655f182015-07-15 14:05:41 +0900203 value: value,
Fumitoshi Ukai21426172015-06-30 18:02:45 +0900204 origin: "file",
205 }, nil
Shinichiro Hamajiea170b12015-04-15 10:02:33 +0900206}
207
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900208type recursiveVar struct {
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900209 expr Value
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900210 origin string
211}
212
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900213func (v *recursiveVar) Flavor() string { return "recursive" }
214func (v *recursiveVar) Origin() string { return v.origin }
215func (v *recursiveVar) IsDefined() bool { return true }
Fumitoshi Ukaic1847602015-04-02 16:18:02 +0900216
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900217func (v *recursiveVar) String() string { return v.expr.String() }
Fumitoshi Ukaib44b12d2015-07-07 14:19:32 +0900218func (v *recursiveVar) Eval(w evalWriter, ev *Evaluator) error {
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900219 v.expr.Eval(w, ev)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900220 return nil
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900221}
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900222func (v *recursiveVar) serialize() serializableVar {
223 return serializableVar{
Shinichiro Hamaji3d6d0aa2015-04-28 16:18:44 +0900224 Type: "recursive",
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900225 Children: []serializableVar{v.expr.serialize()},
Shinichiro Hamaji3d6d0aa2015-04-28 16:18:44 +0900226 Origin: v.origin,
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +0900227 }
228}
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900229func (v *recursiveVar) dump(d *dumpbuf) {
230 d.Byte(valueTypeRecursive)
231 v.expr.dump(d)
232 d.Str(v.origin)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +0900233}
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900234
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900235func (v *recursiveVar) Append(_ *Evaluator, s string) (Var, error) {
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900236 var exp expr
237 if e, ok := v.expr.(expr); ok {
238 exp = append(e, literal(" "))
Fumitoshi Ukaif3609102015-04-19 23:06:54 +0900239 } else {
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900240 exp = expr{v.expr, literal(" ")}
Fumitoshi Ukaif3609102015-04-19 23:06:54 +0900241 }
Fumitoshi Ukaie9aa3802015-07-03 11:33:23 +0900242 sv, _, err := parseExpr([]byte(s), nil, parseOp{alloc: true})
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900243 if err != nil {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900244 return nil, err
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900245 }
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900246 if aexpr, ok := sv.(expr); ok {
247 exp = append(exp, aexpr...)
Fumitoshi Ukaif3609102015-04-19 23:06:54 +0900248 } else {
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900249 exp = append(exp, sv)
Fumitoshi Ukaif3609102015-04-19 23:06:54 +0900250 }
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900251 v.expr = exp
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900252 return v, nil
Fumitoshi Ukaic1847602015-04-02 16:18:02 +0900253}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900254
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900255func (v *recursiveVar) AppendVar(ev *Evaluator, val Value) (Var, error) {
Shinichiro Hamajiea170b12015-04-15 10:02:33 +0900256 var buf bytes.Buffer
257 buf.WriteString(v.expr.String())
258 buf.WriteByte(' ')
259 buf.WriteString(val.String())
Fumitoshi Ukaie9aa3802015-07-03 11:33:23 +0900260 e, _, err := parseExpr(buf.Bytes(), nil, parseOp{alloc: true})
Shinichiro Hamajiea170b12015-04-15 10:02:33 +0900261 if err != nil {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900262 return nil, err
Shinichiro Hamajiea170b12015-04-15 10:02:33 +0900263 }
264 v.expr = e
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900265 return v, nil
Shinichiro Hamajiea170b12015-04-15 10:02:33 +0900266}
267
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900268type undefinedVar struct{}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900269
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900270func (undefinedVar) Flavor() string { return "undefined" }
271func (undefinedVar) Origin() string { return "undefined" }
272func (undefinedVar) IsDefined() bool { return false }
273func (undefinedVar) String() string { return "" }
Fumitoshi Ukaib44b12d2015-07-07 14:19:32 +0900274func (undefinedVar) Eval(_ evalWriter, _ *Evaluator) error {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900275 return nil
Fumitoshi Ukaic1847602015-04-02 16:18:02 +0900276}
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900277func (undefinedVar) serialize() serializableVar {
278 return serializableVar{Type: "undefined"}
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +0900279}
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900280func (undefinedVar) dump(d *dumpbuf) {
281 d.Byte(valueTypeUndefined)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +0900282}
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900283
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900284func (undefinedVar) Append(*Evaluator, string) (Var, error) {
285 return undefinedVar{}, nil
Fumitoshi Ukaic1847602015-04-02 16:18:02 +0900286}
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900287
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900288func (undefinedVar) AppendVar(_ *Evaluator, val Value) (Var, error) {
289 return undefinedVar{}, nil
Shinichiro Hamajiea170b12015-04-15 10:02:33 +0900290}
291
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900292// Vars is a map for make variables.
Shinichiro Hamajicc919ae2015-04-09 17:23:30 +0900293type Vars map[string]Var
294
Fumitoshi Ukaib5612a82015-07-14 13:22:17 +0900295// usedEnvs tracks what environment variables are used.
296var usedEnvs = map[string]bool{}
297
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900298// Lookup looks up named make variable.
Shinichiro Hamajicc919ae2015-04-09 17:23:30 +0900299func (vt Vars) Lookup(name string) Var {
300 if v, ok := vt[name]; ok {
Fumitoshi Ukaib5612a82015-07-14 13:22:17 +0900301 if strings.HasPrefix(v.Origin(), "environment") {
302 usedEnvs[name] = true
303 }
Shinichiro Hamajicc919ae2015-04-09 17:23:30 +0900304 return v
305 }
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +0900306 return undefinedVar{}
Shinichiro Hamajicc919ae2015-04-09 17:23:30 +0900307}
308
Fumitoshi Ukai38c46a72015-06-30 17:25:14 +0900309// 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{
Fumitoshi Ukai38c46a72015-06-30 17:25:14 +0900317 "override": 4,
318 "environment override": 4,
319 "command line": 3,
320 "file": 2,
321 "environment": 2,
322 "default": 1,
323 "undefined": 0,
Fumitoshi Ukai21426172015-06-30 18:02:45 +0900324 "automatic": 0,
Fumitoshi Ukai38c46a72015-06-30 17:25:14 +0900325}
326
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900327// Assign assigns v to name.
Shinichiro Hamajicc919ae2015-04-09 17:23:30 +0900328func (vt Vars) Assign(name string, v Var) {
Fumitoshi Ukai38c46a72015-06-30 17:25:14 +0900329 vo := v.Origin()
Fumitoshi Ukai21426172015-06-30 18:02:45 +0900330 // assign automatic always win.
331 // assign new value to automatic always win.
Fumitoshi Ukai38c46a72015-06-30 17:25:14 +0900332 if vo != "automatic" {
333 vp := originPrecedence[v.Origin()]
334 var op int
Fumitoshi Ukaif59f9f92015-06-18 15:51:55 +0900335 if ov, ok := vt[name]; ok {
Fumitoshi Ukai38c46a72015-06-30 17:25:14 +0900336 op = originPrecedence[ov.Origin()]
337 }
338 if op > vp {
339 return
Fumitoshi Ukai8ae323b2015-04-08 17:44:38 +0900340 }
341 }
Shinichiro Hamajicc919ae2015-04-09 17:23:30 +0900342 vt[name] = v
343}
344
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900345// NewVars creates new Vars.
Shinichiro Hamaji63a77d42015-04-12 01:04:07 +0900346func NewVars(vt Vars) Vars {
347 r := make(Vars)
348 r.Merge(vt)
349 return r
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900350}
Shinichiro Hamaji03a6f6d2015-04-07 03:59:41 +0900351
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900352// Merge merges vt2 into vt.
Shinichiro Hamaji63a77d42015-04-12 01:04:07 +0900353func (vt Vars) Merge(vt2 Vars) {
354 for k, v := range vt2 {
355 vt[k] = v
356 }
Shinichiro Hamaji03a6f6d2015-04-07 03:59:41 +0900357}
Shinichiro Hamaji4e9ab1a2015-04-12 01:31:58 +0900358
Fumitoshi Ukai9b10ecf2015-04-15 17:45:50 +0900359// 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() {
Fumitoshi Ukai5a374592015-06-18 22:40:45 +0900363 if v, ok := vt[name]; ok {
Fumitoshi Ukai9b10ecf2015-04-15 17:45:50 +0900364 return func() {
365 vt[name] = v
366 }
Shinichiro Hamaji4e9ab1a2015-04-12 01:31:58 +0900367 }
Fumitoshi Ukai9b10ecf2015-04-15 17:45:50 +0900368 return func() {
369 delete(vt, name)
Shinichiro Hamaji4e9ab1a2015-04-12 01:31:58 +0900370 }
Shinichiro Hamaji4e9ab1a2015-04-12 01:31:58 +0900371}