This commit is contained in:
Daniel Jones 2013-03-03 17:51:00 -08:00
parent ee70f46012
commit 8a218f35c0
6 changed files with 586 additions and 623 deletions

View file

@ -1,4 +1,3 @@
// String substitution and expansion.
package main
@ -8,7 +7,6 @@ import (
"unicode/utf8"
)
// Expand a word. This includes substituting variables and handling quotes.
func expand(input string, vars map[string][]string, expandBackticks bool) []string {
parts := make([]string, 0)
@ -167,7 +165,6 @@ func expandSigil(input string, vars map[string][]string) ([]string, int) {
return []string{"$" + input}, len(input)
}
// Find and expand all sigils.
func expandSigils(input string, vars map[string][]string) []string {
parts := make([]string, 0)
@ -195,7 +192,6 @@ func expandSigils(input string, vars map[string][]string) []string {
return parts
}
// Find and expand all sigils in a recipe, producing a flat string.
func expandRecipeSigils(input string, vars map[string][]string) string {
expanded := ""
@ -229,7 +225,6 @@ func expandRecipeSigils(input string, vars map[string][]string) string {
return expanded
}
// Expand all unescaped '%' characters.
func expandSuffixes(input string, stem string) string {
expanded := make([]byte, 0)
@ -257,10 +252,8 @@ func expandSuffixes(input string, stem string) string {
return string(expanded)
}
// TODO: expand RegexpRefs
// Expand a backtick quoted string, by executing the contents.
func expandBackQuoted(input string, vars map[string][]string) (string, int) {
// TODO: expand sigils?
@ -274,40 +267,34 @@ func expandBackQuoted(input string, vars map[string][]string) (string, int) {
return output, (j + 1)
}
// Split a string on whitespace taking into account escaping and quoting.
//func splitQuoted(input string) []string {
//parts := make([]string, 0)
//var i, j int
//i = 0
//for {
//// skip all unescaped whitespace
//for i < len(input) {
//c, w := utf8.DecodeRuneInString(input[i:])
//if strings.IndexRune(" \t", c) < 0 {
//break
//}
//i += w
//}
//if i >= len(input) {
//break
//}
//// Ugh. Will this take into account quoting in variables?
//switch c {
//case '"':
//case '\'':
//default:
//}
//}
//return parts
//parts := make([]string, 0)
//var i, j int
//i = 0
//for {
//// skip all unescaped whitespace
//for i < len(input) {
//c, w := utf8.DecodeRuneInString(input[i:])
//if strings.IndexRune(" \t", c) < 0 {
//break
//}
//i += w
//}
//if i >= len(input) {
//break
//}
//// Ugh. Will this take into account quoting in variables?
//switch c {
//case '"':
//case '\'':
//default:
//}
//}
//return parts
//}

View file

@ -1,4 +1,3 @@
package main
import (
@ -23,7 +22,6 @@ type edge struct {
r *rule
}
// Current status of a node in the build.
type nodeStatus int
@ -34,7 +32,6 @@ const (
nodeStatusFailed
)
// A node in the dependency graph
type node struct {
r *rule // rule to be applied
@ -80,7 +77,6 @@ func (g *graph) visualize(w io.Writer) {
fmt.Fprintln(w, "}")
}
// Create a new arc.
func (u *node) newedge(v *node, r *rule) *edge {
e := &edge{v: v, r: r}
@ -88,7 +84,6 @@ func (u *node) newedge(v *node, r *rule) *edge {
return e
}
// Create a dependency graph for the given target.
func buildgraph(rs *ruleSet, target string) *graph {
g := &graph{nil, make(map[string]*node)}
@ -201,6 +196,3 @@ func applyrules(rs *ruleSet, g *graph, target string, rulecnt []int) *node {
return u
}

5
mk.go
View file

@ -7,7 +7,6 @@ import (
"os"
)
// True if messages should be printed without fancy colors.
var nocolor bool = false
@ -28,7 +27,6 @@ const (
colorMagenta string = "\033[35m"
)
func mk(rs *ruleSet, target string, dryrun bool) {
g := buildgraph(rs, target)
//g.visualize(os.Stdout)
@ -57,7 +55,7 @@ func mkNode(g *graph, u *node) {
// when finished, notify the listeners
finalstatus := nodeStatusDone
defer func () {
defer func() {
u.mutex.Lock()
u.status = finalstatus
u.mutex.Unlock()
@ -177,7 +175,6 @@ func mkPrintRecipe(msg string) {
}
}
func main() {
var mkfilepath string
var dryrun bool

View file

@ -313,7 +313,7 @@ func parseRecipe(p *parser, t token) parserStateFun {
if idx > 0 {
left = regexp.QuoteMeta(targetstr[:idx])
}
if idx < len(targetstr) - 1 {
if idx < len(targetstr)-1 {
right = regexp.QuoteMeta(targetstr[idx+1:])
}

View file

@ -1,19 +1,17 @@
// Various function for dealing with recipes.
package main
import (
"bufio"
"fmt"
"io"
"log"
"os"
"os/exec"
"bufio"
"fmt"
"strings"
)
// Try to unindent a recipe, so that it begins an column 0. (This is mainly for
// recipes in python, or other indentation-significant languages.)
//func stripIndentation(s string) string {
@ -30,7 +28,7 @@ func printIndented(out io.Writer, s string) {
io.WriteString(out, line)
}
if (err != nil) {
if err != nil {
break
}
}
@ -43,7 +41,7 @@ func dorecipe(target string, u *node, e *edge) bool {
if e.r.ismeta {
if e.r.attributes.regex {
for i := range e.matches {
vars[fmt.Sprintf("stem%d", i)] = e.matches[i:i+1]
vars[fmt.Sprintf("stem%d", i)] = e.matches[i : i+1]
}
} else {
vars["stem"] = []string{e.stem}
@ -87,13 +85,11 @@ func dorecipe(target string, u *node, e *edge) bool {
true,
false)
// TODO: update the timestamps of each target
return success
}
// A monolithic function for executing subprocesses
func subprocess(program string,
args []string,

View file

@ -6,9 +6,9 @@ package main
import (
"fmt"
"unicode/utf8"
"regexp"
"sync"
"unicode/utf8"
)
type attribSet struct {
@ -27,7 +27,6 @@ type attribError struct {
found rune
}
// target and rereq patterns
type pattern struct {
issuffix bool // is a suffix '%' rule, so we should define $stem.
@ -35,7 +34,6 @@ type pattern struct {
rpat *regexp.Regexp // non-nil if this is a regexp pattern
}
// Match a pattern, returning an array of submatches, or nil if it doesn'm
// match.
func (p *pattern) match(target string) []string {
@ -50,7 +48,6 @@ func (p *pattern) match(target string) []string {
return nil
}
// A single rule.
type rule struct {
targets []pattern // non-empty array of targets
@ -63,7 +60,6 @@ type rule struct {
mutex sync.Mutex // prevent the rule from being executed multiple times
}
// A set of rules.
type ruleSet struct {
vars map[string][]string
@ -72,7 +68,6 @@ type ruleSet struct {
targetrules map[string][]int
}
// Read attributes for an array of strings, updating the rule.
func (r *rule) parseAttribs(inputs []string) *attribError {
for i := 0; i < len(inputs); i++ {
@ -134,7 +129,6 @@ func (rs *ruleSet) add(r rule) {
}
}
func isValidVarName(v string) bool {
for i := 0; i < len(v); {
c, w := utf8.DecodeRuneInString(v[i:])
@ -152,7 +146,6 @@ func isdigit(c rune) bool {
return '0' <= c && c <= '9'
}
func isalpha(c rune) bool {
return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
}
@ -175,14 +168,12 @@ func (rs *ruleSet) executeAssignment(ts []token) *assignmentError {
ts[0]}
}
// expanded variables
vals := make([]string, 0)
for i := 1; i < len(ts); i++ {
vals = append(vals, expand(ts[i].val, rs.vars, true)...)
}
rs.vars[assignee] = vals
return nil
}