mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 18:38:06 -04:00 
			
		
		
		
	* Fix validate() function to handle errors in embedded anon structs * Implement webhook branch filter See #2025, #3998.
		
			
				
	
	
		
			158 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package ast
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"fmt"
 | |
| 	"github.com/gobwas/glob/syntax/lexer"
 | |
| 	"unicode/utf8"
 | |
| )
 | |
| 
 | |
| type Lexer interface {
 | |
| 	Next() lexer.Token
 | |
| }
 | |
| 
 | |
| type parseFn func(*Node, Lexer) (parseFn, *Node, error)
 | |
| 
 | |
| func Parse(lexer Lexer) (*Node, error) {
 | |
| 	var parser parseFn
 | |
| 
 | |
| 	root := NewNode(KindPattern, nil)
 | |
| 
 | |
| 	var (
 | |
| 		tree *Node
 | |
| 		err  error
 | |
| 	)
 | |
| 	for parser, tree = parserMain, root; parser != nil; {
 | |
| 		parser, tree, err = parser(tree, lexer)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return root, nil
 | |
| }
 | |
| 
 | |
| func parserMain(tree *Node, lex Lexer) (parseFn, *Node, error) {
 | |
| 	for {
 | |
| 		token := lex.Next()
 | |
| 		switch token.Type {
 | |
| 		case lexer.EOF:
 | |
| 			return nil, tree, nil
 | |
| 
 | |
| 		case lexer.Error:
 | |
| 			return nil, tree, errors.New(token.Raw)
 | |
| 
 | |
| 		case lexer.Text:
 | |
| 			Insert(tree, NewNode(KindText, Text{token.Raw}))
 | |
| 			return parserMain, tree, nil
 | |
| 
 | |
| 		case lexer.Any:
 | |
| 			Insert(tree, NewNode(KindAny, nil))
 | |
| 			return parserMain, tree, nil
 | |
| 
 | |
| 		case lexer.Super:
 | |
| 			Insert(tree, NewNode(KindSuper, nil))
 | |
| 			return parserMain, tree, nil
 | |
| 
 | |
| 		case lexer.Single:
 | |
| 			Insert(tree, NewNode(KindSingle, nil))
 | |
| 			return parserMain, tree, nil
 | |
| 
 | |
| 		case lexer.RangeOpen:
 | |
| 			return parserRange, tree, nil
 | |
| 
 | |
| 		case lexer.TermsOpen:
 | |
| 			a := NewNode(KindAnyOf, nil)
 | |
| 			Insert(tree, a)
 | |
| 
 | |
| 			p := NewNode(KindPattern, nil)
 | |
| 			Insert(a, p)
 | |
| 
 | |
| 			return parserMain, p, nil
 | |
| 
 | |
| 		case lexer.Separator:
 | |
| 			p := NewNode(KindPattern, nil)
 | |
| 			Insert(tree.Parent, p)
 | |
| 
 | |
| 			return parserMain, p, nil
 | |
| 
 | |
| 		case lexer.TermsClose:
 | |
| 			return parserMain, tree.Parent.Parent, nil
 | |
| 
 | |
| 		default:
 | |
| 			return nil, tree, fmt.Errorf("unexpected token: %s", token)
 | |
| 		}
 | |
| 	}
 | |
| 	return nil, tree, fmt.Errorf("unknown error")
 | |
| }
 | |
| 
 | |
| func parserRange(tree *Node, lex Lexer) (parseFn, *Node, error) {
 | |
| 	var (
 | |
| 		not   bool
 | |
| 		lo    rune
 | |
| 		hi    rune
 | |
| 		chars string
 | |
| 	)
 | |
| 	for {
 | |
| 		token := lex.Next()
 | |
| 		switch token.Type {
 | |
| 		case lexer.EOF:
 | |
| 			return nil, tree, errors.New("unexpected end")
 | |
| 
 | |
| 		case lexer.Error:
 | |
| 			return nil, tree, errors.New(token.Raw)
 | |
| 
 | |
| 		case lexer.Not:
 | |
| 			not = true
 | |
| 
 | |
| 		case lexer.RangeLo:
 | |
| 			r, w := utf8.DecodeRuneInString(token.Raw)
 | |
| 			if len(token.Raw) > w {
 | |
| 				return nil, tree, fmt.Errorf("unexpected length of lo character")
 | |
| 			}
 | |
| 			lo = r
 | |
| 
 | |
| 		case lexer.RangeBetween:
 | |
| 			//
 | |
| 
 | |
| 		case lexer.RangeHi:
 | |
| 			r, w := utf8.DecodeRuneInString(token.Raw)
 | |
| 			if len(token.Raw) > w {
 | |
| 				return nil, tree, fmt.Errorf("unexpected length of lo character")
 | |
| 			}
 | |
| 
 | |
| 			hi = r
 | |
| 
 | |
| 			if hi < lo {
 | |
| 				return nil, tree, fmt.Errorf("hi character '%s' should be greater than lo '%s'", string(hi), string(lo))
 | |
| 			}
 | |
| 
 | |
| 		case lexer.Text:
 | |
| 			chars = token.Raw
 | |
| 
 | |
| 		case lexer.RangeClose:
 | |
| 			isRange := lo != 0 && hi != 0
 | |
| 			isChars := chars != ""
 | |
| 
 | |
| 			if isChars == isRange {
 | |
| 				return nil, tree, fmt.Errorf("could not parse range")
 | |
| 			}
 | |
| 
 | |
| 			if isRange {
 | |
| 				Insert(tree, NewNode(KindRange, Range{
 | |
| 					Lo:  lo,
 | |
| 					Hi:  hi,
 | |
| 					Not: not,
 | |
| 				}))
 | |
| 			} else {
 | |
| 				Insert(tree, NewNode(KindList, List{
 | |
| 					Chars: chars,
 | |
| 					Not:   not,
 | |
| 				}))
 | |
| 			}
 | |
| 
 | |
| 			return parserMain, tree, nil
 | |
| 		}
 | |
| 	}
 | |
| }
 |