diff --git a/vendor/github.com/mvdan/sh/interp/arith.go b/vendor/github.com/mvdan/sh/interp/arith.go index 36c1d127..ba07b678 100644 --- a/vendor/github.com/mvdan/sh/interp/arith.go +++ b/vendor/github.com/mvdan/sh/interp/arith.go @@ -11,8 +11,8 @@ import ( func (r *Runner) arithm(expr syntax.ArithmExpr) int { switch x := expr.(type) { - case *syntax.Word: - str := r.loneWord(x) + case *syntax.Lit: + str := x.Value // recursively fetch vars for { val := r.getVar(str) @@ -23,12 +23,14 @@ func (r *Runner) arithm(expr syntax.ArithmExpr) int { } // default to 0 return atoi(str) + case *syntax.ParamExp: + return atoi(r.paramExp(x)) case *syntax.ParenArithm: return r.arithm(x.X) case *syntax.UnaryArithm: switch x.Op { case syntax.Inc, syntax.Dec: - name := x.X.(*syntax.Word).Parts[0].(*syntax.Lit).Value + name := x.X.(*syntax.Lit).Value old := atoi(r.getVar(name)) val := old if x.Op == syntax.Inc { @@ -81,7 +83,7 @@ func atoi(s string) int { } func (r *Runner) assgnArit(b *syntax.BinaryArithm) int { - name := b.X.(*syntax.Word).Parts[0].(*syntax.Lit).Value + name := b.X.(*syntax.Lit).Value val := atoi(r.getVar(name)) arg := r.arithm(b.Y) switch b.Op { @@ -105,7 +107,7 @@ func (r *Runner) assgnArit(b *syntax.BinaryArithm) int { val ^= arg case syntax.ShlAssgn: val <<= uint(arg) - default: // syntax.ShrAssgn + case syntax.ShrAssgn: val >>= uint(arg) } r.setVar(name, strconv.Itoa(val)) diff --git a/vendor/github.com/mvdan/sh/interp/builtin.go b/vendor/github.com/mvdan/sh/interp/builtin.go index 1fa235b5..b195a988 100644 --- a/vendor/github.com/mvdan/sh/interp/builtin.go +++ b/vendor/github.com/mvdan/sh/interp/builtin.go @@ -5,13 +5,26 @@ package interp import ( "os" + "os/exec" "path/filepath" "strconv" "github.com/mvdan/sh/syntax" ) -func (r *Runner) builtin(pos syntax.Pos, name string, args []string) bool { +func isBuiltin(name string) bool { + switch name { + case "true", ":", "false", "exit", "set", "shift", "unset", + "echo", "printf", "break", "continue", "pwd", "cd", + "wait", "builtin", "trap", "type", "source", "command", + "pushd", "popd", "umask", "alias", "unalias", "fg", "bg", + "getopts": + return true + } + return false +} + +func (r *Runner) builtin(pos syntax.Pos, name string, args []string) { exit := 0 switch name { case "true", ":": @@ -46,6 +59,7 @@ func (r *Runner) builtin(pos syntax.Pos, name string, args []string) bool { default: r.errf("usage: shift [n]\n") exit = 2 + break } if len(r.args) < n { n = len(r.args) @@ -160,20 +174,28 @@ func (r *Runner) builtin(pos syntax.Pos, name string, args []string) bool { if len(args) < 1 { break } - // TODO: pos - if !r.builtin(0, args[0], args[1:]) { + if !isBuiltin(args[0]) { exit = 1 + break } - case "trap", "type", "source", "command", "pushd", "popd", + // TODO: pos + r.builtin(0, args[0], args[1:]) + case "type": + for _, arg := range args { + if isBuiltin(arg) { + r.outf("%s is a shell builtin\n", arg) + continue + } + if path, err := exec.LookPath(arg); err == nil { + r.outf("%s is %s\n", arg, path) + continue + } + exit = 1 + r.errf("type: %s: not found\n", arg) + } + case "trap", "source", "command", "pushd", "popd", "umask", "alias", "unalias", "fg", "bg", "getopts": r.errf("unhandled builtin: %s", name) - // TODO(mvdan): we rely on the binary versions of these, we - // should eventually implement them as builtins like Bash for - // portability - // case "[", "test": - default: - return false } r.exit = exit - return true } diff --git a/vendor/github.com/mvdan/sh/interp/interp.go b/vendor/github.com/mvdan/sh/interp/interp.go index d2472aa9..592d96fb 100644 --- a/vendor/github.com/mvdan/sh/interp/interp.go +++ b/vendor/github.com/mvdan/sh/interp/interp.go @@ -98,12 +98,10 @@ func (r *Runner) varInd(v varValue, e syntax.ArithmExpr) string { } case []string: // TODO: @ between double quotes - if w, ok := e.(*syntax.Word); ok { - if lit, ok := w.Parts[0].(*syntax.Lit); ok { - switch lit.Value { - case "@", "*": - return strings.Join(x, " ") - } + if lit, ok := e.(*syntax.Lit); ok { + switch lit.Value { + case "@", "*": + return strings.Join(x, " ") } } i := r.arithm(e) @@ -373,6 +371,7 @@ func (r *Runner) cmd(cm syntax.Command) { r.stmts(x.ThenStmts) return } + r.exit = 0 for _, el := range x.Elifs { r.stmts(el.CondStmts) if r.exit == 0 { @@ -381,9 +380,6 @@ func (r *Runner) cmd(cm syntax.Command) { } } r.stmts(x.ElseStmts) - if len(x.Elifs)+len(x.ElseStmts) == 0 { - r.exit = 0 - } case *syntax.WhileClause: for r.err == nil { r.stmts(x.CondStmts) @@ -559,10 +555,16 @@ func (r *Runner) wordParts(wps []syntax.WordPart, quoted bool) []string { curBuf.WriteString(field) } } - for _, wp := range wps { + for i, wp := range wps { switch x := wp.(type) { case *syntax.Lit: - curBuf.WriteString(x.Value) + s := x.Value + if i > 0 || len(s) == 0 || s[0] != '~' { + } else if len(s) < 2 || s[1] == '/' { + // TODO: ~someuser + s = r.getVar("HOME") + s[1:] + } + curBuf.WriteString(s) case *syntax.SglQuoted: curBuf.WriteString(x.Value) case *syntax.DblQuoted: @@ -619,7 +621,8 @@ func (r *Runner) call(pos syntax.Pos, name string, args []string) { r.args = oldArgs return } - if r.builtin(pos, name, args) { + if isBuiltin(name) { + r.builtin(pos, name, args) return } cmd := exec.CommandContext(r.Context, name, args...) diff --git a/vendor/github.com/mvdan/sh/interp/param.go b/vendor/github.com/mvdan/sh/interp/param.go index a15d1f23..9fe92bb1 100644 --- a/vendor/github.com/mvdan/sh/interp/param.go +++ b/vendor/github.com/mvdan/sh/interp/param.go @@ -40,7 +40,7 @@ func (r *Runner) paramExp(pe *syntax.ParamExp) string { switch { case pe.Length: str = strconv.Itoa(utf8.RuneCountInString(str)) - case pe.Excl: + case pe.Indirect: val, set = r.lookupVar(str) str = varStr(val) } @@ -141,7 +141,7 @@ func (r *Runner) paramExp(pe *syntax.ParamExp) string { str = string(rs) case syntax.LowerAll: str = strings.ToLower(str) - default: // syntax.OtherParamOps + case syntax.OtherParamOps: switch arg { case "Q": str = strconv.Quote(str) diff --git a/vendor/github.com/mvdan/sh/interp/test.go b/vendor/github.com/mvdan/sh/interp/test.go index 1d1fd403..ef7246e9 100644 --- a/vendor/github.com/mvdan/sh/interp/test.go +++ b/vendor/github.com/mvdan/sh/interp/test.go @@ -74,10 +74,10 @@ func (r *Runner) binTest(op syntax.BinTestOperator, x, y string) bool { return x != "" && y != "" case syntax.OrTest: return x != "" || y != "" - case syntax.TsEqual: + case syntax.TsMatch: m, _ := path.Match(y, x) return m - case syntax.TsNequal: + case syntax.TsNoMatch: m, _ := path.Match(y, x) return !m case syntax.TsBefore: diff --git a/vendor/github.com/mvdan/sh/syntax/canonical.sh b/vendor/github.com/mvdan/sh/syntax/canonical.sh index e0acfc32..e67bd5b7 100644 --- a/vendor/github.com/mvdan/sh/syntax/canonical.sh +++ b/vendor/github.com/mvdan/sh/syntax/canonical.sh @@ -25,9 +25,9 @@ case $foo in esac foo | bar -foo \ - && $(bar) \ - && (more) +foo && + $(bar) && + (more) foo 2>&1 foo < 0 { return p.word(parts) } @@ -514,7 +501,7 @@ func (p *parser) getWordOrEmpty() *Word { if len(parts) == 0 { l := p.lit(p.pos, "") l.ValueEnd = l.ValuePos // force Lit.Pos() == Lit.End() - return p.word(p.singleWps(l)) + return p.word(p.wps(l)) } return p.word(parts) } @@ -536,9 +523,10 @@ func (p *parser) wordParts() (wps []WordPart) { return } if wps == nil { - wps = p.wps() + wps = p.wps(n) + } else { + wps = append(wps, n) } - wps = append(wps, n) if p.spaced { return } @@ -607,11 +595,10 @@ func (p *parser) wordPart() WordPart { p.rune() p.tok, p.val = _LitWord, string(r) default: - if p.quote&allRegTokens != 0 { - p.advanceLitNone(r) - } else { - p.advanceLitOther(r) - } + old := p.quote + p.quote = paramName + p.advanceLitOther(r) + p.quote = old } pe.Param = p.getLit() return pe @@ -665,12 +652,7 @@ func (p *parser) wordPart() WordPart { old := p.quote p.quote = dblQuotes p.next() - if p.tok == _LitWord { - q.Parts = p.singleWps(p.lit(p.pos, p.val)) - p.next() - } else { - q.Parts = p.wordParts() - } + q.Parts = p.wordParts() p.quote = old if !p.got(dblQuote) { p.quoteErr(q.Pos(), dblQuote) @@ -803,7 +785,7 @@ func (p *parser) arithmExpr(ftok token, fpos Pos, level int, compact, tern bool) } case AddAssgn, SubAssgn, MulAssgn, QuoAssgn, RemAssgn, AndAssgn, OrAssgn, XorAssgn, ShlAssgn, ShrAssgn, Assgn: - if w, ok := b.X.(*Word); !ok || !p.wordIdent(w) { + if l, ok := b.X.(*Lit); !ok || !validIdent(l.Value, p.bash()) { p.posErr(b.OpPos, "%s must follow a name", b.Op.String()) } } @@ -822,14 +804,6 @@ func (p *parser) arithmExpr(ftok token, fpos Pos, level int, compact, tern bool) return b } -func (p *parser) wordIdent(w *Word) bool { - if len(w.Parts) != 1 { - return false - } - lit, ok := w.Parts[0].(*Lit) - return ok && validIdent(lit.Value, p.bash()) -} - func (p *parser) arithmExprBase(compact bool) ArithmExpr { var x ArithmExpr switch p.tok { @@ -843,7 +817,11 @@ func (p *parser) arithmExprBase(compact bool) ArithmExpr { case addAdd, subSub: ue := &UnaryArithm{OpPos: p.pos, Op: UnAritOperator(p.tok)} p.next() - ue.X = p.followWordTok(token(ue.Op), ue.OpPos) + if lit := p.getLit(); lit == nil { + p.followErr(ue.OpPos, token(ue.Op).String(), "a literal") + } else { + ue.X = lit + } return ue case leftParen: pe := &ParenArithm{Lparen: p.pos} @@ -864,23 +842,27 @@ func (p *parser) arithmExprBase(compact bool) ArithmExpr { p.followErrExp(ue.OpPos, ue.Op.String()) } x = ue + case illegalTok, rightBrack, rightBrace, rightParen: + case _LitWord: + x = p.getLit() + case dollar, dollBrace: + x = p.wordPart().(*ParamExp) case bckQuote: if p.quote == arithmExprLet { return nil } fallthrough default: - if w := p.getWord(); w != nil { - // we want real nil, not (*Word)(nil) as that - // sets the type to non-nil and then x != nil - x = w + if arithmOpLevel(BinAritOperator(p.tok)) >= 0 { + break } + p.curErr("arithmetic expressions must consist of names and numbers") } if compact && p.spaced { return x } if p.tok == addAdd || p.tok == subSub { - if w, ok := x.(*Word); !ok || !p.wordIdent(w) { + if l, ok := x.(*Lit); !ok || !validIdent(l.Value, p.bash()) { p.curErr("%s must follow a name", p.tok.String()) } u := &UnaryArithm{ @@ -914,7 +896,7 @@ func (p *parser) paramExp() *ParamExp { } case exclMark: if p.r != '}' { - pe.Excl = true + pe.Indirect = true p.next() } } @@ -1089,7 +1071,7 @@ func (p *parser) getAssign() *Assign { start := p.lit(p.pos+1, p.val[p.asPos+1:]) if start.Value != "" { start.ValuePos += Pos(p.asPos) - as.Value = p.word(p.singleWps(start)) + as.Value = p.word(p.wps(start)) } if p.next(); p.spaced { return as @@ -1108,7 +1090,7 @@ func (p *parser) getAssign() *Assign { } } ae.Rparen = p.matched(ae.Lparen, leftParen, rightParen) - as.Value = p.word(p.singleWps(ae)) + as.Value = p.word(p.wps(ae)) } else if !p.newLine && !stopToken(p.tok) { if w := p.getWord(); w != nil { if as.Value == nil { @@ -1227,55 +1209,66 @@ preLoop: return } -func bashDeclareWord(s string) bool { - switch s { - case "declare", "local", "export", "readonly", "typeset", "nameref": - return true - } - return false -} - func (p *parser) gotStmtPipe(s *Stmt) *Stmt { switch p.tok { - case leftParen: - s.Cmd = p.subshell() - case dblLeftParen: - s.Cmd = p.arithmExpCmd() case _LitWord: - switch { - case p.val == "}": - p.curErr("%s can only be used to close a block", p.val) - case p.val == "{": + switch p.val { + case "{": s.Cmd = p.block() - case p.val == "if": + case "if": s.Cmd = p.ifClause() - case p.val == "while": + case "while": s.Cmd = p.whileClause() - case p.val == "until": + case "until": s.Cmd = p.untilClause() - case p.val == "for": + case "for": s.Cmd = p.forClause() - case p.val == "case": + case "case": s.Cmd = p.caseClause() - case p.bash() && p.val == "[[": - s.Cmd = p.testClause() - case p.bash() && bashDeclareWord(p.val): - s.Cmd = p.declClause() - case p.bash() && p.val == "eval": - s.Cmd = p.evalClause() - case p.bash() && p.val == "coproc": - s.Cmd = p.coprocClause() - case p.bash() && p.val == "let": - s.Cmd = p.letClause() - case p.bash() && p.val == "function": - s.Cmd = p.bashFuncDecl() + case "}": + p.curErr(`%s can only be used to close a block`, p.val) + case "]]": + if !p.bash() { + break + } + p.curErr(`%s can only be used to close a test`, p.val) + case "then": + p.curErr(`%q can only be used in an if`, p.val) + case "elif": + p.curErr(`%q can only be used in an if`, p.val) + case "fi": + p.curErr(`%q can only be used to end an if`, p.val) + case "do": + p.curErr(`%q can only be used in a loop`, p.val) + case "done": + p.curErr(`%q can only be used to end a loop`, p.val) + case "esac": + p.curErr(`%q can only be used to end a case`, p.val) default: + if !p.bash() { + break + } + switch p.val { + case "[[": + s.Cmd = p.testClause() + case "declare", "local", "export", "readonly", + "typeset", "nameref": + s.Cmd = p.declClause() + case "coproc": + s.Cmd = p.coprocClause() + case "let": + s.Cmd = p.letClause() + case "function": + s.Cmd = p.bashFuncDecl() + } + } + if s.Cmd == nil { name := p.lit(p.pos, p.val) if p.next(); p.gotSameLine(leftParen) { p.follow(name.ValuePos, "foo(", rightParen) s.Cmd = p.funcDecl(name, name.ValuePos) } else { - s.Cmd = p.callExpr(s, p.word(p.singleWps(name))) + s.Cmd = p.callExpr(s, p.word(p.wps(name))) } } case bckQuote: @@ -1291,6 +1284,10 @@ func (p *parser) gotStmtPipe(s *Stmt) *Stmt { p.posErr(w.Pos(), "invalid func name") } s.Cmd = p.callExpr(s, w) + case leftParen: + s.Cmd = p.subshell() + case dblLeftParen: + s.Cmd = p.arithmExpCmd() } for !p.newLine && p.peekRedir() { p.doRedirect(s) @@ -1625,24 +1622,15 @@ func (p *parser) declClause() *DeclClause { return ds } -func (p *parser) evalClause() *EvalClause { - ec := &EvalClause{Eval: p.pos} - p.next() - ec.Stmt, _ = p.getStmt(false, false) - return ec -} - func isBashCompoundCommand(tok token, val string) bool { switch tok { case leftParen, dblLeftParen: return true case _LitWord: switch val { - case "{", "if", "while", "until", "for", "case", "[[", "eval", - "coproc", "let", "function": - return true - } - if bashDeclareWord(val) { + case "{", "if", "while", "until", "for", "case", "[[", + "coproc", "let", "function", "declare", "local", + "export", "readonly", "typeset", "nameref": return true } } @@ -1668,12 +1656,12 @@ func (p *parser) coprocClause() *CoprocClause { } // name was in fact the stmt cc.Stmt = p.stmt(cc.Name.ValuePos) - cc.Stmt.Cmd = p.call(p.word(p.singleWps(cc.Name))) + cc.Stmt.Cmd = p.call(p.word(p.wps(cc.Name))) cc.Name = nil } else if cc.Name != nil { if call, ok := cc.Stmt.Cmd.(*CallExpr); ok { // name was in fact the start of a call - call.Args = append([]*Word{p.word(p.singleWps(cc.Name))}, + call.Args = append([]*Word{p.word(p.wps(cc.Name))}, call.Args...) cc.Name = nil } @@ -1726,7 +1714,7 @@ func (p *parser) callExpr(s *Stmt, w *Word) *CallExpr { return ce case _LitWord: ce.Args = append(ce.Args, p.word( - p.singleWps(p.lit(p.pos, p.val)), + p.wps(p.lit(p.pos, p.val)), )) p.next() case bckQuote: diff --git a/vendor/github.com/mvdan/sh/syntax/printer.go b/vendor/github.com/mvdan/sh/syntax/printer.go index dac6242f..3b214ea9 100644 --- a/vendor/github.com/mvdan/sh/syntax/printer.go +++ b/vendor/github.com/mvdan/sh/syntax/printer.go @@ -11,7 +11,14 @@ import ( // PrintConfig controls how the printing of an AST node will behave. type PrintConfig struct { - Spaces int // 0 (default) for tabs, >0 for number of spaces + // Spaces dictates the indentation style. The default value of 0 + // uses tabs, and any positive value uses that number of spaces. + Spaces int + // BinaryNextLine makes binary operators (such as &&, || and |) + // be at the start of a line if the statement that follows them + // is on a separate line. This means that the operator will come + // after an escaped newline. + BinaryNextLine bool } var printerFree = sync.Pool{ @@ -310,52 +317,7 @@ func (p *printer) wordPart(wp WordPart) { p.nestedStmts(x.Stmts, x.Right) p.sepTok(")", x.Right) case *ParamExp: - if x.Short { - p.WriteByte('$') - p.WriteString(x.Param.Value) - break - } - p.WriteString("${") - switch { - case x.Length: - p.WriteByte('#') - case x.Excl: - p.WriteByte('!') - } - if x.Param != nil { - p.WriteString(x.Param.Value) - } - if x.Ind != nil { - p.WriteByte('[') - p.arithmExpr(x.Ind.Expr, false) - p.WriteByte(']') - } - if x.Slice != nil { - p.WriteByte(':') - if un, ok := x.Slice.Offset.(*UnaryArithm); ok { - if un.Op == Plus || un.Op == Minus { - // to avoid :+ and :- - p.WriteByte(' ') - } - } - p.arithmExpr(x.Slice.Offset, true) - if x.Slice.Length != nil { - p.WriteByte(':') - p.arithmExpr(x.Slice.Length, true) - } - } else if x.Repl != nil { - if x.Repl.All { - p.WriteByte('/') - } - p.WriteByte('/') - p.word(x.Repl.Orig) - p.WriteByte('/') - p.word(x.Repl.With) - } else if x.Exp != nil { - p.WriteString(x.Exp.Op.String()) - p.word(x.Exp.Word) - } - p.WriteByte('}') + p.paramExp(x) case *ArithmExp: p.WriteString("$((") p.arithmExpr(x.X, false) @@ -381,6 +343,55 @@ func (p *printer) wordPart(wp WordPart) { } } +func (p *printer) paramExp(pe *ParamExp) { + if pe.Short { + p.WriteByte('$') + p.WriteString(pe.Param.Value) + return + } + p.WriteString("${") + switch { + case pe.Length: + p.WriteByte('#') + case pe.Indirect: + p.WriteByte('!') + } + if pe.Param != nil { + p.WriteString(pe.Param.Value) + } + if pe.Ind != nil { + p.WriteByte('[') + p.arithmExpr(pe.Ind.Expr, false) + p.WriteByte(']') + } + if pe.Slice != nil { + p.WriteByte(':') + if un, ok := pe.Slice.Offset.(*UnaryArithm); ok { + if un.Op == Plus || un.Op == Minus { + // to avoid :+ and :- + p.WriteByte(' ') + } + } + p.arithmExpr(pe.Slice.Offset, true) + if pe.Slice.Length != nil { + p.WriteByte(':') + p.arithmExpr(pe.Slice.Length, true) + } + } else if pe.Repl != nil { + if pe.Repl.All { + p.WriteByte('/') + } + p.WriteByte('/') + p.word(pe.Repl.Orig) + p.WriteByte('/') + p.word(pe.Repl.With) + } else if pe.Exp != nil { + p.WriteString(pe.Exp.Op.String()) + p.word(pe.Exp.Word) + } + p.WriteByte('}') +} + func (p *printer) loop(loop Loop) { switch x := loop.(type) { case *WordIter: @@ -405,8 +416,10 @@ func (p *printer) loop(loop Loop) { func (p *printer) arithmExpr(expr ArithmExpr, compact bool) { switch x := expr.(type) { - case *Word: - p.word(x) + case *Lit: + p.WriteString(x.Value) + case *ParamExp: + p.paramExp(x) case *BinaryArithm: if compact { p.arithmExpr(x.X, compact) @@ -636,19 +649,28 @@ func (p *printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { p.incLevel() } _, p.nestedBinary = x.Y.Cmd.(*BinaryCmd) - if len(p.pendingHdocs) == 0 && x.Y.Pos() > p.nline { - p.bslashNewl() - p.indent() - } - p.spacedString(x.Op.String()) - if p.anyCommentsBefore(x.Y.Pos()) { - p.wantSpace = false - p.WriteByte('\n') - p.indent() - p.incLines(p.comments[0].Pos()) - p.commentsUpTo(x.Y.Pos()) - p.WriteByte('\n') - p.indent() + if p.BinaryNextLine { + if len(p.pendingHdocs) == 0 && x.Y.Pos() > p.nline { + p.bslashNewl() + p.indent() + } + p.spacedString(x.Op.String()) + if p.anyCommentsBefore(x.Y.Pos()) { + p.wantSpace = false + p.WriteByte('\n') + p.indent() + p.incLines(p.comments[0].Pos()) + p.commentsUpTo(x.Y.Pos()) + p.WriteByte('\n') + p.indent() + } + } else { + p.spacedString(x.Op.String()) + if x.Y.Pos() > p.nline { + p.commentsUpTo(x.Y.Pos()) + p.newline(0) + p.indent() + } } p.incLines(x.Y.Pos()) p.stmt(x.Y) @@ -723,11 +745,6 @@ func (p *printer) command(cmd Command, redirs []*Redirect) (startRedirs int) { p.word(w) } p.assigns(x.Assigns) - case *EvalClause: - p.spacedString("eval") - if x.Stmt != nil { - p.stmt(x.Stmt) - } case *CoprocClause: p.spacedString("coproc") if x.Name != nil { diff --git a/vendor/github.com/mvdan/sh/syntax/tokens.go b/vendor/github.com/mvdan/sh/syntax/tokens.go index 26bf6a82..7bed2e02 100644 --- a/vendor/github.com/mvdan/sh/syntax/tokens.go +++ b/vendor/github.com/mvdan/sh/syntax/tokens.go @@ -316,16 +316,12 @@ const ( TsGeq TsLss TsGtr - AndTest = BinTestOperator(andAnd) - OrTest = BinTestOperator(orOr) - // TODO(mvdan): == and != are pattern matches; use more - // appropriate names like TsMatch and TsNoMatch in 2.0 - TsEqual = BinTestOperator(equal) - TsNequal = BinTestOperator(nequal) - TsBefore = BinTestOperator(rdrIn) - TsAfter = BinTestOperator(rdrOut) - // Deprecated: now parses as TsEqual - TsAssgn = BinTestOperator(assgn) // TODO(mvdan): remove in 2.0 + AndTest = BinTestOperator(andAnd) + OrTest = BinTestOperator(orOr) + TsMatch = BinTestOperator(equal) + TsNoMatch = BinTestOperator(nequal) + TsBefore = BinTestOperator(rdrIn) + TsAfter = BinTestOperator(rdrOut) ) func (o RedirOperator) String() string { return token(o).String() } diff --git a/vendor/github.com/mvdan/sh/syntax/walk.go b/vendor/github.com/mvdan/sh/syntax/walk.go index f2b6d3fd..f6c7ecfd 100644 --- a/vendor/github.com/mvdan/sh/syntax/walk.go +++ b/vendor/github.com/mvdan/sh/syntax/walk.go @@ -163,10 +163,6 @@ func Walk(node Node, f func(Node) bool) { Walk(x.Pattern, f) case *ProcSubst: walkStmts(x.Stmts, f) - case *EvalClause: - if x.Stmt != nil { - Walk(x.Stmt, f) - } case *CoprocClause: if x.Name != nil { Walk(x.Name, f) diff --git a/vendor/vendor.json b/vendor/vendor.json index 6329c833..84e43985 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -51,16 +51,16 @@ "revisionTime": "2017-01-24T11:57:57Z" }, { - "checksumSHA1": "1ZLAvHVYAS3kxaYI8OQiTBllqNU=", + "checksumSHA1": "ZjfvXVu+OyeRBysQ8uowAkPD/6o=", "path": "github.com/mvdan/sh/interp", - "revision": "17e267b541e30baece16b7ddeae50822cc6a795f", - "revisionTime": "2017-04-24T11:31:08Z" + "revision": "faf782d3a498f50cfc6aa9071d04e6f1e82e8035", + "revisionTime": "2017-04-30T14:10:52Z" }, { - "checksumSHA1": "4/7joITdf4wl+uoV8zDXgYqy2aw=", + "checksumSHA1": "RIR7FOsCR78SmOJOUsclJe9lvxo=", "path": "github.com/mvdan/sh/syntax", - "revision": "17e267b541e30baece16b7ddeae50822cc6a795f", - "revisionTime": "2017-04-24T11:31:08Z" + "revision": "faf782d3a498f50cfc6aa9071d04e6f1e82e8035", + "revisionTime": "2017-04-30T14:10:52Z" }, { "checksumSHA1": "HUXE+Nrcau8FSaVEvPYHMvDjxOE=",