blob: 03ca5219f7faafbd052519b6cf7c978201019ab2 [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 Ukaif2f84562015-03-30 19:47:45 +090016
17import (
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090018 "bytes"
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090019 "fmt"
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090020 "io"
Shinichiro Hamajie7aafb02015-04-09 18:23:46 +090021 "os"
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090022 "os/exec"
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +090023 "path/filepath"
Shinichiro Hamaji13b30d92015-04-03 14:42:21 +090024 "sort"
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +090025 "strconv"
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090026 "strings"
Fumitoshi Ukai586b02a2015-05-08 00:23:10 +090027 "time"
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090028)
29
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090030// mkFunc is a make function.
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090031// http://www.gnu.org/software/make/manual/make.html#Functions
Fumitoshi Ukaie520f262015-03-31 17:27:03 +090032
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090033// mkFunc is make builtin function.
34type mkFunc interface {
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090035 // Arity is max function's arity.
36 // ',' will not be handled as argument separator more than arity.
37 // 0 means varargs.
38 Arity() int
39
40 // AddArg adds value as an argument.
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +090041 // the first argument will be "(funcname", or "{funcname".
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090042 AddArg(Value)
43
44 Value
45}
46
47var (
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090048 funcMap = map[string]func() mkFunc{
49 "patsubst": func() mkFunc { return &funcPatsubst{} },
50 "strip": func() mkFunc { return &funcStrip{} },
51 "subst": func() mkFunc { return &funcSubst{} },
52 "findstring": func() mkFunc { return &funcFindstring{} },
53 "filter": func() mkFunc { return &funcFilter{} },
54 "filter-out": func() mkFunc { return &funcFilterOut{} },
55 "sort": func() mkFunc { return &funcSort{} },
56 "word": func() mkFunc { return &funcWord{} },
57 "wordlist": func() mkFunc { return &funcWordlist{} },
58 "words": func() mkFunc { return &funcWords{} },
59 "firstword": func() mkFunc { return &funcFirstword{} },
60 "lastword": func() mkFunc { return &funcLastword{} },
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +090061
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090062 "join": func() mkFunc { return &funcJoin{} },
63 "wildcard": func() mkFunc { return &funcWildcard{} },
64 "dir": func() mkFunc { return &funcDir{} },
65 "notdir": func() mkFunc { return &funcNotdir{} },
66 "suffix": func() mkFunc { return &funcSuffix{} },
67 "basename": func() mkFunc { return &funcBasename{} },
68 "addsuffix": func() mkFunc { return &funcAddsuffix{} },
69 "addprefix": func() mkFunc { return &funcAddprefix{} },
70 "realpath": func() mkFunc { return &funcRealpath{} },
71 "abspath": func() mkFunc { return &funcAbspath{} },
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +090072
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090073 "if": func() mkFunc { return &funcIf{} },
74 "and": func() mkFunc { return &funcAnd{} },
75 "or": func() mkFunc { return &funcOr{} },
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +090076
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090077 "value": func() mkFunc { return &funcValue{} },
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +090078
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090079 "eval": func() mkFunc { return &funcEval{} },
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +090080
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090081 "shell": func() mkFunc { return &funcShell{} },
82 "call": func() mkFunc { return &funcCall{} },
83 "foreach": func() mkFunc { return &funcForeach{} },
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +090084
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +090085 "origin": func() mkFunc { return &funcOrigin{} },
86 "flavor": func() mkFunc { return &funcFlavor{} },
87 "info": func() mkFunc { return &funcInfo{} },
88 "warning": func() mkFunc { return &funcWarning{} },
89 "error": func() mkFunc { return &funcError{} },
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090090 }
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +090091)
92
Fumitoshi Ukai65c72332015-06-26 21:32:50 +090093type arityError struct {
94 narg int
95 name string
96}
97
98func (e arityError) Error() string {
99 return fmt.Sprintf("*** insufficient number of arguments (%d) to function `%s'.", e.narg, e.name)
100}
101
102func assertArity(name string, req, n int) error {
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900103 if n-1 < req {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900104 return arityError{narg: n - 1, name: name}
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900105 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900106 return nil
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900107}
108
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900109func numericValueForFunc(v string) (int, bool) {
110 n, err := strconv.Atoi(v)
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900111 if err != nil || n < 0 {
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900112 return n, false
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900113 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900114 return n, true
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900115}
116
Shinichiro Hamajiba6b84d2015-06-03 18:46:13 +0900117func formatCommandOutput(out []byte) []byte {
118 out = bytes.TrimRight(out, "\n")
119 out = bytes.Replace(out, []byte{'\n'}, []byte{' '}, -1)
120 return out
121}
122
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900123type fclosure struct {
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900124 // args[0] is "(funcname", or "{funcname".
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900125 args []Value
126}
127
128func (c *fclosure) AddArg(v Value) {
129 c.args = append(c.args, v)
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900130}
131
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900132func (c *fclosure) String() string {
133 if len(c.args) == 0 {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900134 return "$(func)"
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900135 }
136 arg0 := c.args[0].String()
137 if arg0 == "" {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900138 return "$(func )"
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900139 }
140 cp := closeParen(arg0[0])
141 if cp == 0 {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900142 return "${func }"
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900143 }
144 var args []string
145 for _, arg := range c.args[1:] {
146 args = append(args, arg.String())
147 }
148 return fmt.Sprintf("$%s %s%c", arg0, strings.Join(args, ","), cp)
149}
Fumitoshi Ukai78781132015-04-10 17:08:40 +0900150
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900151func (c *fclosure) serialize() serializableVar {
152 r := serializableVar{Type: "func"}
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +0900153 for _, a := range c.args {
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +0900154 r.Children = append(r.Children, a.serialize())
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +0900155 }
156 return r
157}
158
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900159func (c *fclosure) dump(d *dumpbuf) {
160 d.Byte(valueTypeFunc)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +0900161 for _, a := range c.args {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900162 a.dump(d)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +0900163 }
164}
165
Shinichiro Hamaji4125cf42015-04-03 11:42:28 +0900166// http://www.gnu.org/software/make/manual/make.html#Text-Functions
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900167type funcSubst struct{ fclosure }
168
169func (f *funcSubst) Arity() int { return 3 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900170func (f *funcSubst) Eval(w io.Writer, ev *Evaluator) error {
171 err := assertArity("subst", 3, len(f.args))
172 if err != nil {
173 return err
174 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900175 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900176 fargs, err := ev.args(abuf, f.args[1:]...)
177 if err != nil {
178 return err
179 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900180 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900181 from := fargs[0]
182 to := fargs[1]
183 text := fargs[2]
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900184 logf("subst from:%q to:%q text:%q", from, to, text)
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900185 w.Write(bytes.Replace(text, from, to, -1))
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900186 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900187 stats.add("funcbody", "subst", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900188 return nil
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900189}
190
Shinichiro Hamaji98e910d2015-04-11 10:38:44 +0900191type funcPatsubst struct{ fclosure }
192
193func (f *funcPatsubst) Arity() int { return 3 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900194func (f *funcPatsubst) Eval(w io.Writer, ev *Evaluator) error {
195 err := assertArity("patsubst", 3, len(f.args))
196 if err != nil {
197 return err
198 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900199 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900200 fargs, err := ev.args(abuf, f.args[1:]...)
201 if err != nil {
202 return err
203 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900204 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900205 pat := fargs[0]
206 repl := fargs[1]
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900207 ws := newWordScanner(fargs[2])
Fumitoshi Ukai77411fb2015-06-19 15:46:21 +0900208 space := false
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900209 for ws.Scan() {
Fumitoshi Ukai77411fb2015-06-19 15:46:21 +0900210 if space {
211 writeByte(w, ' ')
212 }
213 pre, subst, post := substPatternBytes(pat, repl, ws.Bytes())
214 w.Write(pre)
215 if subst != nil {
216 w.Write(subst)
217 w.Write(post)
218 }
219 space = true
Shinichiro Hamaji98e910d2015-04-11 10:38:44 +0900220 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900221 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900222 stats.add("funcbody", "patsubst", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900223 return nil
Shinichiro Hamaji98e910d2015-04-11 10:38:44 +0900224}
225
226type funcStrip struct{ fclosure }
227
228func (f *funcStrip) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900229func (f *funcStrip) Eval(w io.Writer, ev *Evaluator) error {
230 err := assertArity("strip", 1, len(f.args))
231 if err != nil {
232 return err
233 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900234 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900235 err = f.args[1].Eval(abuf, ev)
236 if err != nil {
237 return err
238 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900239 t := time.Now()
Shinichiro Hamajib978e112015-06-05 11:02:45 +0900240 ws := newWordScanner(abuf.Bytes())
Fumitoshi Ukaia44b7662015-06-19 11:07:07 +0900241 space := false
Shinichiro Hamajib978e112015-06-05 11:02:45 +0900242 for ws.Scan() {
Fumitoshi Ukaia44b7662015-06-19 11:07:07 +0900243 if space {
244 writeByte(w, ' ')
245 }
246 w.Write(ws.Bytes())
247 space = true
Shinichiro Hamajib978e112015-06-05 11:02:45 +0900248 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900249 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900250 stats.add("funcbody", "strip", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900251 return nil
Shinichiro Hamaji98e910d2015-04-11 10:38:44 +0900252}
253
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900254type funcFindstring struct{ fclosure }
255
256func (f *funcFindstring) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900257func (f *funcFindstring) Eval(w io.Writer, ev *Evaluator) error {
258 err := assertArity("findstring", 2, len(f.args))
259 if err != nil {
260 return err
261 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900262 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900263 fargs, err := ev.args(abuf, f.args[1:]...)
264 if err != nil {
265 return err
266 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900267 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900268 find := fargs[0]
269 text := fargs[1]
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900270 if bytes.Index(text, find) >= 0 {
271 w.Write(find)
272 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900273 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900274 stats.add("funcbody", "findstring", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900275 return nil
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900276}
277
278type funcFilter struct{ fclosure }
279
280func (f *funcFilter) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900281func (f *funcFilter) Eval(w io.Writer, ev *Evaluator) error {
282 err := assertArity("filter", 2, len(f.args))
283 if err != nil {
284 return err
285 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900286 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900287 fargs, err := ev.args(abuf, f.args[1:]...)
288 if err != nil {
289 return err
290 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900291 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900292 var patterns [][]byte
293 ws := newWordScanner(fargs[0])
294 for ws.Scan() {
295 patterns = append(patterns, ws.Bytes())
296 }
297 ws = newWordScanner(fargs[1])
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900298 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900299 for ws.Scan() {
300 text := ws.Bytes()
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900301 for _, pat := range patterns {
302 if matchPatternBytes(pat, text) {
303 sw.Write(text)
304 }
305 }
306 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900307 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900308 stats.add("funcbody", "filter", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900309 return nil
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900310}
311
312type funcFilterOut struct{ fclosure }
313
314func (f *funcFilterOut) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900315func (f *funcFilterOut) Eval(w io.Writer, ev *Evaluator) error {
316 err := assertArity("filter-out", 2, len(f.args))
317 if err != nil {
318 return err
319 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900320 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900321 fargs, err := ev.args(abuf, f.args[1:]...)
322 if err != nil {
323 return err
324 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900325 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900326 var patterns [][]byte
327 ws := newWordScanner(fargs[0])
328 for ws.Scan() {
329 patterns = append(patterns, ws.Bytes())
330 }
331 ws = newWordScanner(fargs[1])
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900332 sw := ssvWriter{w: w}
333Loop:
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900334 for ws.Scan() {
335 text := ws.Bytes()
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900336 for _, pat := range patterns {
337 if matchPatternBytes(pat, text) {
338 continue Loop
339 }
340 }
341 sw.Write(text)
342 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900343 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900344 stats.add("funcbody", "filter-out", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900345 return err
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900346}
347
348type funcSort struct{ fclosure }
349
350func (f *funcSort) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900351func (f *funcSort) Eval(w io.Writer, ev *Evaluator) error {
352 err := assertArity("sort", 1, len(f.args))
353 if err != nil {
354 return err
355 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900356 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900357 err = f.args[1].Eval(abuf, ev)
358 if err != nil {
359 return err
360 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900361 t := time.Now()
Fumitoshi Ukai79cfbab2015-06-18 23:28:26 +0900362 ws := newWordScanner(abuf.Bytes())
363 var toks []string
364 for ws.Scan() {
365 toks = append(toks, string(ws.Bytes()))
366 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900367 freeBuf(abuf)
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900368 sort.Strings(toks)
369
370 // Remove duplicate words.
371 var prev string
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900372 for _, tok := range toks {
Fumitoshi Ukaice14acb2015-06-19 13:54:53 +0900373 if prev == tok {
374 continue
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900375 }
Fumitoshi Ukaice14acb2015-06-19 13:54:53 +0900376 if prev != "" {
377 writeByte(w, ' ')
378 }
379 io.WriteString(w, tok)
380 prev = tok
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900381 }
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900382 stats.add("funcbody", "sort", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900383 return nil
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900384}
385
386type funcWord struct{ fclosure }
387
388func (f *funcWord) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900389func (f *funcWord) Eval(w io.Writer, ev *Evaluator) error {
390 err := assertArity("word", 2, len(f.args))
391 if err != nil {
392 return err
393 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900394 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900395 fargs, err := ev.args(abuf, f.args[1:]...)
396 if err != nil {
397 return err
398 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900399 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900400 v := string(trimSpaceBytes(fargs[0]))
401 index, ok := numericValueForFunc(v)
402 if !ok {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900403 return ev.errorf(`*** non-numeric first argument to "word" function: %q.`, v)
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900404 }
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900405 if index == 0 {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900406 return ev.errorf(`*** first argument to "word" function must be greater than 0.`)
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900407 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900408 ws := newWordScanner(fargs[1])
409 for ws.Scan() {
410 index--
411 if index == 0 {
412 w.Write(ws.Bytes())
413 break
414 }
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900415 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900416 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900417 stats.add("funcbody", "word", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900418 return err
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900419}
420
421type funcWordlist struct{ fclosure }
422
423func (f *funcWordlist) Arity() int { return 3 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900424func (f *funcWordlist) Eval(w io.Writer, ev *Evaluator) error {
425 err := assertArity("wordlist", 3, len(f.args))
426 if err != nil {
427 return err
428 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900429 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900430 fargs, err := ev.args(abuf, f.args[1:]...)
431 if err != nil {
432 return err
433 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900434 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900435 v := string(trimSpaceBytes(fargs[0]))
436 si, ok := numericValueForFunc(v)
437 if !ok {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900438 return ev.errorf(`*** non-numeric first argument to "wordlist" function: %q.`, v)
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900439 }
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900440 if si == 0 {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900441 return ev.errorf(`*** invalid first argument to "wordlist" function: %s`, f.args[1])
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900442 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900443 v = string(trimSpaceBytes(fargs[1]))
444 ei, ok := numericValueForFunc(v)
445 if !ok {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900446 return ev.errorf(`*** non-numeric second argument to "wordlist" function: %q.`, v)
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900447 }
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900448
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900449 ws := newWordScanner(fargs[2])
450 i := 0
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900451 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900452 for ws.Scan() {
453 i++
454 if si <= i && i <= ei {
455 sw.Write(ws.Bytes())
456 }
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900457 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900458 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900459 stats.add("funcbody", "wordlist", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900460 return nil
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900461}
462
463type funcWords struct{ fclosure }
464
465func (f *funcWords) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900466func (f *funcWords) Eval(w io.Writer, ev *Evaluator) error {
467 err := assertArity("words", 1, len(f.args))
468 if err != nil {
469 return err
470 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900471 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900472 err = f.args[1].Eval(abuf, ev)
473 if err != nil {
474 return err
475 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900476 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900477 ws := newWordScanner(abuf.Bytes())
478 n := 0
479 for ws.Scan() {
480 n++
481 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900482 freeBuf(abuf)
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900483 io.WriteString(w, strconv.Itoa(n))
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900484 stats.add("funcbody", "words", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900485 return nil
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900486}
487
488type funcFirstword struct{ fclosure }
489
490func (f *funcFirstword) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900491func (f *funcFirstword) Eval(w io.Writer, ev *Evaluator) error {
492 err := assertArity("firstword", 1, len(f.args))
493 if err != nil {
494 return err
495 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900496 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900497 err = f.args[1].Eval(abuf, ev)
498 if err != nil {
499 return err
500 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900501 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900502 ws := newWordScanner(abuf.Bytes())
503 if ws.Scan() {
504 w.Write(ws.Bytes())
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900505 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900506 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900507 stats.add("funcbody", "firstword", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900508 return nil
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900509}
510
511type funcLastword struct{ fclosure }
512
513func (f *funcLastword) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900514func (f *funcLastword) Eval(w io.Writer, ev *Evaluator) error {
515 err := assertArity("lastword", 1, len(f.args))
516 if err != nil {
517 return err
518 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900519 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900520 err = f.args[1].Eval(abuf, ev)
521 if err != nil {
522 return err
523 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900524 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900525 ws := newWordScanner(abuf.Bytes())
526 var lw []byte
527 for ws.Scan() {
528 lw = ws.Bytes()
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900529 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900530 if lw != nil {
531 w.Write(lw)
532 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900533 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900534 stats.add("funcbody", "lastword", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900535 return err
Shinichiro Hamaji05b222d2015-04-11 11:36:37 +0900536}
537
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900538// https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html#File-Name-Functions
539
540type funcJoin struct{ fclosure }
541
542func (f *funcJoin) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900543func (f *funcJoin) Eval(w io.Writer, ev *Evaluator) error {
544 err := assertArity("join", 2, len(f.args))
545 if err != nil {
546 return err
547 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900548 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900549 fargs, err := ev.args(abuf, f.args[1:]...)
550 if err != nil {
551 return err
552 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900553 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900554 ws1 := newWordScanner(fargs[0])
555 ws2 := newWordScanner(fargs[1])
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900556 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900557 for {
558 if w1, w2 := ws1.Scan(), ws2.Scan(); !w1 && !w2 {
559 break
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900560 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900561 sw.Write(ws1.Bytes())
562 // Use |w| not to append extra ' '.
563 w.Write(ws2.Bytes())
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900564 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900565 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900566 stats.add("funcbody", "join", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900567 return nil
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900568}
569
570type funcWildcard struct{ fclosure }
571
572func (f *funcWildcard) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900573func (f *funcWildcard) Eval(w io.Writer, ev *Evaluator) error {
574 err := assertArity("wildcard", 1, len(f.args))
575 if err != nil {
576 return err
577 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900578 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900579 err = f.args[1].Eval(abuf, ev)
580 if err != nil {
581 return err
582 }
Fumitoshi Ukai83410132015-06-15 14:50:07 +0900583 te := traceEvent.begin("wildcard", tmpval(abuf.Bytes()), traceEventMain)
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900584 if ev.avoidIO && !UseWildcardCache {
Shinichiro Hamaji8b6487f2015-05-26 16:21:47 +0900585 ev.hasIO = true
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900586 io.WriteString(w, "$(/bin/ls -d ")
Shinichiro Hamaji8b6487f2015-05-26 16:21:47 +0900587 w.Write(abuf.Bytes())
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900588 io.WriteString(w, " 2> /dev/null)")
Fumitoshi Ukai432a2422015-06-11 15:16:29 +0900589 traceEvent.end(te)
Fumitoshi Ukai358c68a2015-06-08 13:12:55 +0900590 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900591 return nil
Shinichiro Hamaji8b6487f2015-05-26 16:21:47 +0900592 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900593 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900594 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900595 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900596 for ws.Scan() {
Shinichiro Hamajiba6b84d2015-06-03 18:46:13 +0900597 pat := string(ws.Bytes())
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900598 err = wildcard(&sw, pat)
599 if err != nil {
600 return err
601 }
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900602 }
Fumitoshi Ukai432a2422015-06-11 15:16:29 +0900603 traceEvent.end(te)
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900604 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900605 stats.add("funcbody", "wildcard", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900606 return nil
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900607}
608
609type funcDir struct{ fclosure }
610
611func (f *funcDir) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900612func (f *funcDir) Eval(w io.Writer, ev *Evaluator) error {
613 err := assertArity("dir", 1, len(f.args))
614 if err != nil {
615 return err
616 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900617 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900618 err = f.args[1].Eval(abuf, ev)
619 if err != nil {
620 return err
621 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900622 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900623 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900624 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900625 for ws.Scan() {
Shinichiro Hamaji55906852015-06-29 16:40:33 +0900626 name := filepath.Dir(string(string(ws.Bytes())))
Shinichiro Hamaji37626b62015-04-21 16:59:23 +0900627 if name == "/" {
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900628 sw.WriteString(name)
629 continue
Shinichiro Hamaji37626b62015-04-21 16:59:23 +0900630 }
Shinichiro Hamaji55906852015-06-29 16:40:33 +0900631 sw.WriteString(name + string(filepath.Separator))
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900632 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900633 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900634 stats.add("funcbody", "dir", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900635 return nil
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900636}
637
638type funcNotdir struct{ fclosure }
639
640func (f *funcNotdir) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900641func (f *funcNotdir) Eval(w io.Writer, ev *Evaluator) error {
642 err := assertArity("notdir", 1, len(f.args))
643 if err != nil {
644 return err
645 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900646 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900647 err = f.args[1].Eval(abuf, ev)
648 if err != nil {
649 return err
650 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900651 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900652 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900653 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900654 for ws.Scan() {
655 name := string(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900656 if name == string(filepath.Separator) {
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900657 sw.Write([]byte{}) // separator
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900658 continue
659 }
Shinichiro Hamajia1358912015-04-11 12:16:21 +0900660 sw.WriteString(filepath.Base(name))
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900661 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900662 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900663 stats.add("funcbody", "notdir", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900664 return nil
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900665}
666
667type funcSuffix struct{ fclosure }
668
669func (f *funcSuffix) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900670func (f *funcSuffix) Eval(w io.Writer, ev *Evaluator) error {
671 err := assertArity("suffix", 1, len(f.args))
672 if err != nil {
673 return err
674 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900675 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900676 err = f.args[1].Eval(abuf, ev)
677 if err != nil {
678 return err
679 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900680 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900681 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900682 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900683 for ws.Scan() {
684 tok := string(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900685 e := filepath.Ext(tok)
686 if len(e) > 0 {
Shinichiro Hamajia1358912015-04-11 12:16:21 +0900687 sw.WriteString(e)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900688 }
689 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900690 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900691 stats.add("funcbody", "suffix", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900692 return err
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900693}
694
695type funcBasename struct{ fclosure }
696
697func (f *funcBasename) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900698func (f *funcBasename) Eval(w io.Writer, ev *Evaluator) error {
699 err := assertArity("basename", 1, len(f.args))
700 if err != nil {
701 return err
702 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900703 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900704 err = f.args[1].Eval(abuf, ev)
705 if err != nil {
706 return err
707 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900708 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900709 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900710 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900711 for ws.Scan() {
712 tok := string(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900713 e := stripExt(tok)
Shinichiro Hamajia1358912015-04-11 12:16:21 +0900714 sw.WriteString(e)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900715 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900716 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900717 stats.add("funcbody", "basename", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900718 return nil
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900719}
720
721type funcAddsuffix struct{ fclosure }
722
723func (f *funcAddsuffix) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900724func (f *funcAddsuffix) Eval(w io.Writer, ev *Evaluator) error {
725 err := assertArity("addsuffix", 2, len(f.args))
726 if err != nil {
727 return err
728 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900729 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900730 fargs, err := ev.args(abuf, f.args[1:]...)
731 if err != nil {
732 return err
733 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900734 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900735 suf := fargs[0]
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900736 ws := newWordScanner(fargs[1])
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900737 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900738 for ws.Scan() {
739 sw.Write(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900740 // Use |w| not to append extra ' '.
741 w.Write(suf)
742 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900743 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900744 stats.add("funcbody", "addsuffix", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900745 return err
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900746}
747
748type funcAddprefix struct{ fclosure }
749
750func (f *funcAddprefix) Arity() int { return 2 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900751func (f *funcAddprefix) Eval(w io.Writer, ev *Evaluator) error {
752 err := assertArity("addprefix", 2, len(f.args))
753 if err != nil {
754 return err
755 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900756 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900757 fargs, err := ev.args(abuf, f.args[1:]...)
758 if err != nil {
759 return err
760 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900761 t := time.Now()
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900762 pre := fargs[0]
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900763 ws := newWordScanner(fargs[1])
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900764 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900765 for ws.Scan() {
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900766 sw.Write(pre)
767 // Use |w| not to append extra ' '.
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900768 w.Write(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900769 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900770 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900771 stats.add("funcbody", "addprefix", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900772 return err
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900773}
774
775type funcRealpath struct{ fclosure }
776
777func (f *funcRealpath) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900778func (f *funcRealpath) Eval(w io.Writer, ev *Evaluator) error {
779 err := assertArity("realpath", 1, len(f.args))
780 if err != nil {
781 return err
782 }
Shinichiro Hamajib41fd502015-04-29 03:34:07 +0900783 if ev.avoidIO {
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900784 io.WriteString(w, "KATI_TODO(realpath)")
Shinichiro Hamajib41fd502015-04-29 03:34:07 +0900785 ev.hasIO = true
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900786 return nil
Shinichiro Hamajib41fd502015-04-29 03:34:07 +0900787 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900788 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900789 err = f.args[1].Eval(abuf, ev)
790 if err != nil {
791 return err
792 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900793 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900794 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900795 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900796 for ws.Scan() {
797 name := string(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900798 name, err := filepath.Abs(name)
799 if err != nil {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900800 logf("abs: %v", err)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900801 continue
802 }
803 name, err = filepath.EvalSymlinks(name)
804 if err != nil {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900805 logf("realpath: %v", err)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900806 continue
807 }
Shinichiro Hamajia1358912015-04-11 12:16:21 +0900808 sw.WriteString(name)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900809 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900810 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900811 stats.add("funcbody", "realpath", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900812 return err
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900813}
814
815type funcAbspath struct{ fclosure }
816
817func (f *funcAbspath) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900818func (f *funcAbspath) Eval(w io.Writer, ev *Evaluator) error {
819 err := assertArity("abspath", 1, len(f.args))
820 if err != nil {
821 return err
822 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900823 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900824 err = f.args[1].Eval(abuf, ev)
825 if err != nil {
826 return err
827 }
Fumitoshi Ukai9e0c68d2015-06-19 13:38:19 +0900828 t := time.Now()
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900829 ws := newWordScanner(abuf.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900830 sw := ssvWriter{w: w}
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900831 for ws.Scan() {
832 name := string(ws.Bytes())
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900833 name, err := filepath.Abs(name)
834 if err != nil {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900835 logf("abs: %v", err)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900836 continue
837 }
Shinichiro Hamajia1358912015-04-11 12:16:21 +0900838 sw.WriteString(name)
Shinichiro Hamajiaf61af22015-04-11 12:13:22 +0900839 }
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +0900840 freeBuf(abuf)
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900841 stats.add("funcbody", "abspath", t)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900842 return nil
Shinichiro Hamajic20b84d2015-04-11 12:02:51 +0900843}
844
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900845// http://www.gnu.org/software/make/manual/make.html#Conditional-Functions
846type funcIf struct{ fclosure }
847
848func (f *funcIf) Arity() int { return 3 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900849func (f *funcIf) Eval(w io.Writer, ev *Evaluator) error {
850 err := assertArity("if", 2, len(f.args))
851 if err != nil {
852 return err
853 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900854 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900855 err = f.args[1].Eval(abuf, ev)
856 if err != nil {
857 return err
858 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900859 if len(abuf.Bytes()) != 0 {
860 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900861 return f.args[2].Eval(w, ev)
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900862 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900863 freeBuf(abuf)
Fumitoshi Ukaie27a25d2015-04-18 00:31:01 +0900864 if len(f.args) > 3 {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900865 return f.args[3].Eval(w, ev)
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900866 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900867 return nil
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900868}
869
870type funcAnd struct{ fclosure }
871
872func (f *funcAnd) Arity() int { return 0 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900873func (f *funcAnd) Eval(w io.Writer, ev *Evaluator) error {
874 err := assertArity("and", 0, len(f.args))
875 if err != nil {
876 return nil
877 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900878 abuf := newBuf()
Shinichiro Hamaji2216dd62015-04-11 13:44:39 +0900879 var cond []byte
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900880 for _, arg := range f.args[1:] {
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900881 abuf.Reset()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900882 err = arg.Eval(abuf, ev)
883 if err != nil {
884 return err
885 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900886 cond = abuf.Bytes()
Shinichiro Hamaji2216dd62015-04-11 13:44:39 +0900887 if len(cond) == 0 {
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900888 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900889 return nil
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900890 }
891 }
Shinichiro Hamaji2216dd62015-04-11 13:44:39 +0900892 w.Write(cond)
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900893 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900894 return nil
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900895}
896
897type funcOr struct{ fclosure }
898
899func (f *funcOr) Arity() int { return 0 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900900func (f *funcOr) Eval(w io.Writer, ev *Evaluator) error {
901 err := assertArity("or", 0, len(f.args))
902 if err != nil {
903 return err
904 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900905 abuf := newBuf()
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +0900906 for _, arg := range f.args[1:] {
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900907 abuf.Reset()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900908 err = arg.Eval(abuf, ev)
909 if err != nil {
910 return err
911 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900912 cond := abuf.Bytes()
Shinichiro Hamaji2216dd62015-04-11 13:44:39 +0900913 if len(cond) != 0 {
914 w.Write(cond)
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900915 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900916 return nil
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900917 }
918 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900919 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900920 return nil
Shinichiro Hamaji424baeb2015-04-11 12:35:42 +0900921}
922
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900923// http://www.gnu.org/software/make/manual/make.html#Shell-Function
924type funcShell struct{ fclosure }
925
926func (f *funcShell) Arity() int { return 1 }
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900927
Shinichiro Hamajic0095e32015-05-27 18:49:06 +0900928// A hack for Android build. We need to evaluate things like $((3+4))
929// when we emit ninja file, because the result of such expressions
930// will be passed to other make functions.
931// TODO: Maybe we should modify Android's Makefile and remove this
932// workaround. It would be also nice if we can detect things like
933// this.
934func hasNoIoInShellScript(s []byte) bool {
935 if len(s) == 0 {
936 return true
937 }
938 if !bytes.HasPrefix(s, []byte("echo $((")) || s[len(s)-1] != ')' {
939 return false
940 }
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900941 logf("has no IO - evaluate now: %s", s)
Shinichiro Hamajic0095e32015-05-27 18:49:06 +0900942 return true
943}
944
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900945func (f *funcShell) Eval(w io.Writer, ev *Evaluator) error {
946 err := assertArity("shell", 1, len(f.args))
947 if err != nil {
948 return err
949 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900950 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900951 err = f.args[1].Eval(abuf, ev)
952 if err != nil {
953 return err
954 }
Shinichiro Hamajic0095e32015-05-27 18:49:06 +0900955 if ev.avoidIO && !hasNoIoInShellScript(abuf.Bytes()) {
Fumitoshi Ukai83410132015-06-15 14:50:07 +0900956 te := traceEvent.begin("shell", tmpval(abuf.Bytes()), traceEventMain)
Shinichiro Hamaji8b6487f2015-05-26 16:21:47 +0900957 ev.hasIO = true
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900958 io.WriteString(w, "$(")
Shinichiro Hamaji8b6487f2015-05-26 16:21:47 +0900959 w.Write(abuf.Bytes())
Fumitoshi Ukai145598a2015-06-19 10:08:17 +0900960 writeByte(w, ')')
Fumitoshi Ukai432a2422015-06-11 15:16:29 +0900961 traceEvent.end(te)
Fumitoshi Ukai6a643232015-06-08 14:11:23 +0900962 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900963 return nil
Shinichiro Hamaji8b6487f2015-05-26 16:21:47 +0900964 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900965 arg := abuf.String()
966 freeBuf(abuf)
Shinichiro Hamaji89551c92015-04-11 19:33:03 +0900967 shellVar := ev.LookupVar("SHELL")
968 // TODO: Should be Eval, not String.
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +0900969 cmdline := []string{shellVar.String(), "-c", arg}
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900970 if LogFlag {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900971 logf("shell %q", cmdline)
Fumitoshi Ukai44ae8cf2015-06-24 16:44:15 +0900972 }
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900973 cmd := exec.Cmd{
974 Path: cmdline[0],
975 Args: cmdline,
976 Stderr: os.Stderr,
977 }
Fumitoshi Ukai83410132015-06-15 14:50:07 +0900978 te := traceEvent.begin("shell", literal(arg), traceEventMain)
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900979 out, err := cmd.Output()
Fumitoshi Ukai9042b992015-06-23 16:10:27 +0900980 shellStats.add(time.Since(te.t))
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900981 if err != nil {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +0900982 logf("$(shell %q) failed: %q", arg, err)
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900983 }
Shinichiro Hamajiba6b84d2015-06-03 18:46:13 +0900984 w.Write(formatCommandOutput(out))
Fumitoshi Ukai432a2422015-06-11 15:16:29 +0900985 traceEvent.end(te)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +0900986 return nil
Fumitoshi Ukaib36f3872015-04-10 15:06:38 +0900987}
988
Fumitoshi Ukai106fb792015-06-09 10:37:35 +0900989func (f *funcShell) Compact() Value {
990 if len(f.args)-1 < 1 {
991 return f
992 }
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900993 if !UseFindCache && !UseShellBuiltins {
Fumitoshi Ukai106fb792015-06-09 10:37:35 +0900994 return f
995 }
996
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900997 var exp expr
Fumitoshi Ukai44ae8cf2015-06-24 16:44:15 +0900998 switch v := f.args[1].(type) {
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +0900999 case expr:
1000 exp = v
Fumitoshi Ukai44ae8cf2015-06-24 16:44:15 +09001001 default:
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +09001002 exp = expr{v}
Fumitoshi Ukai106fb792015-06-09 10:37:35 +09001003 }
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001004 if UseShellBuiltins {
Fumitoshi Ukai4a708512015-06-11 17:15:49 +09001005 // hack for android
1006 for _, sb := range shBuiltins {
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +09001007 if v, ok := matchExpr(exp, sb.pattern); ok {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001008 logf("shell compact apply %s for %s", sb.name, exp)
Fumitoshi Ukai4a708512015-06-11 17:15:49 +09001009 return sb.compact(f, v)
1010 }
Fumitoshi Ukai76b609e2015-06-10 14:56:49 +09001011 }
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001012 logf("shell compact no match: %s", exp)
Fumitoshi Ukai76b609e2015-06-10 14:56:49 +09001013 }
Fumitoshi Ukai106fb792015-06-09 10:37:35 +09001014 return f
1015}
1016
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001017// https://www.gnu.org/software/make/manual/html_node/Call-Function.html#Call-Function
1018type funcCall struct{ fclosure }
1019
1020func (f *funcCall) Arity() int { return 0 }
1021
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001022func (f *funcCall) Eval(w io.Writer, ev *Evaluator) error {
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001023 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001024 fargs, err := ev.args(abuf, f.args[1:]...)
1025 if err != nil {
1026 return err
1027 }
Fumitoshi Ukaif543f4d2015-06-15 15:21:47 +09001028 varname := fargs[0]
1029 variable := string(varname)
Fumitoshi Ukai83410132015-06-15 14:50:07 +09001030 te := traceEvent.begin("call", literal(variable), traceEventMain)
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001031 if LogFlag {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001032 logf("call %q variable %q", f.args[1], variable)
Fumitoshi Ukai5c04ad82015-06-18 16:14:04 +09001033 }
Fumitoshi Ukaif543f4d2015-06-15 15:21:47 +09001034 v := ev.LookupVar(variable)
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001035 // Evalualte all arguments first before we modify the table.
Shinichiro Hamaji39728f12015-04-11 20:12:23 +09001036 var args []tmpval
Fumitoshi Ukaif0a2ba72015-04-19 00:02:32 +09001037 // $0 is variable.
Fumitoshi Ukaif543f4d2015-06-15 15:21:47 +09001038 args = append(args, tmpval(varname))
Fumitoshi Ukaif0a2ba72015-04-19 00:02:32 +09001039 // TODO(ukai): If variable is the name of a built-in function,
1040 // the built-in function is always invoked (even if a make variable
1041 // by that name also exists).
1042
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001043 for i, arg := range fargs[1:] {
1044 // f.args[2]=>args[1] will be $1.
1045 args = append(args, tmpval(arg))
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001046 if LogFlag {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001047 logf("call $%d: %q=>%q", i+1, arg, fargs[i+1])
Fumitoshi Ukai5c04ad82015-06-18 16:14:04 +09001048 }
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001049 }
Fumitoshi Ukaif0a2ba72015-04-19 00:02:32 +09001050 oldParams := ev.paramVars
1051 ev.paramVars = args
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001052
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001053 var buf bytes.Buffer
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001054 if LogFlag {
Fumitoshi Ukaie27a25d2015-04-18 00:31:01 +09001055 w = io.MultiWriter(w, &buf)
1056 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001057 err = v.Eval(w, ev)
1058 if err != nil {
1059 return err
1060 }
Fumitoshi Ukaif0a2ba72015-04-19 00:02:32 +09001061 ev.paramVars = oldParams
Fumitoshi Ukai72598e72015-06-11 15:53:09 +09001062 traceEvent.end(te)
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001063 if LogFlag {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001064 logf("call %q variable %q return %q", f.args[1], variable, buf.Bytes())
Fumitoshi Ukai5c04ad82015-06-18 16:14:04 +09001065 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001066 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001067 return nil
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001068}
1069
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +09001070// http://www.gnu.org/software/make/manual/make.html#Value-Function
1071type funcValue struct{ fclosure }
1072
1073func (f *funcValue) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001074func (f *funcValue) Eval(w io.Writer, ev *Evaluator) error {
1075 err := assertArity("value", 1, len(f.args))
1076 if err != nil {
1077 return err
1078 }
Fumitoshi Ukaibbb0db52015-06-30 16:51:27 +09001079 abuf := newBuf()
1080 err = f.args[1].Eval(abuf, ev)
1081 if err != nil {
1082 return err
1083 }
1084 v := ev.LookupVar(abuf.String())
1085 freeBuf(abuf)
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001086 io.WriteString(w, v.String())
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001087 return nil
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +09001088}
1089
1090// http://www.gnu.org/software/make/manual/make.html#Eval-Function
1091type funcEval struct{ fclosure }
1092
1093func (f *funcEval) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001094func (f *funcEval) Eval(w io.Writer, ev *Evaluator) error {
1095 err := assertArity("eval", 1, len(f.args))
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +09001096 if err != nil {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001097 return err
1098 }
1099 abuf := newBuf()
1100 err = f.args[1].Eval(abuf, ev)
1101 if err != nil {
1102 return err
1103 }
1104 s := abuf.Bytes()
1105 logf("eval %q at %s", s, ev.srcpos)
1106 mk, err := parseMakefileBytes(s, ev.srcpos)
1107 if err != nil {
1108 return ev.errorf("%v", err)
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +09001109 }
1110
1111 for _, stmt := range mk.stmts {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001112 err = ev.eval(stmt)
1113 if err != nil {
1114 return err
1115 }
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +09001116 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001117 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001118 return nil
Shinichiro Hamaji28ea5bc2015-04-11 12:41:08 +09001119}
1120
Fumitoshi Ukai9f6b6352015-04-16 16:25:09 +09001121func (f *funcEval) Compact() Value {
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001122 if len(f.args)-1 < 1 {
1123 return f
1124 }
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001125 switch arg := f.args[1].(type) {
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001126 case literal, tmpval:
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +09001127 case expr:
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001128 if len(arg) == 1 {
1129 return f
1130 }
1131 switch prefix := arg[0].(type) {
1132 case literal, tmpval:
1133 lhs, op, rhsprefix, ok := parseAssignLiteral(prefix.String())
1134 if ok {
1135 // $(eval foo = $(bar))
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +09001136 var rhs expr
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001137 if rhsprefix != literal("") {
1138 rhs = append(rhs, rhsprefix)
1139 }
1140 rhs = append(rhs, arg[1:]...)
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001141 logf("eval assign %#v => lhs:%q op:%q rhs:%#v", f, lhs, op, rhs)
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001142 return &funcEvalAssign{
1143 lhs: lhs,
1144 op: op,
1145 rhs: compactExpr(rhs),
1146 }
1147 }
1148 }
1149 // TODO(ukai): eval -> varassign. e.g $(eval $(foo) := $(x)).
Fumitoshi Ukai769157a2015-06-02 15:18:53 +09001150 return f
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001151 default:
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001152 return f
1153 }
1154 arg := f.args[1].String()
1155 arg = stripComment(arg)
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001156 if arg == "" || strings.TrimSpace(arg) == "" {
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001157 return &funcNop{expr: f.String()}
1158 }
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001159 f.args[1] = literal(arg)
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001160 lhs, op, rhs, ok := parseAssignLiteral(f.args[1].String())
1161 if ok {
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001162 return &funcEvalAssign{
1163 lhs: lhs,
1164 op: op,
1165 rhs: rhs,
1166 }
1167 }
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001168 return f
1169}
1170
1171func stripComment(arg string) string {
1172 for {
1173 i := strings.Index(arg, "#")
1174 if i < 0 {
1175 return arg
1176 }
1177 eol := strings.Index(arg[i:], "\n")
1178 if eol < 0 {
1179 return arg[:i]
1180 }
1181 arg = arg[:i] + arg[eol+1:]
1182 }
1183}
1184
1185type funcNop struct{ expr string }
1186
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001187func (f *funcNop) String() string { return f.expr }
1188func (f *funcNop) Eval(io.Writer, *Evaluator) error { return nil }
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +09001189func (f *funcNop) serialize() serializableVar {
1190 return serializableVar{
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +09001191 Type: "funcNop",
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001192 V: f.expr,
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +09001193 }
1194}
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001195func (f *funcNop) dump(d *dumpbuf) {
1196 d.Byte(valueTypeNop)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +09001197}
Fumitoshi Ukaida7f2552015-04-16 13:33:37 +09001198
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001199func parseAssignLiteral(s string) (lhs, op string, rhs Value, ok bool) {
1200 eq := strings.Index(s, "=")
1201 if eq < 0 {
1202 return "", "", nil, false
1203 }
1204 // TODO(ukai): factor out parse assign?
1205 lhs = s[:eq]
1206 op = s[eq : eq+1]
1207 if eq >= 1 && (s[eq-1] == ':' || s[eq-1] == '+' || s[eq-1] == '?') {
1208 lhs = s[:eq-1]
1209 op = s[eq-1 : eq+1]
1210 }
1211 lhs = strings.TrimSpace(lhs)
1212 if strings.IndexAny(lhs, ":$") >= 0 {
1213 // target specific var, or need eval.
1214 return "", "", nil, false
1215 }
1216 r := strings.TrimLeft(s[eq+1:], " \t")
1217 rhs = literal(r)
1218 return lhs, op, rhs, true
1219}
1220
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001221type funcEvalAssign struct {
1222 lhs string
1223 op string
1224 rhs Value
1225}
1226
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001227func (f *funcEvalAssign) String() string {
1228 return fmt.Sprintf("$(eval %s %s %s)", f.lhs, f.op, f.rhs)
1229}
1230
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001231func (f *funcEvalAssign) Eval(w io.Writer, ev *Evaluator) error {
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001232 var abuf bytes.Buffer
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001233 err := f.rhs.Eval(&abuf, ev)
1234 if err != nil {
1235 return err
1236 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001237 rhs := trimLeftSpaceBytes(abuf.Bytes())
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001238 var rvalue Var
1239 switch f.op {
1240 case ":=":
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001241 // TODO(ukai): compute parsed expr in Compact when f.rhs is
1242 // literal? e.g. literal("$(foo)") => varref{literal("foo")}.
Fumitoshi Ukai55c8fa92015-06-25 15:56:10 +09001243 exp, _, err := parseExpr(rhs, nil, false)
Fumitoshi Ukaifa5e9222015-04-17 11:45:20 +09001244 if err != nil {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001245 return ev.errorf("eval assign error: %q: %v", f.String(), err)
Fumitoshi Ukaifa5e9222015-04-17 11:45:20 +09001246 }
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +09001247 vbuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001248 err = exp.Eval(vbuf, ev)
1249 if err != nil {
1250 return err
1251 }
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +09001252 rvalue = &simpleVar{value: vbuf.String(), origin: "file"}
Fumitoshi Ukaidd248f22015-06-18 23:04:28 +09001253 freeBuf(vbuf)
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001254 case "=":
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +09001255 rvalue = &recursiveVar{expr: tmpval(rhs), origin: "file"}
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001256 case "+=":
1257 prev := ev.LookupVar(f.lhs)
Fumitoshi Ukaid8cec172015-04-28 00:08:09 +09001258 if prev.IsDefined() {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001259 rvalue, err = prev.Append(ev, string(rhs))
1260 if err != nil {
1261 return err
1262 }
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001263 } else {
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +09001264 rvalue = &recursiveVar{expr: tmpval(rhs), origin: "file"}
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001265 }
1266 case "?=":
1267 prev := ev.LookupVar(f.lhs)
1268 if prev.IsDefined() {
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001269 return nil
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001270 }
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +09001271 rvalue = &recursiveVar{expr: tmpval(rhs), origin: "file"}
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001272 }
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001273 if LogFlag {
Fumitoshi Ukai07cf1212015-06-25 17:16:25 +09001274 logf("Eval ASSIGN: %s=%q (flavor:%q)", f.lhs, rvalue, rvalue.Flavor())
Fumitoshi Ukai5c04ad82015-06-18 16:14:04 +09001275 }
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001276 ev.outVars.Assign(f.lhs, rvalue)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001277 return nil
Fumitoshi Ukai150c8612015-04-16 15:35:44 +09001278}
1279
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +09001280func (f *funcEvalAssign) serialize() serializableVar {
1281 return serializableVar{
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +09001282 Type: "funcEvalAssign",
Fumitoshi Ukaia045ccb2015-06-25 12:57:25 +09001283 Children: []serializableVar{
1284 serializableVar{V: f.lhs},
1285 serializableVar{V: f.op},
1286 f.rhs.serialize(),
Shinichiro Hamajic8bc7312015-04-28 02:48:03 +09001287 },
1288 }
1289}
1290
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001291func (f *funcEvalAssign) dump(d *dumpbuf) {
1292 d.Byte(valueTypeAssign)
1293 d.Str(f.lhs)
1294 d.Str(f.op)
1295 f.rhs.dump(d)
Shinichiro Hamaji723f56a2015-05-15 17:12:55 +09001296}
1297
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +09001298// http://www.gnu.org/software/make/manual/make.html#Origin-Function
1299type funcOrigin struct{ fclosure }
1300
1301func (f *funcOrigin) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001302func (f *funcOrigin) Eval(w io.Writer, ev *Evaluator) error {
1303 err := assertArity("origin", 1, len(f.args))
1304 if err != nil {
1305 return err
1306 }
Fumitoshi Ukaib64400e2015-06-30 16:06:09 +09001307 abuf := newBuf()
1308 err = f.args[1].Eval(abuf, ev)
1309 if err != nil {
1310 return err
1311 }
1312 v := ev.LookupVar(abuf.String())
1313 freeBuf(abuf)
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001314 io.WriteString(w, v.Origin())
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001315 return nil
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +09001316}
1317
1318// https://www.gnu.org/software/make/manual/html_node/Flavor-Function.html#Flavor-Function
1319type funcFlavor struct{ fclosure }
1320
1321func (f *funcFlavor) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001322func (f *funcFlavor) Eval(w io.Writer, ev *Evaluator) error {
1323 err := assertArity("flavor", 1, len(f.args))
1324 if err != nil {
1325 return err
1326 }
Fumitoshi Ukaib64400e2015-06-30 16:06:09 +09001327 abuf := newBuf()
1328 err = f.args[1].Eval(abuf, ev)
1329 if err != nil {
1330 return err
1331 }
1332 v := ev.LookupVar(abuf.String())
1333 freeBuf(abuf)
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001334 io.WriteString(w, v.Flavor())
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001335 return nil
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +09001336}
1337
1338// http://www.gnu.org/software/make/manual/make.html#Make-Control-Functions
1339type funcInfo struct{ fclosure }
1340
1341func (f *funcInfo) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001342func (f *funcInfo) Eval(w io.Writer, ev *Evaluator) error {
1343 err := assertArity("info", 1, len(f.args))
1344 if err != nil {
1345 return err
1346 }
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001347 if ev.avoidIO {
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001348 io.WriteString(w, "KATI_TODO(info)")
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001349 ev.hasIO = true
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001350 return nil
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001351 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001352 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001353 err = f.args[1].Eval(abuf, ev)
1354 if err != nil {
1355 return err
1356 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001357 fmt.Printf("%s\n", abuf.String())
1358 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001359 return nil
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +09001360}
1361
1362type funcWarning struct{ fclosure }
1363
1364func (f *funcWarning) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001365func (f *funcWarning) Eval(w io.Writer, ev *Evaluator) error {
1366 err := assertArity("warning", 1, len(f.args))
1367 if err != nil {
1368 return err
1369 }
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001370 if ev.avoidIO {
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001371 io.WriteString(w, "KATI_TODO(warning)")
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001372 ev.hasIO = true
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001373 return nil
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001374 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001375 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001376 err = f.args[1].Eval(abuf, ev)
1377 if err != nil {
1378 return err
1379 }
1380 fmt.Printf("%s: %s\n", ev.srcpos, abuf.String())
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001381 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001382 return nil
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +09001383}
1384
1385type funcError struct{ fclosure }
1386
1387func (f *funcError) Arity() int { return 1 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001388func (f *funcError) Eval(w io.Writer, ev *Evaluator) error {
1389 err := assertArity("error", 1, len(f.args))
1390 if err != nil {
1391 return err
1392 }
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001393 if ev.avoidIO {
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001394 io.WriteString(w, "KATI_TODO(error)")
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001395 ev.hasIO = true
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001396 return nil
Shinichiro Hamajib41fd502015-04-29 03:34:07 +09001397 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001398 var abuf buffer
1399 err = f.args[1].Eval(&abuf, ev)
1400 if err != nil {
1401 return err
1402 }
1403 return ev.errorf("*** %s.", abuf.String())
Shinichiro Hamaji916f35f2015-04-11 12:46:19 +09001404}
1405
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001406// http://www.gnu.org/software/make/manual/make.html#Foreach-Function
1407type funcForeach struct{ fclosure }
1408
1409func (f *funcForeach) Arity() int { return 3 }
1410
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001411func (f *funcForeach) Eval(w io.Writer, ev *Evaluator) error {
1412 err := assertArity("foreach", 3, len(f.args))
1413 if err != nil {
1414 return err
1415 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001416 abuf := newBuf()
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001417 fargs, err := ev.args(abuf, f.args[1], f.args[2])
1418 if err != nil {
1419 return err
1420 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001421 varname := string(fargs[0])
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +09001422 ws := newWordScanner(fargs[1])
Fumitoshi Ukaib2670d92015-04-16 10:28:27 +09001423 text := f.args[3]
Fumitoshi Ukai9b10ecf2015-04-15 17:45:50 +09001424 restore := ev.outVars.save(varname)
1425 defer restore()
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001426 space := false
Fumitoshi Ukai9da19f62015-05-08 14:39:08 +09001427 for ws.Scan() {
1428 word := ws.Bytes()
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +09001429 ev.outVars.Assign(varname, &automaticVar{value: word})
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001430 if space {
Fumitoshi Ukai145598a2015-06-19 10:08:17 +09001431 writeByte(w, ' ')
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001432 }
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001433 err = text.Eval(w, ev)
1434 if err != nil {
1435 return err
1436 }
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001437 space = true
1438 }
Fumitoshi Ukaib06cd9d2015-05-07 12:56:12 +09001439 freeBuf(abuf)
Fumitoshi Ukai65c72332015-06-26 21:32:50 +09001440 return nil
Fumitoshi Ukaid2bcf662015-04-11 01:02:27 +09001441}