mirror of
https://github.com/go-task/task.git
synced 2025-01-26 05:27:15 +02:00
Update github.com/mvdan/sh
This commit is contained in:
parent
460297e43a
commit
c40148a52e
10
vendor/github.com/mvdan/sh/interp/arith.go
generated
vendored
10
vendor/github.com/mvdan/sh/interp/arith.go
generated
vendored
@ -11,8 +11,8 @@ import (
|
||||
|
||||
func (r *Runner) arithm(expr syntax.ArithmExpr) int {
|
||||
switch x := expr.(type) {
|
||||
case *syntax.Lit:
|
||||
str := x.Value
|
||||
case *syntax.Word:
|
||||
str := r.loneWord(x)
|
||||
// recursively fetch vars
|
||||
for {
|
||||
val := r.getVar(str)
|
||||
@ -23,14 +23,12 @@ 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.Lit).Value
|
||||
name := x.X.(*syntax.Word).Parts[0].(*syntax.Lit).Value
|
||||
old := atoi(r.getVar(name))
|
||||
val := old
|
||||
if x.Op == syntax.Inc {
|
||||
@ -83,7 +81,7 @@ func atoi(s string) int {
|
||||
}
|
||||
|
||||
func (r *Runner) assgnArit(b *syntax.BinaryArithm) int {
|
||||
name := b.X.(*syntax.Lit).Value
|
||||
name := b.X.(*syntax.Word).Parts[0].(*syntax.Lit).Value
|
||||
val := atoi(r.getVar(name))
|
||||
arg := r.arithm(b.Y)
|
||||
switch b.Op {
|
||||
|
65
vendor/github.com/mvdan/sh/interp/interp.go
generated
vendored
65
vendor/github.com/mvdan/sh/interp/interp.go
generated
vendored
@ -98,10 +98,12 @@ func (r *Runner) varInd(v varValue, e syntax.ArithmExpr) string {
|
||||
}
|
||||
case []string:
|
||||
// TODO: @ between double quotes
|
||||
if lit, ok := e.(*syntax.Lit); ok {
|
||||
switch lit.Value {
|
||||
case "@", "*":
|
||||
return strings.Join(x, " ")
|
||||
if w, ok := e.(*syntax.Word); ok {
|
||||
if lit, ok := w.Parts[0].(*syntax.Lit); ok {
|
||||
switch lit.Value {
|
||||
case "@", "*":
|
||||
return strings.Join(x, " ")
|
||||
}
|
||||
}
|
||||
}
|
||||
i := r.arithm(e)
|
||||
@ -231,6 +233,9 @@ func (r *Runner) fields(words []*syntax.Word) []string {
|
||||
}
|
||||
|
||||
func (r *Runner) loneWord(word *syntax.Word) string {
|
||||
if word == nil {
|
||||
return ""
|
||||
}
|
||||
return strings.Join(r.wordParts(word.Parts, false), "")
|
||||
}
|
||||
|
||||
@ -263,13 +268,37 @@ func (r *Runner) stmt(st *syntax.Stmt) {
|
||||
}
|
||||
|
||||
func (r *Runner) assignValue(as *syntax.Assign) varValue {
|
||||
prev, _ := r.lookupVar(as.Name.Value)
|
||||
if as.Value != nil {
|
||||
return r.loneWord(as.Value)
|
||||
s := r.loneWord(as.Value)
|
||||
if !as.Append || prev == nil {
|
||||
return s
|
||||
}
|
||||
switch x := prev.(type) {
|
||||
case string:
|
||||
return x + s
|
||||
case []string:
|
||||
if len(x) == 0 {
|
||||
return []string{s}
|
||||
}
|
||||
x[0] += s
|
||||
return x
|
||||
}
|
||||
return s
|
||||
}
|
||||
if as.Array != nil {
|
||||
strs := make([]string, len(as.Array.List))
|
||||
for i, w := range as.Array.List {
|
||||
strs[i] = r.loneWord(w)
|
||||
strs := make([]string, len(as.Array.Elems))
|
||||
for i, elem := range as.Array.Elems {
|
||||
strs[i] = r.loneWord(elem.Value)
|
||||
}
|
||||
if !as.Append || prev == nil {
|
||||
return strs
|
||||
}
|
||||
switch x := prev.(type) {
|
||||
case string:
|
||||
return append([]string{x}, strs...)
|
||||
case []string:
|
||||
return append(x, strs...)
|
||||
}
|
||||
return strs
|
||||
}
|
||||
@ -279,16 +308,15 @@ func (r *Runner) assignValue(as *syntax.Assign) varValue {
|
||||
func (r *Runner) stmtSync(st *syntax.Stmt) {
|
||||
oldVars := r.cmdVars
|
||||
for _, as := range st.Assigns {
|
||||
name := as.Name.Value
|
||||
val := r.assignValue(as)
|
||||
if st.Cmd == nil {
|
||||
r.setVar(name, val)
|
||||
r.setVar(as.Name.Value, val)
|
||||
continue
|
||||
}
|
||||
if r.cmdVars == nil {
|
||||
r.cmdVars = make(map[string]varValue, len(st.Assigns))
|
||||
}
|
||||
r.cmdVars[name] = val
|
||||
r.cmdVars[as.Name.Value] = val
|
||||
}
|
||||
oldIn, oldOut, oldErr := r.Stdin, r.Stdout, r.Stderr
|
||||
for _, rd := range st.Redirs {
|
||||
@ -392,7 +420,7 @@ func (r *Runner) cmd(cm syntax.Command) {
|
||||
switch y := x.Loop.(type) {
|
||||
case *syntax.WordIter:
|
||||
name := y.Name.Value
|
||||
for _, field := range r.fields(y.List) {
|
||||
for _, field := range r.fields(y.Items) {
|
||||
r.setVar(name, field)
|
||||
if r.loopStmtsBroken(x.DoStmts) {
|
||||
break
|
||||
@ -423,11 +451,11 @@ func (r *Runner) cmd(cm syntax.Command) {
|
||||
}
|
||||
case *syntax.CaseClause:
|
||||
str := r.loneWord(x.Word)
|
||||
for _, pl := range x.List {
|
||||
for _, word := range pl.Patterns {
|
||||
for _, ci := range x.Items {
|
||||
for _, word := range ci.Patterns {
|
||||
pat := r.loneWord(word)
|
||||
if match(pat, str) {
|
||||
r.stmts(pl.Stmts)
|
||||
r.stmts(ci.Stmts)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -436,6 +464,13 @@ func (r *Runner) cmd(cm syntax.Command) {
|
||||
if r.bashTest(x.X) == "" && r.exit == 0 {
|
||||
r.exit = 1
|
||||
}
|
||||
case *syntax.DeclClause:
|
||||
if len(x.Opts) > 0 {
|
||||
r.runErr(cm.Pos(), "unhandled declare opts")
|
||||
}
|
||||
for _, as := range x.Assigns {
|
||||
r.setVar(as.Name.Value, r.assignValue(as))
|
||||
}
|
||||
default:
|
||||
r.runErr(cm.Pos(), "unhandled command node: %T", x)
|
||||
}
|
||||
|
4
vendor/github.com/mvdan/sh/interp/test.go
generated
vendored
4
vendor/github.com/mvdan/sh/interp/test.go
generated
vendored
@ -146,7 +146,9 @@ func (r *Runner) unTest(op syntax.UnTestOperator, x string) bool {
|
||||
case syntax.TsNempStr:
|
||||
return x != ""
|
||||
//case syntax.TsOptSet:
|
||||
//case syntax.TsVarSet:
|
||||
case syntax.TsVarSet:
|
||||
_, e := r.lookupVar(x)
|
||||
return e
|
||||
//case syntax.TsRefVar:
|
||||
case syntax.TsNot:
|
||||
return x == ""
|
||||
|
8
vendor/github.com/mvdan/sh/syntax/canonical.sh
generated
vendored
8
vendor/github.com/mvdan/sh/syntax/canonical.sh
generated
vendored
@ -18,10 +18,10 @@ for foo in a b c; do
|
||||
done
|
||||
|
||||
case $foo in
|
||||
a) A ;;
|
||||
b)
|
||||
B
|
||||
;;
|
||||
a) A ;;
|
||||
b)
|
||||
B
|
||||
;;
|
||||
esac
|
||||
|
||||
foo | bar
|
||||
|
106
vendor/github.com/mvdan/sh/syntax/lexer.go
generated
vendored
106
vendor/github.com/mvdan/sh/syntax/lexer.go
generated
vendored
@ -32,7 +32,7 @@ func paramOps(r rune) bool {
|
||||
func arithmOps(r rune) bool {
|
||||
switch r {
|
||||
case '+', '-', '!', '*', '/', '%', '(', ')', '^', '<', '>', ':', '=',
|
||||
',', '?', '|', '&', ']':
|
||||
',', '?', '|', '&', '[', ']', '#':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@ -86,10 +86,11 @@ retry:
|
||||
return p.r
|
||||
}
|
||||
|
||||
func (p *Parser) unrune(r rune) {
|
||||
func (p *Parser) unrune(r rune, tok token) {
|
||||
if p.r != utf8.RuneSelf {
|
||||
p.npos -= utf8.RuneLen(p.r)
|
||||
p.r = r
|
||||
p.tok = tok
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,6 +241,13 @@ skipSpace:
|
||||
p.litBs = nil
|
||||
}
|
||||
p.next()
|
||||
case '[':
|
||||
if p.quote == arrayElems {
|
||||
p.tok = leftBrack
|
||||
p.rune()
|
||||
} else {
|
||||
p.advanceLitNone(r)
|
||||
}
|
||||
case '?', '*', '+', '@', '!':
|
||||
if p.peekByte('(') {
|
||||
switch r {
|
||||
@ -306,7 +314,7 @@ func (p *Parser) regToken(r rune) token {
|
||||
p.rune()
|
||||
return andAnd
|
||||
case '>':
|
||||
if !p.bash() {
|
||||
if p.lang == LangPOSIX {
|
||||
break
|
||||
}
|
||||
if p.rune() == '>' {
|
||||
@ -322,23 +330,23 @@ func (p *Parser) regToken(r rune) token {
|
||||
p.rune()
|
||||
return orOr
|
||||
case '&':
|
||||
if !p.bash() {
|
||||
if p.lang == LangPOSIX {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
return pipeAll
|
||||
return orAnd
|
||||
}
|
||||
return or
|
||||
case '$':
|
||||
switch p.rune() {
|
||||
case '\'':
|
||||
if !p.bash() {
|
||||
if p.lang == LangPOSIX {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
return dollSglQuote
|
||||
case '"':
|
||||
if !p.bash() {
|
||||
if p.lang == LangPOSIX {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
@ -347,7 +355,7 @@ func (p *Parser) regToken(r rune) token {
|
||||
p.rune()
|
||||
return dollBrace
|
||||
case '[':
|
||||
if !p.bash() {
|
||||
if p.lang != LangBash {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
@ -361,7 +369,7 @@ func (p *Parser) regToken(r rune) token {
|
||||
}
|
||||
return dollar
|
||||
case '(':
|
||||
if p.rune() == '(' && p.bash() {
|
||||
if p.rune() == '(' && p.lang != LangPOSIX {
|
||||
p.rune()
|
||||
return dblLeftParen
|
||||
}
|
||||
@ -372,17 +380,23 @@ func (p *Parser) regToken(r rune) token {
|
||||
case ';':
|
||||
switch p.rune() {
|
||||
case ';':
|
||||
if p.rune() == '&' && p.bash() {
|
||||
if p.rune() == '&' && p.lang == LangBash {
|
||||
p.rune()
|
||||
return dblSemiFall
|
||||
return dblSemiAnd
|
||||
}
|
||||
return dblSemicolon
|
||||
case '&':
|
||||
if !p.bash() {
|
||||
if p.lang == LangPOSIX {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
return semiFall
|
||||
return semiAnd
|
||||
case '|':
|
||||
if p.lang != LangMirBSDKorn {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
return semiOr
|
||||
}
|
||||
return semicolon
|
||||
case '<':
|
||||
@ -391,7 +405,7 @@ func (p *Parser) regToken(r rune) token {
|
||||
if r = p.rune(); r == '-' {
|
||||
p.rune()
|
||||
return dashHdoc
|
||||
} else if r == '<' && p.bash() {
|
||||
} else if r == '<' && p.lang != LangPOSIX {
|
||||
p.rune()
|
||||
return wordHdoc
|
||||
}
|
||||
@ -403,7 +417,7 @@ func (p *Parser) regToken(r rune) token {
|
||||
p.rune()
|
||||
return dplIn
|
||||
case '(':
|
||||
if !p.bash() {
|
||||
if p.lang != LangBash {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
@ -422,7 +436,7 @@ func (p *Parser) regToken(r rune) token {
|
||||
p.rune()
|
||||
return clbOut
|
||||
case '(':
|
||||
if !p.bash() {
|
||||
if p.lang != LangBash {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
@ -446,7 +460,7 @@ func (p *Parser) dqToken(r rune) token {
|
||||
p.rune()
|
||||
return dollBrace
|
||||
case '[':
|
||||
if !p.bash() {
|
||||
if p.lang != LangBash {
|
||||
break
|
||||
}
|
||||
p.rune()
|
||||
@ -651,6 +665,9 @@ func (p *Parser) arithmToken(r rune) token {
|
||||
return xorAssgn
|
||||
}
|
||||
return caret
|
||||
case '[':
|
||||
p.rune()
|
||||
return leftBrack
|
||||
case ']':
|
||||
p.rune()
|
||||
return rightBrack
|
||||
@ -660,9 +677,12 @@ func (p *Parser) arithmToken(r rune) token {
|
||||
case '?':
|
||||
p.rune()
|
||||
return quest
|
||||
default: // ':'
|
||||
case ':':
|
||||
p.rune()
|
||||
return colon
|
||||
default: // '#'
|
||||
p.rune()
|
||||
return hash
|
||||
}
|
||||
}
|
||||
|
||||
@ -756,7 +776,7 @@ loop:
|
||||
if p.quote&allParamReg != 0 {
|
||||
break loop
|
||||
}
|
||||
if r == '[' && p.bash() && p.quote&allArithmExpr != 0 {
|
||||
if r == '[' && p.lang != LangPOSIX && p.quote&allArithmExpr != 0 {
|
||||
break loop
|
||||
}
|
||||
case '+':
|
||||
@ -829,7 +849,7 @@ loop:
|
||||
case '=':
|
||||
p.asPos = len(p.litBs) - 1
|
||||
case '[':
|
||||
if p.bash() && len(p.litBs) > 1 && p.litBs[0] != '[' {
|
||||
if p.lang != LangPOSIX && len(p.litBs) > 1 && p.litBs[0] != '[' {
|
||||
tok = _Lit
|
||||
break loop
|
||||
}
|
||||
@ -864,19 +884,25 @@ func (p *Parser) advanceLitHdoc(r rune) {
|
||||
}
|
||||
}
|
||||
lStart := len(p.litBs) - 1
|
||||
loop:
|
||||
for ; r != utf8.RuneSelf; r = p.rune() {
|
||||
for ; ; r = p.rune() {
|
||||
switch r {
|
||||
case '`', '$':
|
||||
break loop
|
||||
p.val = p.endLit()
|
||||
return
|
||||
case '\\': // escaped byte follows
|
||||
p.rune()
|
||||
case '\n':
|
||||
if bytes.Equal(p.litBs[lStart:len(p.litBs)-1], p.hdocStop) {
|
||||
case '\n', utf8.RuneSelf:
|
||||
if bytes.HasPrefix(p.litBs[lStart:], p.hdocStop) {
|
||||
p.val = p.endLit()[:lStart]
|
||||
if p.val == "" {
|
||||
p.tok = illegalTok
|
||||
}
|
||||
p.hdocStop = nil
|
||||
return
|
||||
}
|
||||
if r == utf8.RuneSelf {
|
||||
return
|
||||
}
|
||||
if p.quote == hdocBodyTabs {
|
||||
for p.peekByte('\t') {
|
||||
p.rune()
|
||||
@ -885,22 +911,15 @@ loop:
|
||||
lStart = len(p.litBs)
|
||||
}
|
||||
}
|
||||
if bytes.Equal(p.litBs[lStart:], p.hdocStop) {
|
||||
p.val = p.endLit()[:lStart]
|
||||
p.hdocStop = nil
|
||||
} else {
|
||||
p.val = p.endLit()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) hdocLitWord() *Word {
|
||||
r := p.r
|
||||
p.newLit(r)
|
||||
pos, val := p.getPos(), ""
|
||||
for {
|
||||
pos := p.getPos()
|
||||
for ; ; r = p.rune() {
|
||||
if r == utf8.RuneSelf {
|
||||
val = p.endLit()
|
||||
break
|
||||
return nil
|
||||
}
|
||||
if p.quote == hdocBodyTabs {
|
||||
for r == '\t' {
|
||||
@ -911,18 +930,15 @@ func (p *Parser) hdocLitWord() *Word {
|
||||
for r != utf8.RuneSelf && r != '\n' {
|
||||
r = p.rune()
|
||||
}
|
||||
lEnd := len(p.litBs)
|
||||
if r != utf8.RuneSelf {
|
||||
lEnd--
|
||||
if bytes.HasPrefix(p.litBs[lStart:], p.hdocStop) {
|
||||
p.hdocStop = nil
|
||||
val := p.endLit()[:lStart]
|
||||
if val == "" {
|
||||
return nil
|
||||
}
|
||||
return p.word(p.wps(p.lit(pos, val)))
|
||||
}
|
||||
if bytes.Equal(p.litBs[lStart:lEnd], p.hdocStop) {
|
||||
val = p.endLit()[:lStart]
|
||||
break
|
||||
}
|
||||
r = p.rune()
|
||||
}
|
||||
l := p.lit(pos, val)
|
||||
return p.word(p.wps(l))
|
||||
}
|
||||
|
||||
func (p *Parser) advanceLitRe(r rune) {
|
||||
|
101
vendor/github.com/mvdan/sh/syntax/nodes.go
generated
vendored
101
vendor/github.com/mvdan/sh/syntax/nodes.go
generated
vendored
@ -111,12 +111,15 @@ func (c *Comment) End() Pos { return c.Hash + Pos(len(c.Text)) }
|
||||
// Stmt represents a statement, otherwise known as a compound command.
|
||||
// It is compromised of a command and other components that may come
|
||||
// before or after it.
|
||||
//
|
||||
// The Coprocess field is particular to MirBSDKorn.
|
||||
type Stmt struct {
|
||||
Cmd Command
|
||||
Position Pos
|
||||
Semicolon Pos
|
||||
Negated bool
|
||||
Background bool
|
||||
Coprocess bool
|
||||
Assigns []*Assign
|
||||
Redirs []*Redirect
|
||||
}
|
||||
@ -147,7 +150,7 @@ func (s *Stmt) End() Pos {
|
||||
//
|
||||
// These are *CallExpr, *IfClause, *WhileClause, *ForClause,
|
||||
// *CaseClause, *Block, *Subshell, *BinaryCmd, *FuncDecl, *ArithmCmd,
|
||||
// *TestClause, *DeclClause, *LetClause, and *CoprocClause.
|
||||
// *TestClause, *DeclClause, *LetClause, *TimeClause, and *CoprocClause.
|
||||
type Command interface {
|
||||
Node
|
||||
commandNode()
|
||||
@ -166,24 +169,21 @@ func (*ArithmCmd) commandNode() {}
|
||||
func (*TestClause) commandNode() {}
|
||||
func (*DeclClause) commandNode() {}
|
||||
func (*LetClause) commandNode() {}
|
||||
func (*TimeClause) commandNode() {}
|
||||
func (*CoprocClause) commandNode() {}
|
||||
|
||||
// Assign represents an assignment to a variable.
|
||||
type Assign struct {
|
||||
Append bool
|
||||
Naked bool
|
||||
Name *Lit
|
||||
Index ArithmExpr
|
||||
Key *DblQuoted
|
||||
Value *Word
|
||||
Array *ArrayExpr
|
||||
}
|
||||
|
||||
func (a *Assign) Pos() Pos {
|
||||
if a.Name != nil {
|
||||
return a.Name.Pos()
|
||||
}
|
||||
return a.Value.Pos()
|
||||
}
|
||||
|
||||
func (a *Assign) Pos() Pos { return a.Name.Pos() }
|
||||
func (a *Assign) End() Pos {
|
||||
if a.Value != nil {
|
||||
return a.Value.End()
|
||||
@ -194,6 +194,12 @@ func (a *Assign) End() Pos {
|
||||
if a.Index != nil {
|
||||
return a.Index.End() + 2
|
||||
}
|
||||
if a.Key != nil {
|
||||
return a.Key.End() + 2
|
||||
}
|
||||
if a.Naked {
|
||||
return a.Name.End()
|
||||
}
|
||||
return a.Name.End() + 1
|
||||
}
|
||||
|
||||
@ -293,12 +299,12 @@ func (*CStyleLoop) loopNode() {}
|
||||
// WordIter represents the iteration of a variable over a series of
|
||||
// words in a for clause.
|
||||
type WordIter struct {
|
||||
Name *Lit
|
||||
List []*Word
|
||||
Name *Lit
|
||||
Items []*Word
|
||||
}
|
||||
|
||||
func (w *WordIter) Pos() Pos { return w.Name.Pos() }
|
||||
func (w *WordIter) End() Pos { return posMax(w.Name.End(), wordLastEnd(w.List)) }
|
||||
func (w *WordIter) End() Pos { return posMax(w.Name.End(), wordLastEnd(w.Items)) }
|
||||
|
||||
// CStyleLoop represents the behaviour of a for clause similar to the C
|
||||
// language.
|
||||
@ -408,6 +414,11 @@ func (q *DblQuoted) End() Pos {
|
||||
type CmdSubst struct {
|
||||
Left, Right Pos
|
||||
Stmts []*Stmt
|
||||
|
||||
// MirBSDTempFile is true for mksh's ${ foo;}
|
||||
MirBSDTempFile bool
|
||||
// MirBSDReplyvar is true for mksh's ${|foo;}
|
||||
MirBSDReplyVar bool
|
||||
}
|
||||
|
||||
func (c *CmdSubst) Pos() Pos { return c.Left }
|
||||
@ -419,8 +430,10 @@ type ParamExp struct {
|
||||
Short bool
|
||||
Indirect bool
|
||||
Length bool
|
||||
Width bool
|
||||
Param *Lit
|
||||
Index ArithmExpr
|
||||
Key *DblQuoted
|
||||
Slice *Slice
|
||||
Repl *Replace
|
||||
Exp *Expansion
|
||||
@ -431,10 +444,18 @@ func (p *ParamExp) End() Pos {
|
||||
if !p.Short {
|
||||
return p.Rbrace + 1
|
||||
}
|
||||
if p.Index != nil {
|
||||
return p.Index.End() + 1
|
||||
}
|
||||
if p.Key != nil {
|
||||
return p.Key.End() + 1
|
||||
}
|
||||
return p.Param.End()
|
||||
}
|
||||
|
||||
func (p *ParamExp) nakedIndex() bool { return p.Short && p.Index != nil }
|
||||
func (p *ParamExp) nakedIndex() bool {
|
||||
return p.Short && (p.Index != nil || p.Key != nil)
|
||||
}
|
||||
|
||||
// Slice represents character slicing inside a ParamExp.
|
||||
//
|
||||
@ -460,6 +481,7 @@ type Expansion struct {
|
||||
type ArithmExp struct {
|
||||
Left, Right Pos
|
||||
Bracket bool
|
||||
Unsigned bool
|
||||
X ArithmExpr
|
||||
}
|
||||
|
||||
@ -476,6 +498,7 @@ func (a *ArithmExp) End() Pos {
|
||||
// This node will never appear when in PosixConformant mode.
|
||||
type ArithmCmd struct {
|
||||
Left, Right Pos
|
||||
Unsigned bool
|
||||
X ArithmExpr
|
||||
}
|
||||
|
||||
@ -484,8 +507,7 @@ func (a *ArithmCmd) End() Pos { return a.Right + 2 }
|
||||
|
||||
// ArithmExpr represents all nodes that form arithmetic expressions.
|
||||
//
|
||||
// These are *BinaryArithm, *UnaryArithm, *ParenArithm, *Lit, and
|
||||
// *ParamExp.
|
||||
// These are *BinaryArithm, *UnaryArithm, *ParenArithm, and *Word.
|
||||
type ArithmExpr interface {
|
||||
Node
|
||||
arithmExprNode()
|
||||
@ -494,14 +516,13 @@ type ArithmExpr interface {
|
||||
func (*BinaryArithm) arithmExprNode() {}
|
||||
func (*UnaryArithm) arithmExprNode() {}
|
||||
func (*ParenArithm) arithmExprNode() {}
|
||||
func (*Lit) arithmExprNode() {}
|
||||
func (*ParamExp) arithmExprNode() {}
|
||||
func (*Word) arithmExprNode() {}
|
||||
|
||||
// BinaryArithm represents a binary expression between two arithmetic
|
||||
// expression.
|
||||
//
|
||||
// If Op is any assign operator, X will be a *Lit whose value is a valid
|
||||
// name.
|
||||
// If Op is any assign operator, X will be a word with a single *Lit
|
||||
// whose value is a valid name.
|
||||
//
|
||||
// Ternary operators like "a ? b : c" are fit into this structure. Thus,
|
||||
// if Op == Quest, Y will be a *BinaryArithm with Op == Colon. Op can
|
||||
@ -518,7 +539,8 @@ func (b *BinaryArithm) End() Pos { return b.Y.End() }
|
||||
// UnaryArithm represents an unary expression over a node, either before
|
||||
// or after it.
|
||||
//
|
||||
// If Op is Inc or Dec, X will be a *Lit whose value is a valid name.
|
||||
// If Op is Inc or Dec, X will be a word with a single *Lit whose value
|
||||
// is a valid name.
|
||||
type UnaryArithm struct {
|
||||
OpPos Pos
|
||||
Op UnAritOperator
|
||||
@ -554,14 +576,14 @@ func (p *ParenArithm) End() Pos { return p.Rparen + 1 }
|
||||
type CaseClause struct {
|
||||
Case, Esac Pos
|
||||
Word *Word
|
||||
List []*PatternList
|
||||
Items []*CaseItem
|
||||
}
|
||||
|
||||
func (c *CaseClause) Pos() Pos { return c.Case }
|
||||
func (c *CaseClause) End() Pos { return c.Esac + 4 }
|
||||
|
||||
// PatternList represents a pattern list (case) within a CaseClause.
|
||||
type PatternList struct {
|
||||
// CaseItem represents a pattern list (case) within a CaseClause.
|
||||
type CaseItem struct {
|
||||
Op CaseOperator
|
||||
OpPos Pos
|
||||
Patterns []*Word
|
||||
@ -647,12 +669,29 @@ func (d *DeclClause) End() Pos {
|
||||
// This node will never appear when in PosixConformant mode.
|
||||
type ArrayExpr struct {
|
||||
Lparen, Rparen Pos
|
||||
List []*Word
|
||||
Elems []*ArrayElem
|
||||
}
|
||||
|
||||
func (a *ArrayExpr) Pos() Pos { return a.Lparen }
|
||||
func (a *ArrayExpr) End() Pos { return a.Rparen + 1 }
|
||||
|
||||
type ArrayElem struct {
|
||||
Index ArithmExpr
|
||||
Key *DblQuoted
|
||||
Value *Word
|
||||
}
|
||||
|
||||
func (a *ArrayElem) Pos() Pos {
|
||||
if a.Index != nil {
|
||||
return a.Index.Pos()
|
||||
}
|
||||
if a.Key != nil {
|
||||
return a.Key.Pos()
|
||||
}
|
||||
return a.Value.Pos()
|
||||
}
|
||||
func (a *ArrayElem) End() Pos { return a.Value.End() }
|
||||
|
||||
// ExtGlob represents a Bash extended globbing expression. Note that
|
||||
// these are parsed independently of whether shopt has been called or
|
||||
// not.
|
||||
@ -679,6 +718,22 @@ type ProcSubst struct {
|
||||
func (s *ProcSubst) Pos() Pos { return s.OpPos }
|
||||
func (s *ProcSubst) End() Pos { return s.Rparen + 1 }
|
||||
|
||||
// TimeClause represents a Bash time clause.
|
||||
//
|
||||
// This node will never appear when in PosixConformant mode.
|
||||
type TimeClause struct {
|
||||
Time Pos
|
||||
Stmt *Stmt
|
||||
}
|
||||
|
||||
func (c *TimeClause) Pos() Pos { return c.Time }
|
||||
func (c *TimeClause) End() Pos {
|
||||
if c.Stmt == nil {
|
||||
return c.Time + 4
|
||||
}
|
||||
return c.Stmt.End()
|
||||
}
|
||||
|
||||
// CoprocClause represents a Bash coproc clause.
|
||||
//
|
||||
// This node will never appear when in PosixConformant mode.
|
||||
|
592
vendor/github.com/mvdan/sh/syntax/parser.go
generated
vendored
592
vendor/github.com/mvdan/sh/syntax/parser.go
generated
vendored
File diff suppressed because it is too large
Load Diff
254
vendor/github.com/mvdan/sh/syntax/printer.go
generated
vendored
254
vendor/github.com/mvdan/sh/syntax/printer.go
generated
vendored
@ -34,18 +34,14 @@ func (p *Printer) Print(w io.Writer, f *File) error {
|
||||
p.stmts(f.Stmts)
|
||||
p.commentsUpTo(0)
|
||||
p.newline(0)
|
||||
if flusher, ok := p.bufWriter.(interface {
|
||||
Flush() error
|
||||
}); ok {
|
||||
return flusher.Flush()
|
||||
}
|
||||
return nil
|
||||
return p.bufWriter.Flush()
|
||||
}
|
||||
|
||||
type bufWriter interface {
|
||||
WriteByte(byte) error
|
||||
WriteString(string) (int, error)
|
||||
Reset(io.Writer)
|
||||
Flush() error
|
||||
}
|
||||
|
||||
type Printer struct {
|
||||
@ -190,8 +186,10 @@ func (p *Printer) newline(pos Pos) {
|
||||
hdocs := p.pendingHdocs
|
||||
p.pendingHdocs = p.pendingHdocs[:0]
|
||||
for _, r := range hdocs {
|
||||
p.word(r.Hdoc)
|
||||
p.incLines(r.Hdoc.End())
|
||||
if r.Hdoc != nil {
|
||||
p.word(r.Hdoc)
|
||||
p.incLines(r.Hdoc.End())
|
||||
}
|
||||
p.unquotedWord(r.Word)
|
||||
p.WriteByte('\n')
|
||||
p.incLine()
|
||||
@ -233,13 +231,13 @@ func (p *Printer) semiRsrv(s string, pos Pos, fallback bool) {
|
||||
p.level--
|
||||
if p.wantNewline || pos > p.nline {
|
||||
p.newlines(pos)
|
||||
} else if fallback {
|
||||
if !p.wroteSemi {
|
||||
} else {
|
||||
if fallback && !p.wroteSemi {
|
||||
p.WriteByte(';')
|
||||
}
|
||||
p.WriteByte(' ')
|
||||
} else if p.wantSpace {
|
||||
p.WriteByte(' ')
|
||||
if p.wantSpace {
|
||||
p.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
p.WriteString(s)
|
||||
p.wantSpace = true
|
||||
@ -287,27 +285,34 @@ func (p *Printer) wordPart(wp WordPart) {
|
||||
p.WriteByte('\'')
|
||||
p.incLines(x.End())
|
||||
case *DblQuoted:
|
||||
if x.Dollar {
|
||||
p.WriteByte('$')
|
||||
}
|
||||
p.WriteByte('"')
|
||||
for i, n := range x.Parts {
|
||||
p.wordPart(n)
|
||||
if i == len(x.Parts)-1 {
|
||||
p.incLines(n.End())
|
||||
}
|
||||
}
|
||||
p.WriteByte('"')
|
||||
p.dblQuoted(x)
|
||||
case *CmdSubst:
|
||||
p.incLines(x.Pos())
|
||||
p.WriteString("$(")
|
||||
p.wantSpace = len(x.Stmts) > 0 && startsWithLparen(x.Stmts[0])
|
||||
p.nestedStmts(x.Stmts, x.Right)
|
||||
p.sepTok(")", x.Right)
|
||||
switch {
|
||||
case x.MirBSDTempFile:
|
||||
p.WriteString("${")
|
||||
p.wantSpace = true
|
||||
p.nestedStmts(x.Stmts, x.Right)
|
||||
p.wantSpace = false
|
||||
p.semiRsrv("}", x.Right, true)
|
||||
case x.MirBSDReplyVar:
|
||||
p.WriteString("${|")
|
||||
p.nestedStmts(x.Stmts, x.Right)
|
||||
p.wantSpace = false
|
||||
p.semiRsrv("}", x.Right, true)
|
||||
default:
|
||||
p.WriteString("$(")
|
||||
p.wantSpace = len(x.Stmts) > 0 && startsWithLparen(x.Stmts[0])
|
||||
p.nestedStmts(x.Stmts, x.Right)
|
||||
p.sepTok(")", x.Right)
|
||||
}
|
||||
case *ParamExp:
|
||||
p.paramExp(x)
|
||||
case *ArithmExp:
|
||||
p.WriteString("$((")
|
||||
if x.Unsigned {
|
||||
p.WriteString("# ")
|
||||
}
|
||||
p.arithmExpr(x.X, false, false)
|
||||
p.WriteString("))")
|
||||
case *ExtGlob:
|
||||
@ -326,12 +331,38 @@ func (p *Printer) wordPart(wp WordPart) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Printer) dblQuoted(dq *DblQuoted) {
|
||||
if dq.Dollar {
|
||||
p.WriteByte('$')
|
||||
}
|
||||
p.WriteByte('"')
|
||||
for i, n := range dq.Parts {
|
||||
p.wordPart(n)
|
||||
if i == len(dq.Parts)-1 {
|
||||
p.incLines(n.End())
|
||||
}
|
||||
}
|
||||
p.WriteByte('"')
|
||||
}
|
||||
|
||||
func (p *Printer) wroteIndex(index ArithmExpr, key *DblQuoted) bool {
|
||||
if index == nil && key == nil {
|
||||
return false
|
||||
}
|
||||
p.WriteByte('[')
|
||||
if index != nil {
|
||||
p.arithmExpr(index, false, false)
|
||||
} else {
|
||||
p.dblQuoted(key)
|
||||
}
|
||||
p.WriteByte(']')
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *Printer) paramExp(pe *ParamExp) {
|
||||
if pe.nakedIndex() { // arr[i]
|
||||
if pe.nakedIndex() { // arr[x]
|
||||
p.WriteString(pe.Param.Value)
|
||||
p.WriteByte('[')
|
||||
p.arithmExpr(pe.Index, false, false)
|
||||
p.WriteByte(']')
|
||||
p.wroteIndex(pe.Index, pe.Key)
|
||||
return
|
||||
}
|
||||
if pe.Short { // $var
|
||||
@ -344,17 +375,15 @@ func (p *Printer) paramExp(pe *ParamExp) {
|
||||
switch {
|
||||
case pe.Length:
|
||||
p.WriteByte('#')
|
||||
case pe.Width:
|
||||
p.WriteByte('%')
|
||||
case pe.Indirect:
|
||||
p.WriteByte('!')
|
||||
}
|
||||
if pe.Param != nil {
|
||||
p.WriteString(pe.Param.Value)
|
||||
}
|
||||
if pe.Index != nil {
|
||||
p.WriteByte('[')
|
||||
p.arithmExpr(pe.Index, false, false)
|
||||
p.WriteByte(']')
|
||||
}
|
||||
p.wroteIndex(pe.Index, pe.Key)
|
||||
if pe.Slice != nil {
|
||||
p.WriteByte(':')
|
||||
p.arithmExpr(pe.Slice.Offset, true, true)
|
||||
@ -367,12 +396,18 @@ func (p *Printer) paramExp(pe *ParamExp) {
|
||||
p.WriteByte('/')
|
||||
}
|
||||
p.WriteByte('/')
|
||||
p.word(pe.Repl.Orig)
|
||||
if pe.Repl.Orig != nil {
|
||||
p.word(pe.Repl.Orig)
|
||||
}
|
||||
p.WriteByte('/')
|
||||
p.word(pe.Repl.With)
|
||||
if pe.Repl.With != nil {
|
||||
p.word(pe.Repl.With)
|
||||
}
|
||||
} else if pe.Exp != nil {
|
||||
p.WriteString(pe.Exp.Op.String())
|
||||
p.word(pe.Exp.Word)
|
||||
if pe.Exp.Word != nil {
|
||||
p.word(pe.Exp.Word)
|
||||
}
|
||||
}
|
||||
p.WriteByte('}')
|
||||
}
|
||||
@ -381,9 +416,9 @@ func (p *Printer) loop(loop Loop) {
|
||||
switch x := loop.(type) {
|
||||
case *WordIter:
|
||||
p.WriteString(x.Name.Value)
|
||||
if len(x.List) > 0 {
|
||||
if len(x.Items) > 0 {
|
||||
p.spacedString(" in")
|
||||
p.wordJoin(x.List, true)
|
||||
p.wordJoin(x.Items)
|
||||
}
|
||||
case *CStyleLoop:
|
||||
p.WriteString("((")
|
||||
@ -401,10 +436,8 @@ func (p *Printer) loop(loop Loop) {
|
||||
|
||||
func (p *Printer) arithmExpr(expr ArithmExpr, compact, spacePlusMinus bool) {
|
||||
switch x := expr.(type) {
|
||||
case *Lit:
|
||||
p.WriteString(x.Value)
|
||||
case *ParamExp:
|
||||
p.paramExp(x)
|
||||
case *Word:
|
||||
p.word(x)
|
||||
case *BinaryArithm:
|
||||
if compact {
|
||||
p.arithmExpr(x.X, compact, spacePlusMinus)
|
||||
@ -491,17 +524,12 @@ func (p *Printer) unquotedWord(w *Word) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Printer) wordJoin(ws []*Word, backslash bool) {
|
||||
func (p *Printer) wordJoin(ws []*Word) {
|
||||
anyNewline := false
|
||||
for _, w := range ws {
|
||||
if pos := w.Pos(); pos > p.nline {
|
||||
p.commentsUpTo(pos)
|
||||
if backslash {
|
||||
p.bslashNewl()
|
||||
} else {
|
||||
p.WriteByte('\n')
|
||||
p.incLine()
|
||||
}
|
||||
p.bslashNewl()
|
||||
if !anyNewline {
|
||||
p.incLevel()
|
||||
anyNewline = true
|
||||
@ -518,11 +546,37 @@ func (p *Printer) wordJoin(ws []*Word, backslash bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Printer) elemJoin(elems []*ArrayElem) {
|
||||
anyNewline := false
|
||||
for _, el := range elems {
|
||||
if pos := el.Pos(); pos > p.nline {
|
||||
p.commentsUpTo(pos)
|
||||
p.WriteByte('\n')
|
||||
p.incLine()
|
||||
if !anyNewline {
|
||||
p.incLevel()
|
||||
anyNewline = true
|
||||
}
|
||||
p.indent()
|
||||
} else if p.wantSpace {
|
||||
p.WriteByte(' ')
|
||||
p.wantSpace = false
|
||||
}
|
||||
if p.wroteIndex(el.Index, el.Key) {
|
||||
p.WriteByte('=')
|
||||
}
|
||||
p.word(el.Value)
|
||||
}
|
||||
if anyNewline {
|
||||
p.decLevel()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Printer) stmt(s *Stmt) {
|
||||
if s.Negated {
|
||||
p.spacedString("!")
|
||||
}
|
||||
p.assigns(s.Assigns)
|
||||
p.assigns(s.Assigns, true)
|
||||
var startRedirs int
|
||||
if s.Cmd != nil {
|
||||
startRedirs = p.command(s.Cmd, s.Redirs)
|
||||
@ -545,21 +599,25 @@ func (p *Printer) stmt(s *Stmt) {
|
||||
p.WriteString(r.N.Value)
|
||||
}
|
||||
p.WriteString(r.Op.String())
|
||||
p.wantSpace = true
|
||||
p.word(r.Word)
|
||||
if r.Op == Hdoc || r.Op == DashHdoc {
|
||||
p.pendingHdocs = append(p.pendingHdocs, r)
|
||||
}
|
||||
}
|
||||
p.wroteSemi = false
|
||||
if s.Semicolon.IsValid() && s.Semicolon > p.nline {
|
||||
switch {
|
||||
case s.Semicolon.IsValid() && s.Semicolon > p.nline:
|
||||
p.incLevel()
|
||||
p.bslashNewl()
|
||||
p.indent()
|
||||
p.decLevel()
|
||||
p.WriteByte(';')
|
||||
p.wroteSemi = true
|
||||
} else if s.Background {
|
||||
case s.Background:
|
||||
p.WriteString(" &")
|
||||
case s.Coprocess:
|
||||
p.WriteString(" |&")
|
||||
}
|
||||
if anyNewline {
|
||||
p.decLevel()
|
||||
@ -574,10 +632,10 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
switch x := cmd.(type) {
|
||||
case *CallExpr:
|
||||
if len(x.Args) <= 1 {
|
||||
p.wordJoin(x.Args, true)
|
||||
p.wordJoin(x.Args)
|
||||
return 0
|
||||
}
|
||||
p.wordJoin(x.Args[:1], true)
|
||||
p.wordJoin(x.Args[:1])
|
||||
for _, r := range redirs {
|
||||
if r.Pos() > x.Args[1].Pos() || r.Op == Hdoc || r.Op == DashHdoc {
|
||||
break
|
||||
@ -589,10 +647,11 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
p.WriteString(r.N.Value)
|
||||
}
|
||||
p.WriteString(r.Op.String())
|
||||
p.wantSpace = true
|
||||
p.word(r.Word)
|
||||
startRedirs++
|
||||
}
|
||||
p.wordJoin(x.Args[1:], true)
|
||||
p.wordJoin(x.Args[1:])
|
||||
case *Block:
|
||||
p.WriteByte('{')
|
||||
p.wantSpace = true
|
||||
@ -639,13 +698,18 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
p.semiRsrv("done", x.Done, true)
|
||||
case *BinaryCmd:
|
||||
p.stmt(x.X)
|
||||
if x.Y.Pos() < p.nline {
|
||||
// leave p.nestedBinary untouched
|
||||
p.spacedString(x.Op.String())
|
||||
p.stmt(x.Y)
|
||||
break
|
||||
}
|
||||
indent := !p.nestedBinary
|
||||
if indent {
|
||||
p.incLevel()
|
||||
}
|
||||
_, p.nestedBinary = x.Y.Cmd.(*BinaryCmd)
|
||||
if p.binNextLine {
|
||||
if len(p.pendingHdocs) == 0 && x.Y.Pos() > p.nline {
|
||||
if len(p.pendingHdocs) == 0 {
|
||||
p.bslashNewl()
|
||||
p.indent()
|
||||
}
|
||||
@ -662,16 +726,15 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
} else {
|
||||
p.wantSpace = true
|
||||
p.spacedString(x.Op.String())
|
||||
if x.Y.Pos() > p.nline {
|
||||
if x.OpPos > p.nline {
|
||||
p.incLines(x.OpPos)
|
||||
}
|
||||
p.commentsUpTo(x.Y.Pos())
|
||||
p.newline(0)
|
||||
p.indent()
|
||||
if x.OpPos > p.nline {
|
||||
p.incLines(x.OpPos)
|
||||
}
|
||||
p.commentsUpTo(x.Y.Pos())
|
||||
p.newline(0)
|
||||
p.indent()
|
||||
}
|
||||
p.incLines(x.Y.Pos())
|
||||
_, p.nestedBinary = x.Y.Cmd.(*BinaryCmd)
|
||||
p.stmt(x.Y)
|
||||
if indent {
|
||||
p.decLevel()
|
||||
@ -689,10 +752,9 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
p.WriteString("case ")
|
||||
p.word(x.Word)
|
||||
p.WriteString(" in")
|
||||
p.incLevel()
|
||||
for _, pl := range x.List {
|
||||
p.commentsAndSeparate(pl.Patterns[0].Pos())
|
||||
for i, w := range pl.Patterns {
|
||||
for _, ci := range x.Items {
|
||||
p.commentsAndSeparate(ci.Patterns[0].Pos())
|
||||
for i, w := range ci.Patterns {
|
||||
if i > 0 {
|
||||
p.spacedString("|")
|
||||
}
|
||||
@ -703,24 +765,26 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
}
|
||||
p.WriteByte(')')
|
||||
p.wantSpace = true
|
||||
sep := len(pl.Stmts) > 1 || (len(pl.Stmts) > 0 && pl.Stmts[0].Pos() > p.nline)
|
||||
p.nestedStmts(pl.Stmts, 0)
|
||||
sep := len(ci.Stmts) > 1 || (len(ci.Stmts) > 0 && ci.Stmts[0].Pos() > p.nline)
|
||||
p.nestedStmts(ci.Stmts, 0)
|
||||
p.level++
|
||||
if sep {
|
||||
p.commentsUpTo(pl.OpPos)
|
||||
p.newlines(pl.OpPos)
|
||||
p.commentsUpTo(ci.OpPos)
|
||||
p.newlines(ci.OpPos)
|
||||
}
|
||||
p.spacedString(pl.Op.String())
|
||||
p.incLines(pl.OpPos)
|
||||
p.spacedString(ci.Op.String())
|
||||
p.incLines(ci.OpPos)
|
||||
p.level--
|
||||
if sep || pl.OpPos == x.Esac {
|
||||
if sep || ci.OpPos == x.Esac {
|
||||
p.wantNewline = true
|
||||
}
|
||||
}
|
||||
p.decLevel()
|
||||
p.semiRsrv("esac", x.Esac, len(x.List) == 0)
|
||||
p.semiRsrv("esac", x.Esac, len(x.Items) == 0)
|
||||
case *ArithmCmd:
|
||||
p.WriteString("((")
|
||||
if x.Unsigned {
|
||||
p.WriteString("# ")
|
||||
}
|
||||
p.arithmExpr(x.X, false, false)
|
||||
p.WriteString("))")
|
||||
case *TestClause:
|
||||
@ -728,16 +792,17 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
||||
p.testExpr(x.X)
|
||||
p.spacedString("]]")
|
||||
case *DeclClause:
|
||||
name := x.Variant
|
||||
if name == "" {
|
||||
name = "declare"
|
||||
}
|
||||
p.spacedString(name)
|
||||
p.spacedString(x.Variant)
|
||||
for _, w := range x.Opts {
|
||||
p.WriteByte(' ')
|
||||
p.word(w)
|
||||
}
|
||||
p.assigns(x.Assigns)
|
||||
p.assigns(x.Assigns, false)
|
||||
case *TimeClause:
|
||||
p.spacedString("time")
|
||||
if x.Stmt != nil {
|
||||
p.stmt(x.Stmt)
|
||||
}
|
||||
case *CoprocClause:
|
||||
p.spacedString("coproc")
|
||||
if x.Name != nil {
|
||||
@ -878,6 +943,7 @@ func (c *byteCounter) WriteString(s string) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
func (c *byteCounter) Reset(io.Writer) { *c = 0 }
|
||||
func (c *byteCounter) Flush() error { return nil }
|
||||
|
||||
// stmtCols reports the length that s will take when formatted in a
|
||||
// single line. If it will span multiple lines, stmtCols will return -1.
|
||||
@ -902,7 +968,7 @@ func (p *Printer) nestedStmts(stmts []*Stmt, closing Pos) {
|
||||
p.decLevel()
|
||||
}
|
||||
|
||||
func (p *Printer) assigns(assigns []*Assign) {
|
||||
func (p *Printer) assigns(assigns []*Assign, alwaysEqual bool) {
|
||||
anyNewline := false
|
||||
for _, a := range assigns {
|
||||
if a.Pos() > p.nline {
|
||||
@ -917,22 +983,20 @@ func (p *Printer) assigns(assigns []*Assign) {
|
||||
}
|
||||
if a.Name != nil {
|
||||
p.WriteString(a.Name.Value)
|
||||
if a.Index != nil {
|
||||
p.WriteByte('[')
|
||||
p.arithmExpr(a.Index, false, false)
|
||||
p.WriteByte(']')
|
||||
}
|
||||
p.wroteIndex(a.Index, a.Key)
|
||||
if a.Append {
|
||||
p.WriteByte('+')
|
||||
}
|
||||
p.WriteByte('=')
|
||||
if alwaysEqual || a.Value != nil || a.Array != nil {
|
||||
p.WriteByte('=')
|
||||
}
|
||||
}
|
||||
if a.Value != nil {
|
||||
p.word(a.Value)
|
||||
} else if a.Array != nil {
|
||||
p.wantSpace = false
|
||||
p.WriteByte('(')
|
||||
p.wordJoin(a.Array.List, false)
|
||||
p.elemJoin(a.Array.Elems)
|
||||
p.sepTok(")", a.Array.Rparen)
|
||||
}
|
||||
p.wantSpace = true
|
||||
|
6
vendor/github.com/mvdan/sh/syntax/token_string.go
generated
vendored
6
vendor/github.com/mvdan/sh/syntax/token_string.go
generated
vendored
@ -1,12 +1,12 @@
|
||||
// Code generated by "stringer -type token"; DO NOT EDIT
|
||||
// Code generated by "stringer -type token -linecoms"; DO NOT EDIT.
|
||||
|
||||
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 = "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?(*(+(@(!("
|
||||
|
||||
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, 74, 76, 78, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 108, 111, 112, 114, 115, 117, 119, 121, 123, 125, 128, 131, 133, 136, 138, 140, 141, 143, 144, 146, 147, 149, 150, 152, 153, 155, 156, 158, 159, 161, 162, 164, 165, 166, 168, 169, 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, 222, 225, 228, 231, 234, 237, 240, 243, 246, 248, 250, 252, 254, 256}
|
||||
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}
|
||||
|
||||
func (i token) String() string {
|
||||
if i >= token(len(_token_index)-1) {
|
||||
|
33
vendor/github.com/mvdan/sh/syntax/tokens.go
generated
vendored
33
vendor/github.com/mvdan/sh/syntax/tokens.go
generated
vendored
@ -8,25 +8,26 @@ type token uint32
|
||||
// Modified version of golang.org/x/tools/cmd/stringer that gets the
|
||||
// string value from the inline comment of each constant, if there is
|
||||
// one. Also removes leading '_'.
|
||||
//go:generate stringer -type token
|
||||
//go:generate stringer -type token -linecoms
|
||||
|
||||
// The list of all possible tokens.
|
||||
const (
|
||||
illegalTok token = iota
|
||||
_EOF
|
||||
_Lit
|
||||
_LitWord
|
||||
_LitRedir
|
||||
|
||||
_EOF // EOF
|
||||
_Lit // Lit
|
||||
_LitWord // LitWord
|
||||
_LitRedir // LitRedir
|
||||
|
||||
sglQuote // '
|
||||
dblQuote // "
|
||||
bckQuote // `
|
||||
|
||||
and // &
|
||||
andAnd // &&
|
||||
orOr // ||
|
||||
or // |
|
||||
pipeAll // |&
|
||||
and // &
|
||||
andAnd // &&
|
||||
orOr // ||
|
||||
or // |
|
||||
orAnd // |&
|
||||
|
||||
dollar // $
|
||||
dollSglQuote // $'
|
||||
@ -46,8 +47,9 @@ const (
|
||||
semicolon // ;
|
||||
|
||||
dblSemicolon // ;;
|
||||
semiFall // ;&
|
||||
dblSemiFall // ;;&
|
||||
semiAnd // ;&
|
||||
dblSemiAnd // ;;&
|
||||
semiOr // ;|
|
||||
|
||||
exclMark // !
|
||||
addAdd // ++
|
||||
@ -196,9 +198,10 @@ const (
|
||||
type CaseOperator token
|
||||
|
||||
const (
|
||||
DblSemicolon = CaseOperator(dblSemicolon) + iota
|
||||
SemiFall
|
||||
DblSemiFall
|
||||
Break = CaseOperator(dblSemicolon) + iota
|
||||
Fallthrough
|
||||
Resume
|
||||
ResumeKorn
|
||||
)
|
||||
|
||||
type ParExpOperator token
|
||||
|
39
vendor/github.com/mvdan/sh/syntax/walk.go
generated
vendored
39
vendor/github.com/mvdan/sh/syntax/walk.go
generated
vendored
@ -79,7 +79,7 @@ func Walk(node Node, f func(Node) bool) {
|
||||
walkStmts(x.DoStmts, f)
|
||||
case *WordIter:
|
||||
Walk(x.Name, f)
|
||||
walkWords(x.List, f)
|
||||
walkWords(x.Items, f)
|
||||
case *CStyleLoop:
|
||||
if x.Init != nil {
|
||||
Walk(x.Init, f)
|
||||
@ -116,20 +116,20 @@ func Walk(node Node, f func(Node) bool) {
|
||||
Walk(x.Index, f)
|
||||
}
|
||||
if x.Repl != nil {
|
||||
Walk(x.Repl.Orig, f)
|
||||
Walk(x.Repl.With, f)
|
||||
if x.Repl.Orig != nil {
|
||||
Walk(x.Repl.Orig, f)
|
||||
}
|
||||
if x.Repl.With != nil {
|
||||
Walk(x.Repl.With, f)
|
||||
}
|
||||
}
|
||||
if x.Exp != nil {
|
||||
if x.Exp != nil && x.Exp.Word != nil {
|
||||
Walk(x.Exp.Word, f)
|
||||
}
|
||||
case *ArithmExp:
|
||||
if x.X != nil {
|
||||
Walk(x.X, f)
|
||||
}
|
||||
Walk(x.X, f)
|
||||
case *ArithmCmd:
|
||||
if x.X != nil {
|
||||
Walk(x.X, f)
|
||||
}
|
||||
Walk(x.X, f)
|
||||
case *BinaryArithm:
|
||||
Walk(x.X, f)
|
||||
Walk(x.Y, f)
|
||||
@ -146,9 +146,9 @@ func Walk(node Node, f func(Node) bool) {
|
||||
Walk(x.X, f)
|
||||
case *CaseClause:
|
||||
Walk(x.Word, f)
|
||||
for _, pl := range x.List {
|
||||
walkWords(pl.Patterns, f)
|
||||
walkStmts(pl.Stmts, f)
|
||||
for _, ci := range x.Items {
|
||||
walkWords(ci.Patterns, f)
|
||||
walkStmts(ci.Stmts, f)
|
||||
}
|
||||
case *TestClause:
|
||||
Walk(x.X, f)
|
||||
@ -158,11 +158,22 @@ func Walk(node Node, f func(Node) bool) {
|
||||
Walk(a, f)
|
||||
}
|
||||
case *ArrayExpr:
|
||||
walkWords(x.List, f)
|
||||
for _, el := range x.Elems {
|
||||
Walk(el, f)
|
||||
}
|
||||
case *ArrayElem:
|
||||
if x.Index != nil {
|
||||
Walk(x.Index, f)
|
||||
}
|
||||
Walk(x.Value, f)
|
||||
case *ExtGlob:
|
||||
Walk(x.Pattern, f)
|
||||
case *ProcSubst:
|
||||
walkStmts(x.Stmts, f)
|
||||
case *TimeClause:
|
||||
if x.Stmt != nil {
|
||||
Walk(x.Stmt, f)
|
||||
}
|
||||
case *CoprocClause:
|
||||
if x.Name != nil {
|
||||
Walk(x.Name, f)
|
||||
|
12
vendor/vendor.json
vendored
12
vendor/vendor.json
vendored
@ -51,16 +51,16 @@
|
||||
"revisionTime": "2017-01-24T11:57:57Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "ohm6oyTSFu/xZk5HtTUG7RIONO4=",
|
||||
"checksumSHA1": "dZOPdDhOrEZfccmKxqRLsbCwm6g=",
|
||||
"path": "github.com/mvdan/sh/interp",
|
||||
"revision": "380eaf2df0412887a2240f5b15e76ac810ca2e71",
|
||||
"revisionTime": "2017-05-17T16:44:15Z"
|
||||
"revision": "27fa62d749f4f87716626413e5960586c91e36f9",
|
||||
"revisionTime": "2017-05-26T14:37:19Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "2OcfNJuStj/eAcEPW5yRdU02DCc=",
|
||||
"checksumSHA1": "vGslbhw/1KheACSg3CayaaKY6DA=",
|
||||
"path": "github.com/mvdan/sh/syntax",
|
||||
"revision": "380eaf2df0412887a2240f5b15e76ac810ca2e71",
|
||||
"revisionTime": "2017-05-17T16:44:15Z"
|
||||
"revision": "27fa62d749f4f87716626413e5960586c91e36f9",
|
||||
"revisionTime": "2017-05-26T14:37:19Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "HUXE+Nrcau8FSaVEvPYHMvDjxOE=",
|
||||
|
Loading…
x
Reference in New Issue
Block a user