From 0160f5dd30670740f2ef9295e9733175be8fc655 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Thu, 7 Sep 2017 14:02:52 -0300 Subject: [PATCH] update deps fixes #67 fixed upstream on mvdan/sh#159 --- Gopkg.lock | 4 +- vendor/github.com/Masterminds/sprig/date.go | 18 ++ vendor/github.com/Masterminds/sprig/dict.go | 10 +- vendor/github.com/Masterminds/sprig/doc.go | 5 + .../github.com/Masterminds/sprig/functions.go | 12 +- .../github.com/Masterminds/sprig/strings.go | 4 + vendor/mvdan.cc/sh/README.md | 4 +- vendor/mvdan.cc/sh/interp/interp.go | 15 ++ vendor/mvdan.cc/sh/syntax/lexer.go | 24 ++- vendor/mvdan.cc/sh/syntax/parser.go | 171 ++++++++++++------ vendor/mvdan.cc/sh/syntax/token_string.go | 4 +- vendor/mvdan.cc/sh/syntax/tokens.go | 1 + 12 files changed, 188 insertions(+), 84 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 302e97fa..2f1a54dd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -11,7 +11,7 @@ branch = "master" name = "github.com/Masterminds/sprig" packages = ["."] - revision = "e039e20e500c2c025d9145be375e27cf42a94174" + revision = "175e437013029f9a1c35bdf04bc451b0d20d4331" [[projects]] name = "github.com/aokoli/goutils" @@ -101,7 +101,7 @@ branch = "master" name = "mvdan.cc/sh" packages = ["interp","syntax"] - revision = "eaf7b83013b7a3dbfe3c627d00e1b9971afc9748" + revision = "d8d2c36c06455d4bb8e2116cc2b955271046329d" [solve-meta] analyzer-name = "dep" diff --git a/vendor/github.com/Masterminds/sprig/date.go b/vendor/github.com/Masterminds/sprig/date.go index dc5263f2..e72a66bd 100644 --- a/vendor/github.com/Masterminds/sprig/date.go +++ b/vendor/github.com/Masterminds/sprig/date.go @@ -51,3 +51,21 @@ func dateModify(fmt string, date time.Time) time.Time { } return date.Add(d) } + +func dateAgo(date interface{}) string { + var t time.Time + + switch date := date.(type) { + default: + t = time.Now() + case time.Time: + t = date + case int64: + t = time.Unix(date, 0) + case int: + t = time.Unix(int64(date), 0) + } + // Drop resolution to seconds + duration := time.Since(t) / time.Second * time.Second + return duration.String() +} diff --git a/vendor/github.com/Masterminds/sprig/dict.go b/vendor/github.com/Masterminds/sprig/dict.go index 46692d15..fabc736b 100644 --- a/vendor/github.com/Masterminds/sprig/dict.go +++ b/vendor/github.com/Masterminds/sprig/dict.go @@ -75,10 +75,12 @@ func dict(v ...interface{}) map[string]interface{} { return dict } -func merge(dst map[string]interface{}, src map[string]interface{}) interface{} { - if err := mergo.Merge(&dst, src); err != nil { - // Swallow errors inside of a template. - return "" +func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} { + for _, src := range srcs { + if err := mergo.Merge(&dst, src); err != nil { + // Swallow errors inside of a template. + return "" + } } return dst } diff --git a/vendor/github.com/Masterminds/sprig/doc.go b/vendor/github.com/Masterminds/sprig/doc.go index 0eac8e27..7b7eefd4 100644 --- a/vendor/github.com/Masterminds/sprig/doc.go +++ b/vendor/github.com/Masterminds/sprig/doc.go @@ -48,6 +48,10 @@ String Functions - randAlpha: Given a length, generate an alphabetic string - randAscii: Given a length, generate a random ASCII string (symbols included) - randNumeric: Given a length, generate a string of digits. + - swapcase: SwapCase swaps the case of a string using a word based algorithm. see https://godoc.org/github.com/Masterminds/goutils#SwapCase + - shuffle: Shuffle randomizes runes in a string and returns the result. It uses default random source in `math/rand` + - snakecase: convert all upper case characters in a string to underscore format. + - camelcase: convert all lower case characters behind underscores to upper case character - wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"` - wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "
", $html` - contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines) @@ -57,6 +61,7 @@ String Functions - squote: Wrap string(s) in double quotation marks, does not escape content. - cat: Concatenate strings, separating them by spaces. `cat $a $b $c`. - indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar" + - nindent: Indent a string using space characters and prepend a new line. `indent 4 "foo\nbar"` produces "\n foo\n bar" - replace: Replace an old with a new in a string: `$name | replace " " "-"` - plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"` - sha256sum: Generate a hex encoded sha256 hash of the input diff --git a/vendor/github.com/Masterminds/sprig/functions.go b/vendor/github.com/Masterminds/sprig/functions.go index c20175b2..c15522c0 100644 --- a/vendor/github.com/Masterminds/sprig/functions.go +++ b/vendor/github.com/Masterminds/sprig/functions.go @@ -98,6 +98,7 @@ var genericMap = map[string]interface{}{ "htmlDateInZone": htmlDateInZone, "dateInZone": dateInZone, "dateModify": dateModify, + "ago": dateAgo, // Strings "abbrev": abbrev, @@ -137,6 +138,7 @@ var genericMap = map[string]interface{}{ "squote": squote, "cat": cat, "indent": indent, + "nindent": nindent, "replace": replace, "plural": plural, "sha256sum": sha256sum, @@ -263,10 +265,10 @@ var genericMap = map[string]interface{}{ "fail": func(msg string) (string, error) { return "", errors.New(msg) }, // Regex - "regexMatch": regexMatch, - "regexFindAll": regexFindAll, - "regexFind": regexFind, - "regexReplaceAll": regexReplaceAll, + "regexMatch": regexMatch, + "regexFindAll": regexFindAll, + "regexFind": regexFind, + "regexReplaceAll": regexReplaceAll, "regexReplaceAllLiteral": regexReplaceAllLiteral, - "regexSplit": regexSplit, + "regexSplit": regexSplit, } diff --git a/vendor/github.com/Masterminds/sprig/strings.go b/vendor/github.com/Masterminds/sprig/strings.go index 69bcd985..f6afa2ff 100644 --- a/vendor/github.com/Masterminds/sprig/strings.go +++ b/vendor/github.com/Masterminds/sprig/strings.go @@ -106,6 +106,10 @@ func indent(spaces int, v string) string { return pad + strings.Replace(v, "\n", "\n"+pad, -1) } +func nindent(spaces int, v string) string { + return "\n" + indent(spaces, v) +} + func replace(old, new, src string) string { return strings.Replace(src, old, new, -1) } diff --git a/vendor/mvdan.cc/sh/README.md b/vendor/mvdan.cc/sh/README.md index a10da368..e142be94 100644 --- a/vendor/mvdan.cc/sh/README.md +++ b/vendor/mvdan.cc/sh/README.md @@ -51,8 +51,8 @@ validity: go get -u mvdan.cc/sh/cmd/gosh -Experimental non-interactive shell that uses `interp`. Work in progress, -so don't expect stability just yet. +Experimental shell that uses `interp`. Work in progress, so don't expect +stability just yet. ### Fuzzing diff --git a/vendor/mvdan.cc/sh/interp/interp.go b/vendor/mvdan.cc/sh/interp/interp.go index 7d7684fe..84849069 100644 --- a/vendor/mvdan.cc/sh/interp/interp.go +++ b/vendor/mvdan.cc/sh/interp/interp.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "io" + "math" "os" "os/exec" "os/user" @@ -17,6 +18,7 @@ import ( "strings" "sync" "syscall" + "time" "mvdan.cc/sh/syntax" ) @@ -645,6 +647,19 @@ func (r *Runner) cmd(cm syntax.Command) { for _, as := range x.Assigns { r.setVar(as.Name.Value, r.assignValue(as)) } + case *syntax.TimeClause: + start := time.Now() + if x.Stmt != nil { + r.stmt(x.Stmt) + } + elapsed := time.Since(start) + r.outf("\n") + min := int(elapsed.Minutes()) + sec := math.Remainder(elapsed.Seconds(), 60.0) + r.outf("real\t%dm%.3fs\n", min, sec) + // TODO: can we do these? + r.outf("user\t0m0.000s\n") + r.outf("sys\t0m0.000s\n") default: r.runErr(cm.Pos(), "unhandled command node: %T", x) } diff --git a/vendor/mvdan.cc/sh/syntax/lexer.go b/vendor/mvdan.cc/sh/syntax/lexer.go index 22784314..02f652f9 100644 --- a/vendor/mvdan.cc/sh/syntax/lexer.go +++ b/vendor/mvdan.cc/sh/syntax/lexer.go @@ -157,7 +157,7 @@ func (p *Parser) nextKeepSpaces() { if r == '`' || r == '$' { p.tok = p.dqToken(r) } else if p.hdocStop == nil { - p.tok = illegalTok + p.tok = _Newl } else { p.advanceLitHdoc(r) } @@ -186,7 +186,7 @@ func (p *Parser) next() { p.tok = _EOF return } - p.spaced, p.newLine = false, false + p.spaced = false if p.quote&allKeepSpaces != 0 { p.nextKeepSpaces() return @@ -202,18 +202,16 @@ skipSpace: p.spaced = true r = p.rune() case '\n': - if p.quote == arithmExprLet || p.quote == hdocWord { - p.tok = illegalTok - return + if p.tok == _Newl { + r = p.rune() + continue } - p.spaced, p.newLine = true, true - r = p.rune() - if len(p.heredocs) > p.buriedHdocs { - if p.doHeredocs(); p.tok == _EOF { - return - } - r = p.r + p.spaced = true + p.tok = _Newl + if p.quote != hdocWord && len(p.heredocs) > p.buriedHdocs { + p.doHeredocs() } + return case '\\': if !p.peekByte('\n') { break skipSpace @@ -899,7 +897,7 @@ func (p *Parser) advanceLitHdoc(r rune) { if bytes.HasPrefix(p.litBs[lStart:], p.hdocStop) { p.val = p.endLit()[:lStart] if p.val == "" { - p.tok = illegalTok + p.tok = _Newl } p.hdocStop = nil return diff --git a/vendor/mvdan.cc/sh/syntax/parser.go b/vendor/mvdan.cc/sh/syntax/parser.go index 8035c1c4..26ce8c30 100644 --- a/vendor/mvdan.cc/sh/syntax/parser.go +++ b/vendor/mvdan.cc/sh/syntax/parser.go @@ -50,7 +50,7 @@ func (p *Parser) Parse(r io.Reader, name string) (*File, error) { p.src = r p.rune() p.next() - p.f.StmtList = p.stmts() + p.f.StmtList = p.stmtList() if p.err == nil { // EOF immediately after heredoc word so no newline to // trigger it @@ -59,6 +59,21 @@ func (p *Parser) Parse(r io.Reader, name string) (*File, error) { return p.f, p.err } +func (p *Parser) Stmts(r io.Reader, fn func(*Stmt)) error { + p.reset() + p.f = &File{} + p.src = r + p.rune() + p.next() + p.stmts(fn) + if p.err == nil { + // EOF immediately after heredoc word so no newline to + // trigger it + p.doHeredocs() + } + return p.err +} + // Parser holds the internal state of the parsing mechanism of a // program. type Parser struct { @@ -70,8 +85,7 @@ type Parser struct { f *File - spaced bool // whether tok has whitespace on its left - newLine bool // whether tok is on a new line + spaced bool // whether tok has whitespace on its left err error // lexer/parser error readErr error // got a read error, but bytes left @@ -291,6 +305,7 @@ func (p *Parser) unquotedWordPart(buf *bytes.Buffer, wp WordPart, quotes bool) ( } func (p *Parser) doHeredocs() { + p.rune() // consume '\n', since we know p.tok == _Newl old := p.quote hdocs := p.heredocs[p.buriedHdocs:] p.heredocs = p.heredocs[:p.buriedHdocs] @@ -322,6 +337,9 @@ func (p *Parser) doHeredocs() { } func (p *Parser) got(tok token) bool { + if p.tok == _Newl { + p.next() + } if p.tok == tok { p.next() return true @@ -329,16 +347,20 @@ func (p *Parser) got(tok token) bool { return false } -func (p *Parser) gotRsrv(val string) bool { +func (p *Parser) gotRsrv(val string) (Pos, bool) { + if p.tok == _Newl { + p.next() + } + pos := p.pos if p.tok == _LitWord && p.val == val { p.next() - return true + return pos, true } - return false + return pos, false } func (p *Parser) gotSameLine(tok token) bool { - if !p.newLine && p.tok == tok { + if p.tok == tok { p.next() return true } @@ -369,8 +391,8 @@ func (p *Parser) follow(lpos Pos, left string, tok token) { } func (p *Parser) followRsrv(lpos Pos, left, val string) Pos { - pos := p.pos - if !p.gotRsrv(val) { + pos, ok := p.gotRsrv(val) + if !ok { p.followErr(lpos, left, fmt.Sprintf("%q", val)) } return pos @@ -380,8 +402,13 @@ func (p *Parser) followStmts(left string, lpos Pos, stops ...string) StmtList { if p.gotSameLine(semicolon) { return StmtList{} } - sl := p.stmts(stops...) - if len(sl.Stmts) < 1 && !p.newLine { + newLine := false + if p.tok == _Newl { + p.next() + newLine = true + } + sl := p.stmtList(stops...) + if len(sl.Stmts) < 1 && !newLine { p.followErr(lpos, left, "a statement list") } return sl @@ -404,8 +431,8 @@ func (p *Parser) followWord(s string, pos Pos) *Word { } func (p *Parser) stmtEnd(n Node, start, end string) Pos { - pos := p.pos - if !p.gotRsrv(end) { + pos, ok := p.gotRsrv(end) + if !ok { p.posErr(n.Pos(), "%s statement must end with %q", start, end) } return pos @@ -464,10 +491,15 @@ func (p *Parser) curErr(format string, a ...interface{}) { p.posErr(p.pos, format, a...) } -func (p *Parser) stmts(stops ...string) (sl StmtList) { +func (p *Parser) stmts(fn func(*Stmt), stops ...string) { gotEnd := true loop: for p.tok != _EOF { + newLine := false + if p.tok == _Newl { + newLine = true + p.next() + } switch p.tok { case _LitWord: for _, stop := range stops { @@ -489,7 +521,7 @@ loop: } p.curErr("%s can only be used in a case clause", p.tok) } - if !p.newLine && !gotEnd { + if !newLine && !gotEnd { p.curErr("statements must be separated by &, ; or a newline") } if p.tok == _EOF { @@ -498,13 +530,20 @@ loop: if s, end := p.getStmt(true, false); s == nil { p.invalidStmtStart() } else { - if sl.Stmts == nil { - sl.Stmts = p.stList() - } - sl.Stmts = append(sl.Stmts, s) + fn(s) gotEnd = end } } +} + +func (p *Parser) stmtList(stops ...string) (sl StmtList) { + fn := func(s *Stmt) { + if sl.Stmts == nil { + sl.Stmts = p.stList() + } + sl.Stmts = append(sl.Stmts, s) + } + p.stmts(fn, stops...) sl.Last, p.accComs = p.accComs, nil return } @@ -586,12 +625,13 @@ func (p *Parser) wordPart() WordPart { old := p.preNested(subCmd) p.rune() // don't tokenize '|' p.next() - cs.StmtList = p.stmts("}") + cs.StmtList = p.stmtList("}") p.postNested(old) - cs.Right = p.pos - if !p.gotRsrv("}") { + pos, ok := p.gotRsrv("}") + if !ok { p.matchingErr(cs.Left, "${", "}") } + cs.Right = pos return cs default: return p.paramExp() @@ -630,7 +670,7 @@ func (p *Parser) wordPart() WordPart { cs := &CmdSubst{Left: p.pos} old := p.preNested(subCmd) p.next() - cs.StmtList = p.stmts() + cs.StmtList = p.stmtList() p.postNested(old) cs.Right = p.matched(cs.Left, leftParen, rightParen) return cs @@ -648,7 +688,7 @@ func (p *Parser) wordPart() WordPart { ps := &ProcSubst{Op: ProcOperator(p.tok), OpPos: p.pos} old := p.preNested(subCmd) p.next() - ps.StmtList = p.stmts() + ps.StmtList = p.stmtList() p.postNested(old) ps.Rparen = p.matched(ps.OpPos, token(ps.Op), rightParen) return ps @@ -709,7 +749,7 @@ func (p *Parser) wordPart() WordPart { cs := &CmdSubst{Left: p.pos} old := p.preNested(subCmdBckquo) p.next() - cs.StmtList = p.stmts() + cs.StmtList = p.stmtList() p.postNested(old) cs.Right = p.pos if !p.got(bckQuote) { @@ -813,6 +853,9 @@ func (p *Parser) arithmExpr(level int, compact, tern bool) ArithmExpr { if compact && p.spaced { return left } + if p.tok == _Newl { + p.next() + } newLevel := arithmOpLevel(BinAritOperator(p.tok)) if !tern && p.tok == colon && p.quote&allParamArith != 0 { newLevel = -1 @@ -1134,7 +1177,7 @@ func (p *Parser) arithmEnd(ltok token, lpos Pos, old saveState) Pos { func stopToken(tok token) bool { switch tok { - case _EOF, semicolon, and, or, andAnd, orOr, orAnd, dblSemicolon, + case _EOF, _Newl, semicolon, and, or, andAnd, orOr, orAnd, dblSemicolon, semiAnd, dblSemiAnd, semiOr, rightParen: return true } @@ -1239,6 +1282,9 @@ func (p *Parser) getAssign(needEqual bool) *Assign { } old := p.preNested(newQuote) p.next() + if p.tok == _Newl { + p.next() + } for p.tok != _EOF && p.tok != rightParen { ae := &ArrayElem{} ae.Comments, p.accComs = p.accComs, nil @@ -1273,6 +1319,9 @@ func (p *Parser) getAssign(needEqual bool) *Assign { } } as.Array.Elems = append(as.Array.Elems, ae) + if p.tok == _Newl { + p.next() + } } as.Array.Last, p.accComs = p.accComs, nil p.postNested(old) @@ -1301,7 +1350,7 @@ func (p *Parser) doRedirect(s *Stmt) { r.N = p.getLit() r.Op, r.OpPos = RedirOperator(p.tok), p.pos p.next() - if p.newLine { + if p.tok == _Newl { p.curErr("redirect word must be on the same line") } switch r.Op { @@ -1311,8 +1360,8 @@ func (p *Parser) doRedirect(s *Stmt) { p.heredocs = append(p.heredocs, r) r.Word = p.followWordTok(token(r.Op), r.OpPos) p.quote, p.forbidNested = old, false - if p.tok == illegalTok { - p.next() + if p.tok == _Newl { + p.doHeredocs() } default: r.Word = p.followWordTok(token(r.Op), r.OpPos) @@ -1321,10 +1370,11 @@ func (p *Parser) doRedirect(s *Stmt) { } func (p *Parser) getStmt(readEnd, binCmd bool) (s *Stmt, gotEnd bool) { - s = p.stmt(p.pos) - if p.gotRsrv("!") { + pos, ok := p.gotRsrv("!") + s = p.stmt(pos) + if ok { s.Negated = true - if p.newLine || stopToken(p.tok) { + if stopToken(p.tok) { p.posErr(s.Pos(), `"!" cannot form a statement alone`) } } @@ -1359,7 +1409,7 @@ func (p *Parser) getStmt(readEnd, binCmd bool) (s *Stmt, gotEnd bool) { } fallthrough case semicolon: - if !p.newLine && readEnd { + if readEnd { s.Semicolon = p.pos p.next() } @@ -1382,6 +1432,10 @@ func (p *Parser) getStmt(readEnd, binCmd bool) (s *Stmt, gotEnd bool) { } func (p *Parser) gotStmtPipe(s *Stmt) *Stmt { + if p.tok == _Newl { + p.next() + s.Position = p.pos + } s.Comments, p.accComs = p.accComs, nil switch p.tok { case _LitWord: @@ -1474,7 +1528,7 @@ func (p *Parser) gotStmtPipe(s *Stmt) *Stmt { hdoc, dashHdoc, wordHdoc, rdrAll, appAll, _LitRedir: p.doRedirect(s) switch { - case p.newLine, p.tok == _EOF, p.tok == semicolon: + case p.tok == _EOF, p.tok == semicolon, p.tok == _Newl: return s } s.Cmd = p.callExpr(s, nil, false) @@ -1504,7 +1558,7 @@ func (p *Parser) gotStmtPipe(s *Stmt) *Stmt { return nil } } - for !p.newLine && p.peekRedir() { + for p.peekRedir() { p.doRedirect(s) } switch p.tok { @@ -1531,7 +1585,7 @@ func (p *Parser) subshell() *Subshell { s := &Subshell{Lparen: p.pos} old := p.preNested(subCmd) p.next() - s.StmtList = p.stmts() + s.StmtList = p.stmtList() p.postNested(old) s.Rparen = p.matched(s.Lparen, leftParen, rightParen) return s @@ -1555,9 +1609,10 @@ func (p *Parser) arithmExpCmd() Command { func (p *Parser) block() *Block { b := &Block{Lbrace: p.pos} p.next() - b.StmtList = p.stmts("}") - b.Rbrace = p.pos - if !p.gotRsrv("}") { + b.StmtList = p.stmtList("}") + pos, ok := p.gotRsrv("}") + b.Rbrace = pos + if !ok { p.matchingErr(b.Lbrace, "{", "}") } return b @@ -1582,7 +1637,7 @@ func (p *Parser) ifClause() *IfClause { curIf.Else.Stmts = []*Stmt{s} curIf = elf } - if elsePos := p.pos; p.gotRsrv("else") { + if elsePos, ok := p.gotRsrv("else"); ok { curIf.ElsePos = elsePos curIf.Else = p.followStmts("else", curIf.ElsePos, "fi") } @@ -1647,8 +1702,8 @@ func (p *Parser) wordIter(ftok string, fpos Pos) *WordIter { if wi.Name = p.getLit(); wi.Name == nil { p.followErr(fpos, ftok, "a literal") } - if p.gotRsrv("in") { - for !p.newLine && p.tok != _EOF && p.tok != semicolon { + if _, ok := p.gotRsrv("in"); ok { + for p.tok != _Newl && p.tok != _EOF && p.tok != semicolon { if w := p.getWord(); w == nil { p.curErr("word list can only contain words") } else { @@ -1656,7 +1711,7 @@ func (p *Parser) wordIter(ftok string, fpos Pos) *WordIter { } } p.gotSameLine(semicolon) - } else if !p.newLine && !p.got(semicolon) { + } else if p.tok != _Newl && !p.got(semicolon) { p.followErr(fpos, ftok+" foo", `"in", ; or a newline`) } return wi @@ -1677,7 +1732,7 @@ func (p *Parser) caseClause() *CaseClause { p.next() cc.Word = p.followWord("case", cc.Case) end := "esac" - if p.gotRsrv("{") { + if _, ok := p.gotRsrv("{"); ok { if p.lang != LangMirBSDKorn { p.posErr(cc.Pos(), `"case i {" is a mksh feature`) } @@ -1692,6 +1747,9 @@ func (p *Parser) caseClause() *CaseClause { } func (p *Parser) caseItems(stop string) (items []*CaseItem) { + if p.tok == _Newl { + p.next() + } for p.tok != _EOF && !(p.tok == _LitWord && p.val == stop) { ci := &CaseItem{} ci.Comments, p.accComs = p.accComs, nil @@ -1711,7 +1769,7 @@ func (p *Parser) caseItems(stop string) (items []*CaseItem) { } old := p.preNested(switchCase) p.next() - ci.StmtList = p.stmts(stop) + ci.StmtList = p.stmtList(stop) p.postNested(old) ci.OpPos = p.pos switch p.tok { @@ -1733,18 +1791,22 @@ func (p *Parser) caseItems(stop string) (items []*CaseItem) { } } items = append(items, ci) + if p.tok == _Newl { + p.next() + } } return } func (p *Parser) testClause() *TestClause { tc := &TestClause{Left: p.pos} - if p.next(); p.tok == _EOF || p.gotRsrv("]]") { + p.next() + if _, ok := p.gotRsrv("]]"); ok || p.tok == _EOF { p.posErr(tc.Left, "test clause requires at least one expression") } tc.X = p.testExpr(illegalTok, tc.Left, false) tc.Right = p.pos - if !p.gotRsrv("]]") { + if _, ok := p.gotRsrv("]]"); !ok { p.matchingErr(tc.Left, "[[", "]]") } return tc @@ -1864,7 +1926,7 @@ func (p *Parser) declClause() *DeclClause { for (p.tok == _LitWord || p.tok == _Lit) && p.val[0] == '-' { ds.Opts = append(ds.Opts, p.getWord()) } - for !p.newLine && !stopToken(p.tok) && !p.peekRedir() { + for !stopToken(p.tok) && !p.peekRedir() { if (p.tok == _Lit || p.tok == _LitWord) && p.hasValidIdent() { ds.Assigns = append(ds.Assigns, p.getAssign(false)) } else if p.eqlOffs > 0 { @@ -1904,7 +1966,7 @@ func isBashCompoundCommand(tok token, val string) bool { func (p *Parser) timeClause() *TimeClause { tc := &TimeClause{Time: p.pos} p.next() - if !p.newLine { + if p.tok != _Newl { tc.Stmt = p.gotStmtPipe(p.stmt(p.pos)) } return tc @@ -1917,7 +1979,7 @@ func (p *Parser) coprocClause() *CoprocClause { cc.Stmt = p.gotStmtPipe(p.stmt(p.pos)) return cc } - if p.newLine { + if p.tok == _Newl { p.posErr(cc.Coproc, "coproc clause requires a command") } cc.Name = p.getLit() @@ -1946,7 +2008,7 @@ func (p *Parser) letClause() *LetClause { lc := &LetClause{Let: p.pos} old := p.preNested(arithmExprLet) p.next() - for !p.newLine && !stopToken(p.tok) && !p.peekRedir() { + for !stopToken(p.tok) && !p.peekRedir() { x := p.arithmExpr(0, true, false) if x == nil { break @@ -1957,9 +2019,6 @@ func (p *Parser) letClause() *LetClause { p.followErrExp(lc.Let, "let") } p.postNested(old) - if p.tok == illegalTok { - p.next() - } return lc } @@ -1987,9 +2046,9 @@ func (p *Parser) callExpr(s *Stmt, w *Word, assign bool) Command { ce.Assigns = append(ce.Assigns, p.getAssign(true)) } loop: - for !p.newLine { + for { switch p.tok { - case _EOF, semicolon, and, or, andAnd, orOr, orAnd, + case _EOF, _Newl, semicolon, and, or, andAnd, orOr, orAnd, dblSemicolon, semiAnd, dblSemiAnd, semiOr: break loop case _LitWord: diff --git a/vendor/mvdan.cc/sh/syntax/token_string.go b/vendor/mvdan.cc/sh/syntax/token_string.go index a7481f40..bc5d4dc1 100644 --- a/vendor/mvdan.cc/sh/syntax/token_string.go +++ b/vendor/mvdan.cc/sh/syntax/token_string.go @@ -4,9 +4,9 @@ package syntax import "fmt" -const _token_name = "illegalTokEOFLitLitWordLitRedir'\"`&&&||||&$$'$\"${$[$($(([(((}])));;;;&;;&;|!++--***==!=<=>=+=-=*=/=%=&=|=^=<<=>>=>>><<><&>&>|<<<<-<<<&>&>><(>(+:+-:-?:?=:=%%%###^^^,,,@///:-e-f-d-c-b-p-S-L-k-g-u-G-O-N-r-w-x-s-t-z-n-o-v-R=~-nt-ot-ef-eq-ne-le-ge-lt-gt?(*(+(@(!(" +const _token_name = "illegalTokEOFNewlineLitLitWordLitRedir'\"`&&&||||&$$'$\"${$[$($(([(((}])));;;;&;;&;|!++--***==!=<=>=+=-=*=/=%=&=|=^=<<=>>=>>><<><&>&>|<<<<-<<<&>&>><(>(+:+-:-?:?=:=%%%###^^^,,,@///:-e-f-d-c-b-p-S-L-k-g-u-G-O-N-r-w-x-s-t-z-n-o-v-R=~-nt-ot-ef-eq-ne-le-ge-lt-gt?(*(+(@(!(" -var _token_index = [...]uint16{0, 10, 13, 16, 23, 31, 32, 33, 34, 35, 37, 39, 40, 42, 43, 45, 47, 49, 51, 53, 56, 57, 58, 60, 61, 62, 63, 65, 66, 68, 70, 73, 75, 76, 78, 80, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 110, 113, 114, 116, 117, 119, 121, 123, 125, 127, 130, 133, 135, 138, 140, 142, 143, 145, 146, 148, 149, 151, 152, 154, 155, 157, 158, 160, 161, 163, 164, 166, 167, 168, 170, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 250, 252, 254, 256, 258} +var _token_index = [...]uint16{0, 10, 13, 20, 23, 30, 38, 39, 40, 41, 42, 44, 46, 47, 49, 50, 52, 54, 56, 58, 60, 63, 64, 65, 67, 68, 69, 70, 72, 73, 75, 77, 80, 82, 83, 85, 87, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 117, 120, 121, 123, 124, 126, 128, 130, 132, 134, 137, 140, 142, 145, 147, 149, 150, 152, 153, 155, 156, 158, 159, 161, 162, 164, 165, 167, 168, 170, 171, 173, 174, 175, 177, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 231, 234, 237, 240, 243, 246, 249, 252, 255, 257, 259, 261, 263, 265} func (i token) String() string { if i >= token(len(_token_index)-1) { diff --git a/vendor/mvdan.cc/sh/syntax/tokens.go b/vendor/mvdan.cc/sh/syntax/tokens.go index e623135b..ce617873 100644 --- a/vendor/mvdan.cc/sh/syntax/tokens.go +++ b/vendor/mvdan.cc/sh/syntax/tokens.go @@ -15,6 +15,7 @@ const ( illegalTok token = iota _EOF // EOF + _Newl // Newline _Lit // Lit _LitWord // LitWord _LitRedir // LitRedir