factor out func.go
diff --git a/eval.go b/eval.go
index baa36cf..040995a 100644
--- a/eval.go
+++ b/eval.go
@@ -3,9 +3,6 @@
import (
"bytes"
"fmt"
- "os/exec"
- "path/filepath"
- "regexp"
"strings"
)
@@ -28,6 +25,8 @@
vars map[string]string
curRule *Rule
+ funcs map[string]Func
+
filename string
lineno int
}
@@ -37,39 +36,23 @@
outVars: make(map[string]string),
refs: make(map[string]bool),
vars: make(map[string]string),
+ funcs: map[string]Func{
+ "wildcard": funcWildcard,
+ "shell": funcShell,
+ "warning": funcWarning,
+ },
}
}
func (ev *Evaluator) evalFunction(ex string) (string, bool) {
- if strings.HasPrefix(ex, "wildcard ") {
- arg := ex[len("wildcard "):]
-
- files, err := filepath.Glob(arg)
- if err != nil {
- panic(err)
- }
- return strings.Join(files, " "), true
- } else if strings.HasPrefix(ex, "shell ") {
- arg := ex[len("shell "):]
-
- args := []string{"/bin/sh", "-c", arg}
- cmd := exec.Cmd{
- Path: args[0],
- Args: args,
- }
- out, err := cmd.CombinedOutput()
- if err != nil {
- panic(err)
- }
- re, err := regexp.Compile(`\s`)
- if err != nil {
- panic(err)
- }
- return string(re.ReplaceAllString(string(out), " ")), true
- } else if strings.HasPrefix(ex, "warning ") {
- arg := ex[len("warning "):]
- fmt.Printf("%s:%d: %s\n", ev.filename, ev.lineno, arg)
- return "", true
+ i := strings.IndexAny(ex, " \t")
+ if i < 0 {
+ return "", false
+ }
+ cmd := strings.TrimSpace(ex[:i])
+ args := strings.TrimLeft(ex[i+1:], " \t")
+ if f, ok := ev.funcs[cmd]; ok {
+ return f(ev, args), true
}
return "", false
}
diff --git a/func.go b/func.go
new file mode 100644
index 0000000..0d05664
--- /dev/null
+++ b/func.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+ "fmt"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+// Func is a make function.
+// http://www.gnu.org/software/make/manual/make.html#Functions
+// TODO(ukai): *Evaluator -> eval context or so?
+// TODO(ukai): return error instead of panic?
+type Func func(*Evaluator, string) string
+
+// http://www.gnu.org/software/make/manual/make.html#File-Name-Functions
+func funcWildcard(_ *Evaluator, arg string) string {
+ files, err := filepath.Glob(arg)
+ if err != nil {
+ panic(err)
+ }
+ return strings.Join(files, " ")
+}
+
+// http://www.gnu.org/software/make/manual/make.html#Shell-Function
+func funcShell(_ *Evaluator, arg string) string {
+ args := []string{"/bin/sh", "-c", arg}
+ cmd := exec.Cmd{
+ Path: args[0],
+ Args: args,
+ }
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ panic(err)
+ }
+ re, err := regexp.Compile(`\s`)
+ if err != nil {
+ panic(err)
+ }
+ return string(re.ReplaceAllString(string(out), " "))
+}
+
+// http://www.gnu.org/software/make/manual/make.html#Make-Control-Functions
+func funcWarning(ev *Evaluator, arg string) string {
+ fmt.Printf("%s:%d: %s\n", ev.filename, ev.lineno, arg)
+ return ""
+}