envsubst vendor fix

This commit is contained in:
Brad Rydzewski 2017-01-18 22:06:01 +07:00
parent a03e962c2a
commit 2bb64949d1
4 changed files with 738 additions and 0 deletions

86
vendor/github.com/drone/envsubst/parse/node.go generated vendored Normal file
View file

@ -0,0 +1,86 @@
package parse
// Node is an element in the parse tree.
type Node interface {
node()
}
// empty string node
var empty = new(TextNode)
// a template is represented by a tree consisting of one
// or more of the following nodes.
type (
// TextNode represents a string of text.
TextNode struct {
Value string
}
// FuncNode represents a string function.
FuncNode struct {
Param string
Name string
Args []Node
}
// ListNode represents a list of nodes.
ListNode struct {
Nodes []Node
}
// ParamNode struct{
// Name string
// }
//
// CaseNode struct {
// Name string
// First bool
// }
//
// LowerNode struct {
// Name string
// First bool
// }
//
// SubstrNode struct {
// Name string
// Pos Node
// Len Node
// }
//
// ReplaceNode struct {
// Name string
// Substring Node
// Replacement Node
// }
//
// TrimNode struct{
//
// }
//
// DefaultNode struct {
// Name string
// Default Node
// }
)
// newTextNode returns a new TextNode.
func newTextNode(text string) *TextNode {
return &TextNode{Value: text}
}
// newListNode returns a new ListNode.
func newListNode(nodes ...Node) *ListNode {
return &ListNode{Nodes: nodes}
}
// newFuncNode returns a new FuncNode.
func newFuncNode(name string) *FuncNode {
return &FuncNode{Param: name}
}
// node() defines the node in a parse tree
func (*TextNode) node() {}
func (*ListNode) node() {}
func (*FuncNode) node() {}

371
vendor/github.com/drone/envsubst/parse/parse.go generated vendored Normal file
View file

@ -0,0 +1,371 @@
package parse
import "errors"
// ErrBadSubstitution represents a substitution parsing error.
var ErrBadSubstitution = errors.New("bad substitution")
// Tree is the representation of a single parsed SQL statement.
type Tree struct {
Root Node
// Parsing only; cleared after parse.
scanner *scanner
}
// Parse parses the string and returns a Tree.
func Parse(buf string) (*Tree, error) {
t := new(Tree)
t.scanner = new(scanner)
return t.Parse(buf)
}
// Parse parses the string buffer to construct an ast
// representation for expansion.
func (t *Tree) Parse(buf string) (tree *Tree, err error) {
t.scanner.init(buf)
t.Root, err = t.parseAny()
return t, err
}
func (t *Tree) parseAny() (Node, error) {
t.scanner.accept = acceptRune
t.scanner.mode = scanIdent | scanLbrack
switch t.scanner.scan() {
case tokenIdent:
left := newTextNode(
t.scanner.string(),
)
right, err := t.parseAny()
switch {
case err != nil:
return nil, err
case right == empty:
return left, nil
}
return newListNode(left, right), nil
case tokenEOF:
return empty, nil
case tokenLbrack:
left, err := t.parseFunc()
if err != nil {
return nil, err
}
right, err := t.parseAny()
switch {
case err != nil:
return nil, err
case right == empty:
return left, nil
}
return newListNode(left, right), nil
}
return nil, ErrBadSubstitution
}
func (t *Tree) parseFunc() (Node, error) {
switch t.scanner.peek() {
case '#':
return t.parseLenFunc()
}
var name string
t.scanner.accept = acceptIdent
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
switch t.scanner.peek() {
case ':':
return t.parseDefaultOrSubstr(name)
case '=':
return t.parseDefaultFunc(name)
case ',', '^':
return t.parseCasingFunc(name)
case '/':
return t.parseReplaceFunc(name)
case '#':
return t.parseRemoveFunc(name, acceptHashFunc)
case '%':
return t.parseRemoveFunc(name, acceptPercentFunc)
}
t.scanner.accept = acceptIdent
t.scanner.mode = scanRbrack
switch t.scanner.scan() {
case tokenRbrack:
return newFuncNode(name), nil
default:
return nil, ErrBadSubstitution
}
}
// parse a substitution function parameter.
func (t *Tree) parseParam(accept acceptFunc, mode byte) (Node, error) {
t.scanner.accept = accept
t.scanner.mode = mode | scanLbrack
switch t.scanner.scan() {
case tokenLbrack:
return t.parseFunc()
case tokenIdent:
return newTextNode(
t.scanner.string(),
), nil
default:
return nil, ErrBadSubstitution
}
}
// parse either a default or substring substitution function.
func (t *Tree) parseDefaultOrSubstr(name string) (Node, error) {
t.scanner.read()
r := t.scanner.peek()
t.scanner.unread()
switch r {
case '=', '-', '?', '+':
return t.parseDefaultFunc(name)
default:
return t.parseSubstrFunc(name)
}
}
// parses the ${param:offset} string function
// parses the ${param:offset:length} string function
func (t *Tree) parseSubstrFunc(name string) (Node, error) {
node := new(FuncNode)
node.Param = name
t.scanner.accept = acceptOneColon
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
// scan arg[1]
{
param, err := t.parseParam(rejectColonClose, scanIdent)
if err != nil {
return nil, err
}
// param.Value = t.scanner.string()
node.Args = append(node.Args, param)
}
// expect delimiter or close
t.scanner.accept = acceptColon
t.scanner.mode = scanIdent | scanRbrack
switch t.scanner.scan() {
case tokenRbrack:
return node, nil
case tokenIdent:
// no-op
default:
return nil, ErrBadSubstitution
}
// err := t.consumeDelimiter(acceptColon, scanIdent|scanRbrack)
// if err != nil {
// return nil, err
// }
// scan arg[2]
{
param, err := t.parseParam(acceptNotClosing, scanIdent)
if err != nil {
return nil, err
}
node.Args = append(node.Args, param)
}
return node, t.consumeRbrack()
}
// parses the ${param%word} string function
// parses the ${param%%word} string function
// parses the ${param#word} string function
// parses the ${param##word} string function
func (t *Tree) parseRemoveFunc(name string, accept acceptFunc) (Node, error) {
node := new(FuncNode)
node.Param = name
t.scanner.accept = accept
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
// scan arg[1]
{
param, err := t.parseParam(acceptNotClosing, scanIdent)
if err != nil {
return nil, err
}
// param.Value = t.scanner.string()
node.Args = append(node.Args, param)
}
return node, t.consumeRbrack()
}
// parses the ${param/pattern/string} string function
// parses the ${param//pattern/string} string function
// parses the ${param/#pattern/string} string function
// parses the ${param/%pattern/string} string function
func (t *Tree) parseReplaceFunc(name string) (Node, error) {
node := new(FuncNode)
node.Param = name
t.scanner.accept = acceptReplaceFunc
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
// scan arg[1]
{
param, err := t.parseParam(acceptNotSlash, scanIdent|scanEscape)
if err != nil {
return nil, err
}
node.Args = append(node.Args, param)
}
// expect delimiter
t.scanner.accept = acceptSlash
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
// no-op
default:
return nil, ErrBadSubstitution
}
{
param, err := t.parseParam(acceptNotClosing, scanIdent)
if err != nil {
return nil, err
}
node.Args = append(node.Args, param)
}
return node, t.consumeRbrack()
}
// parses the ${parameter=word} string function
// parses the ${parameter:=word} string function
// parses the ${parameter:-word} string function
// parses the ${parameter:?word} string function
// parses the ${parameter:+word} string function
func (t *Tree) parseDefaultFunc(name string) (Node, error) {
node := new(FuncNode)
node.Param = name
t.scanner.accept = acceptDefaultFunc
if t.scanner.peek() == '=' {
t.scanner.accept = acceptOneEqual
}
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
// scan arg[1]
{
param, err := t.parseParam(acceptNotClosing, scanIdent)
if err != nil {
return nil, err
}
// param.Value = t.scanner.string()
node.Args = append(node.Args, param)
}
return node, t.consumeRbrack()
}
// parses the ${param,} string function
// parses the ${param,,} string function
// parses the ${param^} string function
// parses the ${param^^} string function
func (t *Tree) parseCasingFunc(name string) (Node, error) {
node := new(FuncNode)
node.Param = name
t.scanner.accept = acceptCasingFunc
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
return node, t.consumeRbrack()
}
// parses the ${#param} string function
func (t *Tree) parseLenFunc() (Node, error) {
node := new(FuncNode)
t.scanner.accept = acceptOneHash
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Name = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
t.scanner.accept = acceptIdent
t.scanner.mode = scanIdent
switch t.scanner.scan() {
case tokenIdent:
node.Param = t.scanner.string()
default:
return nil, ErrBadSubstitution
}
return node, t.consumeRbrack()
}
// consumeRbrack consumes a right closing bracket. If a closing
// bracket token is not consumed an ErrBadSubstitution is returned.
func (t *Tree) consumeRbrack() error {
t.scanner.mode = scanRbrack
if t.scanner.scan() != tokenRbrack {
return ErrBadSubstitution
}
return nil
}
// consumeDelimiter consumes a function argument delimiter. If a
// delimiter is not consumed an ErrBadSubstitution is returned.
// func (t *Tree) consumeDelimiter(accept acceptFunc, mode uint) error {
// t.scanner.accept = accept
// t.scanner.mode = mode
// if t.scanner.scan() != tokenRbrack {
// return ErrBadSubstitution
// }
// return nil
// }

275
vendor/github.com/drone/envsubst/parse/scan.go generated vendored Normal file
View file

@ -0,0 +1,275 @@
package parse
import (
"unicode"
"unicode/utf8"
)
// eof rune sent when end of file is reached
var eof = rune(0)
// token is a lexical token.
type token uint
// list of lexical tokens.
const (
// special tokens
tokenIllegal token = iota
tokenEOF
// identifiers and literals
tokenIdent
// operators and delimiters
tokenLbrack
tokenRbrack
tokenQuote
)
// predefined mode bits to control recognition of tokens.
const (
scanIdent byte = 1 << iota
scanLbrack
scanRbrack
scanEscape
)
// returns true if rune is accepted.
type acceptFunc func(r rune, i int) bool
// scanner implements a lexical scanner that reads unicode
// characters and tokens from a string buffer.
type scanner struct {
buf string
pos int
start int
width int
mode byte
accept acceptFunc
}
// init initializes a scanner with a new buffer.
func (s *scanner) init(buf string) {
s.buf = buf
s.pos = 0
s.start = 0
s.width = 0
s.accept = nil
}
// read returns the next unicode character. It returns eof at
// the end of the string buffer.
func (s *scanner) read() rune {
if s.pos >= len(s.buf) {
s.width = 0
return eof
}
r, w := utf8.DecodeRuneInString(s.buf[s.pos:])
s.width = w
s.pos += s.width
return r
}
func (s *scanner) unread() {
s.pos -= s.width
}
// skip skips over the curring unicode character in the buffer
// by slicing and removing from the buffer.
func (s *scanner) skip() {
l := s.buf[:s.pos-1]
r := s.buf[s.pos:]
s.buf = l + r
}
// peek returns the next unicode character in the buffer without
// advancing the scanner. It returns eof if the scanner's position
// is at the last character of the source.
func (s *scanner) peek() rune {
r := s.read()
s.unread()
return r
}
// string returns the string corresponding to the most recently
// scanned token. Valid after calling scan().
func (s *scanner) string() string {
return s.buf[s.start:s.pos]
}
// scan reads the next token or Unicode character from source and
// returns it. It returns EOF at the end of the source.
func (s *scanner) scan() token {
s.start = s.pos
r := s.read()
switch {
case r == eof:
return tokenEOF
case s.scanLbrack(r):
return tokenLbrack
case s.scanRbrack(r):
return tokenRbrack
case s.scanIdent(r):
return tokenIdent
}
return tokenIllegal
}
// scanIdent reads the next token or Unicode character from source
// and returns true if the Ident character is accepted.
func (s *scanner) scanIdent(r rune) bool {
if s.mode&scanIdent == 0 {
return false
}
if s.scanEscaped(r) {
s.skip()
} else if !s.accept(r, s.pos-s.start) {
return false
}
loop:
for {
r := s.read()
switch {
case r == eof:
s.unread()
break loop
case s.scanLbrack(r):
s.unread()
s.unread()
break loop
}
if s.scanEscaped(r) {
s.skip()
continue
}
if !s.accept(r, s.pos-s.start) {
s.unread()
break loop
}
}
return true
}
// scanLbrack reads the next token or Unicode character from source
// and returns true if the open bracket is encountered.
func (s *scanner) scanLbrack(r rune) bool {
if s.mode&scanLbrack == 0 {
return false
}
if r == '$' {
if s.read() == '{' {
return true
}
s.unread()
}
return false
}
// scanRbrack reads the next token or Unicode character from source
// and returns true if the closing bracket is encountered.
func (s *scanner) scanRbrack(r rune) bool {
if s.mode&scanRbrack == 0 {
return false
}
return r == '}'
}
// scanEscaped reads the next token or Unicode character from source
// and returns true if it being escaped and should be sipped.
func (s *scanner) scanEscaped(r rune) bool {
if s.mode&scanEscape == 0 {
return false
}
if r != '\\' {
return false
}
switch s.peek() {
case '/', '\\':
return true
default:
return false
}
}
//
// scanner functions accept or reject runes.
//
func acceptRune(r rune, i int) bool {
return true
}
func acceptIdent(r rune, i int) bool {
return unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_'
}
func acceptColon(r rune, i int) bool {
return r == ':'
}
func acceptOneHash(r rune, i int) bool {
return r == '#' && i == 1
}
func acceptNone(r rune, i int) bool {
return false
}
func acceptNotClosing(r rune, i int) bool {
return r != '}'
}
func acceptHashFunc(r rune, i int) bool {
return r == '#' && i < 3
}
func acceptPercentFunc(r rune, i int) bool {
return r == '%' && i < 3
}
func acceptDefaultFunc(r rune, i int) bool {
switch {
case i == 1 && r == ':':
return true
case i == 2 && (r == '=' || r == '-' || r == '?' || r == '+'):
return true
default:
return false
}
}
func acceptReplaceFunc(r rune, i int) bool {
switch {
case i == 1 && r == '/':
return true
case i == 2 && (r == '/' || r == '#' || r == '%'):
return true
default:
return false
}
}
func acceptOneEqual(r rune, i int) bool {
return i == 1 && r == '='
}
func acceptOneColon(r rune, i int) bool {
return i == 1 && r == ':'
}
func rejectColonClose(r rune, i int) bool {
return r != ':' && r != '}'
}
func acceptSlash(r rune, i int) bool {
return r == '/'
}
func acceptNotSlash(r rune, i int) bool {
return r != '/'
}
func acceptCasingFunc(r rune, i int) bool {
return (r == ',' || r == '^') && i < 3
}

6
vendor/vendor.json vendored
View file

@ -59,6 +59,12 @@
"revision": "3e65ae5fd2d944d56fdf52cb3f887247498d50e9",
"revisionTime": "2017-01-18T15:01:55Z"
},
{
"checksumSHA1": "LPKfsjm4AYVgCLVcAWnQdSpt5SA=",
"path": "github.com/drone/envsubst/parse",
"revision": "3e65ae5fd2d944d56fdf52cb3f887247498d50e9",
"revisionTime": "2017-01-18T15:01:55Z"
},
{
"path": "github.com/eknkc/amber",
"revision": "144da19a9994994c069f0693294a66dd310e14a4",