mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-04-26 13:34:45 +00:00
envsubst vendor fix
This commit is contained in:
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
86
vendor/github.com/drone/envsubst/parse/node.go
generated
vendored
Normal 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
371
vendor/github.com/drone/envsubst/parse/parse.go
generated
vendored
Normal 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
275
vendor/github.com/drone/envsubst/parse/scan.go
generated
vendored
Normal 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
6
vendor/vendor.json
vendored
|
@ -59,6 +59,12 @@
|
||||||
"revision": "3e65ae5fd2d944d56fdf52cb3f887247498d50e9",
|
"revision": "3e65ae5fd2d944d56fdf52cb3f887247498d50e9",
|
||||||
"revisionTime": "2017-01-18T15:01:55Z"
|
"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",
|
"path": "github.com/eknkc/amber",
|
||||||
"revision": "144da19a9994994c069f0693294a66dd310e14a4",
|
"revision": "144da19a9994994c069f0693294a66dd310e14a4",
|
||||||
|
|
Loading…
Reference in a new issue