This commit is contained in:
DiablosOffens 2016-08-30 14:59:34 +00:00 committed by GitHub
commit fe95fa4679
4 changed files with 26 additions and 11 deletions

View file

@ -5,6 +5,7 @@ package main
import ( import (
"regexp" "regexp"
"strings" "strings"
"os"
"unicode/utf8" "unicode/utf8"
) )
@ -89,31 +90,35 @@ func expandEscape(input string) (string, int) {
if c == '\t' || c == ' ' { if c == '\t' || c == ' ' {
return string(c), w return string(c), w
} }
if c == '\n' {
return "", w
}
return "\\" + string(c), w return "\\" + string(c), w
} }
// Expand a double quoted string starting after a '\"' // Expand a double quoted string starting after a '\"'
func expandDoubleQuoted(input string, vars map[string][]string, expandBackticks bool) (string, int) { func expandDoubleQuoted(input string, vars map[string][]string, expandBackticks bool) (string, int) {
// find the first non-escaped " // find the first non-escaped "
i := 0
j := 0 j := 0
for { for {
j = strings.IndexAny(input[j:], "\"\\") j = strings.IndexAny(input[i:], "\"\\")
if j < 0 { if j < 0 {
break break
} }
j += i
c, w := utf8.DecodeRuneInString(input[j:]) c, w := utf8.DecodeRuneInString(input[j:])
j += w i = j + w
if c == '"' { if c == '"' {
return strings.Join(expand(input[:j], vars, expandBackticks), " "), (j + w) return strings.Join(expand(input[:j], vars, expandBackticks), " "), i
} }
if c == '\\' { if c == '\\' {
if j+w < len(input) { if i < len(input) {
j += w _, w := utf8.DecodeRuneInString(input[i:])
_, w := utf8.DecodeRuneInString(input[j:]) i += w
j += w
} else { } else {
break break
} }
@ -303,9 +308,14 @@ func expandBackQuoted(input string, vars map[string][]string) ([]string, int) {
if j < 0 { if j < 0 {
return []string{input}, len(input) return []string{input}, len(input)
} }
env := os.Environ()
for key, values := range vars {
env = append(env, key + "=" + strings.Join(values, " "))
}
// TODO: handle errors // TODO: handle errors
output, _ := subprocess("sh", nil, input[:j], true) output, _ := subprocess("sh", nil, env, input[:j], true)
parts := make([]string, 0) parts := make([]string, 0)
_, tokens := lexWords(output) _, tokens := lexWords(output)

5
mk.go
View file

@ -24,7 +24,9 @@ var rebuildtargets map[string]bool = make(map[string]bool)
var mkMsgMutex sync.Mutex var mkMsgMutex sync.Mutex
// The maximum number of times an rule may be applied. // The maximum number of times an rule may be applied.
const maxRuleCnt = 1 // This limits recursion of both meta- and non-meta-rules!
// Maybe, this shouldn't affect meta-rules?!
var maxRuleCnt int = 1
// Limit the number of recipes executed simultaneously. // Limit the number of recipes executed simultaneously.
var subprocsAllowed int var subprocsAllowed int
@ -312,6 +314,7 @@ func main() {
flag.BoolVar(&shallowrebuild, "r", false, "force building of just targets") flag.BoolVar(&shallowrebuild, "r", false, "force building of just targets")
flag.BoolVar(&rebuildall, "a", false, "force building of all dependencies") flag.BoolVar(&rebuildall, "a", false, "force building of all dependencies")
flag.IntVar(&subprocsAllowed, "p", 4, "maximum number of jobs to execute in parallel") flag.IntVar(&subprocsAllowed, "p", 4, "maximum number of jobs to execute in parallel")
flag.IntVar(&maxRuleCnt, "l", 1, "maximum number of times a specific rule can be applied (recursion)")
flag.BoolVar(&interactive, "i", false, "prompt before executing rules") flag.BoolVar(&interactive, "i", false, "prompt before executing rules")
flag.BoolVar(&quiet, "q", false, "don't print recipes before executing them") flag.BoolVar(&quiet, "q", false, "don't print recipes before executing them")
flag.Parse() flag.Parse()

View file

@ -118,7 +118,7 @@ func parsePipeInclude(p *parser, t token) parserStateFun {
args[i] = p.tokenbuf[i].val args[i] = p.tokenbuf[i].val
} }
output, success := subprocess("sh", args, "", true) output, success := subprocess("sh", args, nil, "", true)
if !success { if !success {
p.basicErrorAtToken("subprocess include failed", t) p.basicErrorAtToken("subprocess include failed", t)
} }

View file

@ -106,6 +106,7 @@ func dorecipe(target string, u *node, e *edge, dryrun bool) bool {
_, success := subprocess( _, success := subprocess(
sh, sh,
args, args,
nil,
input, input,
false) false)
@ -127,6 +128,7 @@ func dorecipe(target string, u *node, e *edge, dryrun bool) bool {
// //
func subprocess(program string, func subprocess(program string,
args []string, args []string,
env []string,
input string, input string,
capture_out bool) (string, bool) { capture_out bool) (string, bool) {
program_path, err := exec.LookPath(program) program_path, err := exec.LookPath(program)
@ -142,7 +144,7 @@ func subprocess(program string,
log.Fatal(err) log.Fatal(err)
} }
attr := os.ProcAttr{Files: []*os.File{stdin_pipe_read, os.Stdout, os.Stderr}} attr := os.ProcAttr{Env: env, Files: []*os.File{stdin_pipe_read, os.Stdout, os.Stderr}}
output := make([]byte, 0) output := make([]byte, 0)
capture_done := make(chan bool) capture_done := make(chan bool)