mirror of
https://github.com/go-task/task.git
synced 2024-12-16 10:59:23 +02:00
f6c5a46626
Fixes #250
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
// Copyright (c) 2018, Daniel Martí <mvdan@mvdan.cc>
|
|
// See LICENSE for licensing information
|
|
|
|
package expand
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"mvdan.cc/sh/v3/syntax"
|
|
)
|
|
|
|
// Braces performs brace expansion on a word, given that it contains any
|
|
// syntax.BraceExp parts. For example, the word with a brace expansion
|
|
// "foo{bar,baz}" will return two literal words, "foobar" and "foobaz".
|
|
//
|
|
// Note that the resulting words may share word parts.
|
|
func Braces(word *syntax.Word) []*syntax.Word {
|
|
var all []*syntax.Word
|
|
var left []syntax.WordPart
|
|
for i, wp := range word.Parts {
|
|
br, ok := wp.(*syntax.BraceExp)
|
|
if !ok {
|
|
left = append(left, wp.(syntax.WordPart))
|
|
continue
|
|
}
|
|
if br.Sequence {
|
|
var from, to int
|
|
if br.Chars {
|
|
from = int(br.Elems[0].Lit()[0])
|
|
to = int(br.Elems[1].Lit()[0])
|
|
} else {
|
|
from, _ = strconv.Atoi(br.Elems[0].Lit())
|
|
to, _ = strconv.Atoi(br.Elems[1].Lit())
|
|
}
|
|
upward := from <= to
|
|
incr := 1
|
|
if !upward {
|
|
incr = -1
|
|
}
|
|
if len(br.Elems) > 2 {
|
|
n, _ := strconv.Atoi(br.Elems[2].Lit())
|
|
if n != 0 && n > 0 == upward {
|
|
incr = n
|
|
}
|
|
}
|
|
n := from
|
|
for {
|
|
if upward && n > to {
|
|
break
|
|
}
|
|
if !upward && n < to {
|
|
break
|
|
}
|
|
next := *word
|
|
next.Parts = next.Parts[i+1:]
|
|
lit := &syntax.Lit{}
|
|
if br.Chars {
|
|
lit.Value = string(n)
|
|
} else {
|
|
lit.Value = strconv.Itoa(n)
|
|
}
|
|
next.Parts = append([]syntax.WordPart{lit}, next.Parts...)
|
|
exp := Braces(&next)
|
|
for _, w := range exp {
|
|
w.Parts = append(left, w.Parts...)
|
|
}
|
|
all = append(all, exp...)
|
|
n += incr
|
|
}
|
|
return all
|
|
}
|
|
for _, elem := range br.Elems {
|
|
next := *word
|
|
next.Parts = next.Parts[i+1:]
|
|
next.Parts = append(elem.Parts, next.Parts...)
|
|
exp := Braces(&next)
|
|
for _, w := range exp {
|
|
w.Parts = append(left, w.Parts...)
|
|
}
|
|
all = append(all, exp...)
|
|
}
|
|
return all
|
|
}
|
|
return []*syntax.Word{{Parts: left}}
|
|
}
|