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. // String substitution and expansion.
package main package main
@ -8,7 +7,6 @@ import (
"unicode/utf8" "unicode/utf8"
) )
// Expand a word. This includes substituting variables and handling quotes. // Expand a word. This includes substituting variables and handling quotes.
func expand(input string, vars map[string][]string, expandBackticks bool) []string { func expand(input string, vars map[string][]string, expandBackticks bool) []string {
parts := make([]string, 0) parts := make([]string, 0)
@ -167,7 +165,6 @@ func expandSigil(input string, vars map[string][]string) ([]string, int) {
return []string{"$" + input}, len(input) return []string{"$" + input}, len(input)
} }
// Find and expand all sigils. // Find and expand all sigils.
func expandSigils(input string, vars map[string][]string) []string { func expandSigils(input string, vars map[string][]string) []string {
parts := make([]string, 0) parts := make([]string, 0)
@ -195,7 +192,6 @@ func expandSigils(input string, vars map[string][]string) []string {
return parts return parts
} }
// Find and expand all sigils in a recipe, producing a flat string. // Find and expand all sigils in a recipe, producing a flat string.
func expandRecipeSigils(input string, vars map[string][]string) string { func expandRecipeSigils(input string, vars map[string][]string) string {
expanded := "" expanded := ""
@ -229,7 +225,6 @@ func expandRecipeSigils(input string, vars map[string][]string) string {
return expanded return expanded
} }
// Expand all unescaped '%' characters. // Expand all unescaped '%' characters.
func expandSuffixes(input string, stem string) string { func expandSuffixes(input string, stem string) string {
expanded := make([]byte, 0) expanded := make([]byte, 0)
@ -257,10 +252,8 @@ func expandSuffixes(input string, stem string) string {
return string(expanded) return string(expanded)
} }
// TODO: expand RegexpRefs // TODO: expand RegexpRefs
// Expand a backtick quoted string, by executing the contents. // Expand a backtick quoted string, by executing the contents.
func expandBackQuoted(input string, vars map[string][]string) (string, int) { func expandBackQuoted(input string, vars map[string][]string) (string, int) {
// TODO: expand sigils? // TODO: expand sigils?
@ -274,40 +267,34 @@ func expandBackQuoted(input string, vars map[string][]string) (string, int) {
return output, (j + 1) return output, (j + 1)
} }
// Split a string on whitespace taking into account escaping and quoting. // Split a string on whitespace taking into account escaping and quoting.
//func splitQuoted(input string) []string { //func splitQuoted(input string) []string {
//parts := make([]string, 0) //parts := make([]string, 0)
//var i, j int //var i, j int
//i = 0 //i = 0
//for { //for {
//// skip all unescaped whitespace //// skip all unescaped whitespace
//for i < len(input) { //for i < len(input) {
//c, w := utf8.DecodeRuneInString(input[i:]) //c, w := utf8.DecodeRuneInString(input[i:])
//if strings.IndexRune(" \t", c) < 0 { //if strings.IndexRune(" \t", c) < 0 {
//break //break
//} //}
//i += w //i += w
//}
//if i >= len(input) {
//break
//}
//// Ugh. Will this take into account quoting in variables?
//switch c {
//case '"':
//case '\'':
//default:
//}
//}
//return parts
//} //}
//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 package main
import ( import (
@ -23,7 +22,6 @@ type edge struct {
r *rule r *rule
} }
// Current status of a node in the build. // Current status of a node in the build.
type nodeStatus int type nodeStatus int
@ -34,7 +32,6 @@ const (
nodeStatusFailed nodeStatusFailed
) )
// A node in the dependency graph // A node in the dependency graph
type node struct { type node struct {
r *rule // rule to be applied r *rule // rule to be applied
@ -80,7 +77,6 @@ func (g *graph) visualize(w io.Writer) {
fmt.Fprintln(w, "}") fmt.Fprintln(w, "}")
} }
// Create a new arc. // Create a new arc.
func (u *node) newedge(v *node, r *rule) *edge { func (u *node) newedge(v *node, r *rule) *edge {
e := &edge{v: v, r: r} e := &edge{v: v, r: r}
@ -88,7 +84,6 @@ func (u *node) newedge(v *node, r *rule) *edge {
return e return e
} }
// Create a dependency graph for the given target. // Create a dependency graph for the given target.
func buildgraph(rs *ruleSet, target string) *graph { func buildgraph(rs *ruleSet, target string) *graph {
g := &graph{nil, make(map[string]*node)} g := &graph{nil, make(map[string]*node)}
@ -201,6 +196,3 @@ func applyrules(rs *ruleSet, g *graph, target string, rulecnt []int) *node {
return u return u
} }

5
mk.go
View file

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

View file

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

View file

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

View file

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