blob: da17a31fdcef11559ff2b4c428b089250a316d78 [file] [log] [blame]
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +09001package main
2
3import (
4 "fmt"
5 "os/exec"
6 "path/filepath"
Shinichiro Hamaji13b30d92015-04-03 14:42:21 +09007 "sort"
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +09008 "strconv"
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +09009 "strings"
10)
11
12// Func is a make function.
13// http://www.gnu.org/software/make/manual/make.html#Functions
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090014// TODO(ukai): return error instead of panic?
Fumitoshi Ukaie520f262015-03-31 17:27:03 +090015type Func func(*Evaluator, []string) string
16
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090017func arity(name string, req int, args []string) []string {
18 if len(args) < req {
19 panic(fmt.Sprintf("*** insufficient number of arguments (%d) to function `%s'.", len(args), name))
20 }
21 args[req-1] = strings.Join(args[req-1:], ",")
22 // TODO(ukai): ev.evalExpr for all args?
23 Log("%s %q", name, args)
24 return args
25}
26
Shinichiro Hamaji4125cf42015-04-03 11:42:28 +090027// http://www.gnu.org/software/make/manual/make.html#Text-Functions
Fumitoshi Ukaie520f262015-03-31 17:27:03 +090028func funcSubst(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090029 args = arity("subst", 3, args)
Fumitoshi Ukaie520f262015-03-31 17:27:03 +090030 from := ev.evalExpr(args[0])
31 to := ev.evalExpr(args[1])
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090032 text := ev.evalExpr(args[2])
Fumitoshi Ukaibb79a9d2015-04-02 12:46:54 +090033 Log("subst from:%q to:%q text:%q", from, to, text)
Fumitoshi Ukaie520f262015-03-31 17:27:03 +090034 return strings.Replace(text, from, to, -1)
35}
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +090036
Shinichiro Hamajiea8b56d2015-04-01 03:39:29 +090037func funcPatsubst(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090038 args = arity("patsubst", 3, args)
Shinichiro Hamajiea8b56d2015-04-01 03:39:29 +090039 pat := ev.evalExpr(args[0])
40 repl := ev.evalExpr(args[1])
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090041 texts := splitSpaces(ev.evalExpr(args[2]))
Shinichiro Hamajiea8b56d2015-04-01 03:39:29 +090042 for i, text := range texts {
43 texts[i] = substPattern(pat, repl, text)
44 }
45 return strings.Join(texts, " ")
46}
47
Shinichiro Hamaji4125cf42015-04-03 11:42:28 +090048func funcStrip(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090049 args = arity("strip", 1, args)
50 text := ev.evalExpr(args[0])
Shinichiro Hamaji4125cf42015-04-03 11:42:28 +090051 return strings.TrimSpace(text)
52}
53
54func funcFindstring(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090055 args = arity("findstring", 2, args)
Shinichiro Hamaji47ffb722015-04-03 11:48:45 +090056 f := ev.evalExpr(args[0])
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090057 text := ev.evalExpr(args[1])
Shinichiro Hamaji47ffb722015-04-03 11:48:45 +090058 if strings.Index(text, f) >= 0 {
59 return f
60 }
Shinichiro Hamaji4125cf42015-04-03 11:42:28 +090061 return ""
62}
63
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090064func funcFilter(ev *Evaluator, args []string) string {
65 args = arity("filter", 2, args)
66 patterns := splitSpaces(ev.evalExpr(args[0]))
67 texts := splitSpaces(ev.evalExpr(args[1]))
68 var result []string
69 for _, text := range texts {
70 for _, pat := range patterns {
71 if matchPattern(pat, text) {
72 result = append(result, text)
73 }
74 }
75 }
76 return strings.Join(result, " ")
77}
78
79func funcFilterOut(ev *Evaluator, args []string) string {
80 args = arity("filter-out", 2, args)
81 patterns := splitSpaces(ev.evalExpr(args[0]))
82 texts := splitSpaces(ev.evalExpr(args[1]))
83 var result []string
84Loop:
85 for _, text := range texts {
86 for _, pat := range patterns {
87 if matchPattern(pat, text) {
88 continue Loop
89 }
90 }
91 result = append(result, text)
92 }
93 return strings.Join(result, " ")
94}
Shinichiro Hamaji13b30d92015-04-03 14:42:21 +090095
96func funcSort(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +090097 args = arity("sort", 1, args)
98 toks := splitSpaces(ev.evalExpr(args[0]))
Shinichiro Hamaji13b30d92015-04-03 14:42:21 +090099 sort.Strings(toks)
100
101 // Remove duplicate words.
102 var prev string
103 var result []string
104 for _, tok := range toks {
105 if prev != tok {
106 result = append(result, tok)
107 prev = tok
108 }
109 }
110 return strings.Join(result, " ")
111}
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900112
113func numericValueForFunc(ev *Evaluator, a string, funcName string, nth string) int {
114 a = strings.TrimSpace(ev.evalExpr(a))
115 n, err := strconv.Atoi(a)
116 if err != nil || n < 0 {
117 Error(ev.filename, ev.lineno, `*** non-numeric %s argument to "%s" function: "%s".`, nth, funcName, a)
118 }
119 return n
120}
121
122func funcWord(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900123 args = arity("word", 2, args)
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900124 index := numericValueForFunc(ev, args[0], "word", "first")
125 if index == 0 {
126 Error(ev.filename, ev.lineno, `*** first argument to "word" function must be greater than 0.`)
127 }
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900128 toks := splitSpaces(ev.evalExpr(args[1]))
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900129 if index-1 >= len(toks) {
130 return ""
131 }
132 return ev.evalExpr(toks[index-1])
133}
134
135func funcWordlist(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900136 args = arity("wordlist", 3, args)
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900137 si := numericValueForFunc(ev, args[0], "wordlist", "first")
138 if si == 0 {
139 Error(ev.filename, ev.lineno, `*** invalid first argument to "wordlist" function: ""`, args[0])
140 }
141 ei := numericValueForFunc(ev, args[1], "wordlist", "second")
142 if ei == 0 {
143 Error(ev.filename, ev.lineno, `*** invalid second argument to "wordlist" function: ""`, args[1])
144 }
145
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900146 toks := splitSpaces(ev.evalExpr(args[2]))
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900147 if si-1 >= len(toks) {
148 return ""
149 }
150 if ei-1 >= len(toks) {
151 ei = len(toks)
152 }
153
154 return strings.Join(toks[si-1:ei], " ")
155}
156
157func funcWords(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900158 args = arity("words", 1, args)
159 toks := splitSpaces(ev.evalExpr(args[0]))
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900160 return strconv.Itoa(len(toks))
161}
162
163func funcFirstword(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900164 args = arity("firstword", 1, args)
165 toks := splitSpaces(ev.evalExpr(args[0]))
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900166 if len(toks) == 0 {
167 return ""
168 }
169 return toks[0]
170}
171
172func funcLastword(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900173 args = arity("lastword", 1, args)
174 toks := splitSpaces(ev.evalExpr(args[0]))
Shinichiro Hamajie708a9d2015-04-03 14:34:35 +0900175 if len(toks) == 0 {
176 return ""
177 }
178 return toks[len(toks)-1]
179}
Shinichiro Hamaji4125cf42015-04-03 11:42:28 +0900180
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900181// http://www.gnu.org/software/make/manual/make.html#File-Name-Functions
Fumitoshi Ukaie520f262015-03-31 17:27:03 +0900182func funcWildcard(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900183 args = arity("wildcard", 1, args)
184 pattern := ev.evalExpr(args[0])
Fumitoshi Ukaie520f262015-03-31 17:27:03 +0900185 files, err := filepath.Glob(pattern)
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900186 if err != nil {
187 panic(err)
188 }
189 return strings.Join(files, " ")
190}
191
Fumitoshi Ukaibb79a9d2015-04-02 12:46:54 +0900192// https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html#File-Name-Functions
193func funcDir(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900194 args = arity("dir", 1, args)
195 names := splitSpaces(ev.evalExpr(args[0]))
Fumitoshi Ukai0a838032015-04-03 17:58:44 +0900196 if len(names) == 0 {
Fumitoshi Ukaibb79a9d2015-04-02 12:46:54 +0900197 return ""
198 }
Fumitoshi Ukai0a838032015-04-03 17:58:44 +0900199 var dirs []string
200 for _, name := range names {
201 dirs = append(dirs, filepath.Dir(name)+string(filepath.Separator))
202 }
203 return strings.Join(dirs, " ")
Fumitoshi Ukaibb79a9d2015-04-02 12:46:54 +0900204}
205
Fumitoshi Ukai538a3152015-04-02 23:39:12 +0900206func funcNotdir(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900207 args = arity("notdir", 1, args)
208 names := splitSpaces(ev.evalExpr(args[0]))
Fumitoshi Ukai0a838032015-04-03 17:58:44 +0900209 if len(names) == 0 {
Fumitoshi Ukai538a3152015-04-02 23:39:12 +0900210 return ""
211 }
Fumitoshi Ukai0a838032015-04-03 17:58:44 +0900212 var notdirs []string
213 for _, name := range names {
214 if name == string(filepath.Separator) {
215 notdirs = append(notdirs, "")
216 continue
217 }
218 notdirs = append(notdirs, filepath.Base(name))
219 }
220 return strings.Join(notdirs, " ")
Fumitoshi Ukai538a3152015-04-02 23:39:12 +0900221}
222
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900223func funcSuffix(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900224 args = arity("suffix", 1, args)
225 toks := splitSpaces(ev.evalExpr(args[0]))
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900226 var result []string
227 for _, tok := range toks {
228 e := filepath.Ext(tok)
229 if len(e) > 0 {
230 result = append(result, e)
231 }
232 }
233 return strings.Join(result, " ")
234}
235
236func funcBasename(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900237 args = arity("basename", 1, args)
238 toks := splitSpaces(ev.evalExpr(args[0]))
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900239 var result []string
240 for _, tok := range toks {
241 b := stripExt(tok)
242 result = append(result, b)
243 }
244 return strings.Join(result, " ")
245}
246
247func funcAddsuffix(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900248 args = arity("addsuffix", 2, args)
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900249 suf := ev.evalExpr(args[0])
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900250 toks := splitSpaces(ev.evalExpr(args[1]))
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900251 for i, tok := range toks {
252 toks[i] = fmt.Sprintf("%s%s", tok, suf)
253 }
254 return strings.Join(toks, " ")
255}
256
257func funcAddprefix(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900258 args = arity("addprefix", 2, args)
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900259 pre := ev.evalExpr(args[0])
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900260 toks := splitSpaces(ev.evalExpr(args[1]))
Shinichiro Hamaji5e2c3c72015-04-03 15:04:54 +0900261 for i, tok := range toks {
262 toks[i] = fmt.Sprintf("%s%s", pre, tok)
263 }
264 return strings.Join(toks, " ")
265}
266
Fumitoshi Ukaic5206362015-04-01 21:37:53 +0900267func funcRealpath(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900268 args = arity("realpath", 1, args)
269 names := splitSpaces(ev.evalExpr(args[0]))
Fumitoshi Ukaic5206362015-04-01 21:37:53 +0900270 var realpaths []string
271 for _, name := range names {
Fumitoshi Ukaic5206362015-04-01 21:37:53 +0900272 name, err := filepath.Abs(name)
273 if err != nil {
274 Log("abs: %v", err)
275 continue
276 }
277 name, err = filepath.EvalSymlinks(name)
278 if err != nil {
279 Log("realpath: %v", err)
280 continue
281 }
282 realpaths = append(realpaths, name)
283 }
284 return strings.Join(realpaths, " ")
285}
286
287func funcAbspath(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900288 args = arity("abspath", 1, args)
289 names := splitSpaces(ev.evalExpr(args[0]))
Fumitoshi Ukaic5206362015-04-01 21:37:53 +0900290 var realpaths []string
291 for _, name := range names {
Fumitoshi Ukaic5206362015-04-01 21:37:53 +0900292 name, err := filepath.Abs(name)
293 if err != nil {
294 Log("abs: %v", err)
295 continue
296 }
297 realpaths = append(realpaths, name)
298 }
299 return strings.Join(realpaths, " ")
300}
301
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900302// http://www.gnu.org/software/make/manual/make.html#Conditional-Functions
303func funcIf(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900304 args = arity("if", 3, args)
Fumitoshi Ukaib8bdfd52015-04-03 23:08:57 +0900305 cond := ev.evalExpr(strings.TrimSpace(args[0]))
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900306 if cond != "" {
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900307 return ev.evalExpr(args[1])
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900308 }
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900309 return ev.evalExpr(args[2])
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900310}
311
312func funcOr(ev *Evaluator, args []string) string {
Fumitoshi Ukaib8bdfd52015-04-03 23:08:57 +0900313 for _, arg := range args {
314 cond := ev.evalExpr(strings.TrimSpace(arg))
315 if cond != "" {
316 return cond
317 }
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900318 }
Fumitoshi Ukaib8bdfd52015-04-03 23:08:57 +0900319 return ""
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900320}
321
322func funcAnd(ev *Evaluator, args []string) string {
Fumitoshi Ukaib8bdfd52015-04-03 23:08:57 +0900323 var cond string
324 for _, arg := range args {
325 cond = ev.evalExpr(strings.TrimSpace(arg))
326 if cond == "" {
327 return ""
328 }
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900329 }
Fumitoshi Ukaib8bdfd52015-04-03 23:08:57 +0900330 return cond
Shinichiro Hamaji48a85e32015-04-03 17:03:49 +0900331}
332
Shinichiro Hamaji8c75f0b2015-04-03 16:35:21 +0900333// http://www.gnu.org/software/make/manual/make.html#Foreach-Function
334func funcForeach(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900335 args = arity("foreach", 3, args)
Shinichiro Hamaji8c75f0b2015-04-03 16:35:21 +0900336 var result []string
337 varName := ev.evalExpr(args[0])
338 values := splitSpaces(ev.evalExpr(args[1]))
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900339 expr := args[2]
Shinichiro Hamaji8c75f0b2015-04-03 16:35:21 +0900340 for _, val := range values {
341 newVars := NewVarTab(ev.vars)
342 newVars.Assign(varName,
343 SimpleVar{
344 value: val,
345 origin: "automatic",
346 })
347 oldVars := ev.vars
348 ev.vars = newVars
349 result = append(result, ev.evalExpr(expr))
350 ev.vars = oldVars
351 }
352 return strings.Join(result, " ")
353}
354
Shinichiro Hamaji8c5b25a2015-04-04 18:46:37 +0900355// http://www.gnu.org/software/make/manual/make.html#Value-Function
356func funcValue(ev *Evaluator, args []string) string {
357 v := ev.LookupVar(strings.Join(args, ","))
358 return v.String()
359}
360
Shinichiro Hamaji8c75f0b2015-04-03 16:35:21 +0900361// http://www.gnu.org/software/make/manual/make.html#Eval-Function
362func funcEval(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900363 args = arity("eval", 1, args)
364 s := ev.evalExpr(args[0])
Shinichiro Hamajib4ac1b52015-04-03 16:44:04 +0900365 mk, err := ParseMakefileString(s, "*eval*")
366 if err != nil {
367 panic(err)
368 }
369
370 er, err2 := Eval(mk, ev.VarTab())
371 if err2 != nil {
372 panic(err2)
373 }
374
375 for k, v := range er.vars.Vars() {
376 ev.outVars.Assign(k, v)
377 }
378 for _, r := range er.rules {
379 ev.outRules = append(ev.outRules, r)
380 }
381
Shinichiro Hamaji8c75f0b2015-04-03 16:35:21 +0900382 return ""
383}
384
Shinichiro Hamaji7ff34db2015-04-04 18:55:20 +0900385// http://www.gnu.org/software/make/manual/make.html#Origin-Function
386func funcOrigin(ev *Evaluator, args []string) string {
387 v := ev.LookupVar(strings.Join(args, ","))
388 return v.Origin()
389}
390
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900391// http://www.gnu.org/software/make/manual/make.html#Shell-Function
Fumitoshi Ukaie520f262015-03-31 17:27:03 +0900392func funcShell(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900393 args = arity("shell", 1, args)
394 arg := ev.evalExpr(args[0])
Fumitoshi Ukaie520f262015-03-31 17:27:03 +0900395 cmdline := []string{"/bin/sh", "-c", arg}
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900396 cmd := exec.Cmd{
Fumitoshi Ukaie520f262015-03-31 17:27:03 +0900397 Path: cmdline[0],
398 Args: cmdline,
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900399 }
400 out, err := cmd.CombinedOutput()
401 if err != nil {
Shinichiro Hamaji79abd182015-04-03 11:07:38 +0900402 Log("$(shell %q) failed: %q", args, err)
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900403 }
Shinichiro Hamaji79abd182015-04-03 11:07:38 +0900404
405 r := string(out)
406 r = strings.TrimRight(r, "\n")
407 return strings.Replace(r, "\n", " ", -1)
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900408}
409
Fumitoshi Ukaibb79a9d2015-04-02 12:46:54 +0900410// https://www.gnu.org/software/make/manual/html_node/Call-Function.html#Call-Function
411func funcCall(ev *Evaluator, args []string) string {
Fumitoshi Ukaibb79a9d2015-04-02 12:46:54 +0900412 f := ev.LookupVar(args[0]).String()
413 Log("call func %q => %q", args[0], f)
414 localVars := NewVarTab(ev.VarTab())
415 for i, argstr := range args[1:] {
416 arg := ev.evalExpr(argstr)
417 Log("call $%d: %q=>%q", i+1, argstr, arg)
418 localVars.Assign(fmt.Sprintf("%d", i+1),
419 RecursiveVar{
420 expr: arg,
421 origin: "automatic", // ??
422 })
423 }
424 ev = newEvaluator(localVars)
425 r := ev.evalExpr(f)
426 Log("call %q return %q", args[0], r)
427 return r
428}
429
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900430// https://www.gnu.org/software/make/manual/html_node/Flavor-Function.html#Flavor-Function
431func funcFlavor(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900432 args = arity("flavor", 1, args)
433 vname := args[0]
Fumitoshi Ukai8edcb792015-04-02 11:23:23 +0900434 return ev.LookupVar(vname).Flavor()
435}
436
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900437// http://www.gnu.org/software/make/manual/make.html#Make-Control-Functions
Shinichiro Hamajic565e442015-04-03 11:26:27 +0900438func funcInfo(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900439 args = arity("warning", 1, args)
440 arg := ev.evalExpr(args[0])
Shinichiro Hamajic565e442015-04-03 11:26:27 +0900441 fmt.Printf("%s\n", arg)
442 return ""
443}
444
Fumitoshi Ukaie520f262015-03-31 17:27:03 +0900445func funcWarning(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900446 args = arity("warning", 1, args)
447 arg := ev.evalExpr(args[0])
Fumitoshi Ukaif2f84562015-03-30 19:47:45 +0900448 fmt.Printf("%s:%d: %s\n", ev.filename, ev.lineno, arg)
449 return ""
450}
Shinichiro Hamajic565e442015-04-03 11:26:27 +0900451
452func funcError(ev *Evaluator, args []string) string {
Fumitoshi Ukai0b5e18b2015-04-03 22:57:17 +0900453 args = arity("error", 1, args)
454 arg := ev.evalExpr(args[0])
Shinichiro Hamajic565e442015-04-03 11:26:27 +0900455 Error(ev.filename, ev.lineno, "*** %s.", arg)
456 return ""
457}