Add a mkfiledir variable that evuates to the full path of the current mkfile.

This commit is contained in:
Daniel Jones 2014-08-05 14:16:59 -07:00
parent 4554b8c6cb
commit 49fdbebf48
2 changed files with 22 additions and 7 deletions

8
mk.go
View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"strings" "strings"
"sync" "sync"
) )
@ -312,7 +313,12 @@ func main() {
input, _ := ioutil.ReadAll(mkfile) input, _ := ioutil.ReadAll(mkfile)
mkfile.Close() mkfile.Close()
rs := parse(string(input), mkfilepath) abspath, err := filepath.Abs(mkfilepath)
if err != nil {
mkError("unable to find mkfile's absolute path")
}
rs := parse(string(input), mkfilepath, abspath)
targets := flag.Args() targets := flag.Args()
// build the first non-meta rule in the makefile, if none are given explicitly // build the first non-meta rule in the makefile, if none are given explicitly

View file

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath"
"regexp" "regexp"
"strings" "strings"
) )
@ -14,6 +15,7 @@ import (
type parser struct { type parser struct {
l *lexer // underlying lexer l *lexer // underlying lexer
name string // name of the file being parsed name string // name of the file being parsed
path string // full path of the file being parsed
tokenbuf []token // tokens consumed on the current statement tokenbuf []token // tokens consumed on the current statement
rules *ruleSet // current ruleSet rules *ruleSet // current ruleSet
} }
@ -50,18 +52,19 @@ func (p *parser) clear() {
type parserStateFun func(*parser, token) parserStateFun type parserStateFun func(*parser, token) parserStateFun
// Parse a mkfile, returning a new ruleSet. // Parse a mkfile, returning a new ruleSet.
func parse(input string, name string) *ruleSet { func parse(input string, name string, path string) *ruleSet {
rules := &ruleSet{make(map[string][]string), rules := &ruleSet{make(map[string][]string),
make([]rule, 0), make([]rule, 0),
make(map[string][]int)} make(map[string][]int)}
parseInto(input, name, rules) parseInto(input, name, rules, path)
return rules return rules
} }
// Parse a mkfile inserting rules and variables into a given ruleSet. // Parse a mkfile inserting rules and variables into a given ruleSet.
func parseInto(input string, name string, rules *ruleSet) { func parseInto(input string, name string, rules *ruleSet, path string) {
l, tokens := lex(input) l, tokens := lex(input)
p := &parser{l, name, []token{}, rules} p := &parser{l, name, path, []token{}, rules}
p.rules.vars["mkfiledir"] = []string{filepath.Dir(path)}
state := parseTopLevel state := parseTopLevel
for t := range tokens { for t := range tokens {
if t.typ == tokenError { if t.typ == tokenError {
@ -117,7 +120,7 @@ func parsePipeInclude(p *parser, t token) parserStateFun {
p.basicErrorAtToken("subprocess include failed", t) p.basicErrorAtToken("subprocess include failed", t)
} }
parseInto(output, fmt.Sprintf("%s:sh", p.name), p.rules) parseInto(output, fmt.Sprintf("%s:sh", p.name), p.rules, p.path)
p.clear() p.clear()
return parseTopLevel return parseTopLevel
@ -154,7 +157,13 @@ func parseRedirInclude(p *parser, t token) parserStateFun {
p.basicErrorAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0]) p.basicErrorAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0])
} }
input, _ := ioutil.ReadAll(file) input, _ := ioutil.ReadAll(file)
parseInto(string(input), filename, p.rules)
path, err := filepath.Abs(filename)
if err != nil {
mkError("unable to find mkfile's absolute path")
}
parseInto(string(input), filename, p.rules, path)
p.clear() p.clear()
return parseTopLevel return parseTopLevel