// pattern returns all runes representing a file or path pattern, delimited
// either by unescaped whitespace, a path separator '/' or enf of file. An
// error is returned if a problem is encountered reading from the stream.
350044
func (l *lexer) pattern() ([]rune, Error) {
	// read until we hit the first whitespace/end of line/eof rune
	_pattern := make([]rune, 0, 1)

	// loop until there's nothing more to do
	for {
		_r, _err := l.read()
		if _err != nil {
			return _pattern, _err
		}

		// what is the next rune?
		switch _r {
		// whitespace, newline, end of file, separator
		//		- this is the end of the pattern
		case _SPACE:
			fallthrough
		case _TAB:
			fallthrough
		case _CR:
			fallthrough
		case _NEWLINE:
			fallthrough
		case _SEPARATOR:
			fallthrough
		case _EOF:
			// return what we have
			l.unread(_r)
			return _pattern, nil

		// a wildcard is the end of the pattern if it is part of any '**'
		case _WILDCARD:
			_next, _err := l.peek()
			if _err != nil {
				return _pattern, _err
			} else if _next == _WILDCARD {
				l.unread(_r)
				return _pattern, _err
			} else {
				_pattern = append(_pattern, _r)
			}

		// escape sequence - consume the next rune
		case _ESCAPE:
			_escape, _err := l.escape()
			if _err != nil {
				return _pattern, _err
			}

			// add the escape sequence as part of the pattern
			_pattern = append(_pattern, _escape...)

		// any other character, we add to the pattern
		default:
			_pattern = append(_pattern, _r)
		}
	}
}
773115
func (p *pattern) path(tokens []*Token) Pattern {
	// how many directory components are we expecting?
	_depth := 0
	for _, _token := range tokens {
		if _token.Type == SEPARATOR {
			_depth++
		}
	}

	// return the pattern instance
	return &path{pattern: *p, _depth: _depth}
}
501468
func Matches(file string, patterns []string) (bool, error) {
	file = filepath.Clean(file)

	if file == "." {
		// Don't let them exclude everything, kind of silly.
		return false, nil
	}

	patterns, patDirs, _, err := cleanPatterns(patterns)
	if err != nil {
		return false, err
	}

	return optimizedMatches(file, patterns, patDirs)
}
713971
func Pattern(path, in, data, pattern string) *errors.Validation {
	re, err := compileRegexp(pattern)
	if err != nil {
		return errors.FailedPattern(path, in, fmt.Sprintf("%s, but pattern is invalid: %s", pattern, err.Error()))
	}
	if !re.MatchString(data) {
		return errors.FailedPattern(path, in, pattern)
	}
	return nil
}
71450
func (pg *NativeFinder) FullPattern(pattern string) ([]PID, error) {
	var pids []PID
	procs, err := getWin32ProcsByVariable("CommandLine", like, pattern, Timeout)
	if err != nil {
		return pids, err
	}
	for _, p := range procs {
		pids = append(pids, PID(p.ProcessID))
	}
	return pids, nil
}
317698
func New(pat string) *Pattern {
	p := &Pattern{raw: pat}

	if strings.HasSuffix(pat, "/*") {
		pat = pat[:len(pat)-1]
		p.wildcard = true
	}

	matches := patternRe.FindAllStringSubmatchIndex(pat, -1)
	numMatches := len(matches)
	p.pats = make(patNames, numMatches)
	p.breaks = make([]byte, numMatches)
	p.literals = make([]string, numMatches+1)

	n := 0
	for i, match := range matches {
		a, b := match[2], match[3]
		p.literals[i] = pat[n : a-1] // Need to leave off the colon
		p.pats[i].name = pattern.Variable(pat[a:b])
		p.pats[i].idx = i
		if b == len(pat) {
			p.breaks[i] = '/'
		} else {
			p.breaks[i] = pat[b]
		}
		n = b
	}
	p.literals[numMatches] = pat[n:]

	sort.Sort(p.pats)

	return p
}
681807
func NewPattern(pattern string) Pattern {
	switch {
	case strings.HasPrefix(pattern, semverPrefix):
		pattern = strings.TrimPrefix(pattern, semverPrefix)
		c, _ := semver.NewConstraint(pattern)
		return SemverPattern{pattern, c}
	case strings.HasPrefix(pattern, regexpPrefix):
		pattern = strings.TrimPrefix(pattern, regexpPrefix)
		r, _ := regexp.Compile(pattern)
		return RegexpPattern{pattern, r}
	case strings.HasPrefix(pattern, regexpAltPrefix):
		pattern = strings.TrimPrefix(pattern, regexpAltPrefix)
		r, _ := regexp.Compile(pattern)
		return RegexpPattern{pattern, r}
	default:
		return GlobPattern(strings.TrimPrefix(pattern, globPrefix))
	}
}
1028249
func (c *patternCache) translate(pat string) (*regexp.Regexp, error) {
	c.RLock()
	val, ok := c.cache[pat]
	c.RUnlock()
	if ok {
		return val.re, val.err
	}

	c.Lock()
	defer c.Unlock()
	if val, ok := c.cache[pat]; ok {
		return val.re, val.err
	}

	if c.cache == nil || len(c.cache) > 500 {
		c.cache = map[string]cacheEntry{}
	}

	var re *regexp.Regexp
	reStr, err := translate(pat)
	if err == nil {
		re, err = regexp.Compile(reStr)
	}

	c.cache[pat] = cacheEntry{re, err}
	return re, err
}
67785
func treeCanMatchPattern(pattern string) func(name string) bool {
	wildCard := false
	if i := strings.Index(pattern, "..."); i >= 0 {
		wildCard = true
		pattern = pattern[:i]
	}
	return func(name string) bool {
		return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
			wildCard && strings.HasPrefix(name, pattern)
	}
}
884872
func Find(root string, pattern *regexp.Regexp) (paths []string) {
	if Exists(root) {
		filepath.Walk(root, func(path string, info os.FileInfo, e error) error {
			if pattern.MatchString(path) {
				paths = append(paths, info.Name())
			}
			return e
		})
	}
	return
}
1145519
func Handle(pattern string, fn interface{}) {
	elems := strings.Split(pattern, "/")
	n := len(elems)
	if n == 0 {
		panic("empty pattern")
	}
	if n >= 2 && elems[n-2] == "{" && strings.HasSuffix(elems[n-1], "}") {
		elems[n-2] += "/" + elems[n-1]
		n--
		elems = elems[:n]
	}

	var vars []string
	re := "^"
	for i, elem := range elems {
		if i > 0 {
			re += "/"
		}
		wildcard := false
		if strings.HasPrefix(elem, "{") && strings.HasSuffix(elem, "}") {
			elem = elem[1 : len(elem)-1]
			wildcard = true
		}
		if strings.ContainsAny(elem, "{}") {
			panic("invalid pattern: " + pattern)
		}
		if i == 0 {
			if wildcard {
				panic("wildcard not allowed for host")
			}
			if elem == "" {
				re += "[^/]*"
			} else {
				re += `(?:[^/]+\.)?` + regexp.QuoteMeta(elem)
			}
			continue
		}
		if wildcard {
			if i == len(elems)-1 && strings.HasPrefix(elem, "/") {
				elem = elem[1:]
				re += "(.*)"
			} else {
				re += "([^/]+)"
			}
			vars = append(vars, elem)
		} else {
			re += regexp.QuoteMeta(elem)
		}
	}
	re += "$"

	h := &handler{
		regexp.MustCompile(re),
		vars,
		nil,
		fn,
	}

	fmt.Printf("h %s\n", re)

	if len(vars) > 0 {
		h.isVar = make(map[string]bool)
		for _, v := range vars {
			h.isVar[v] = true
		}
	}

	handlers = append(handlers, h)
}
103512
func match(pattern, name string) bool {
	matched, _ := filepath.Match(pattern, name)
	return matched
}
214945
func patternMatch(str string, patChars, patTypes []byte) bool {
	return stringutil.DoMatch(str, patChars, patTypes)
}
415560
func (mux *ServeMux) match(path string) (h Handler, pattern string) {
	var n = 0
	for k, v := range mux.m {
		if !pathMatch(k, path) {
			continue
		}
		if h == nil || len(k) > n {
			n = len(k)
			h = v.h
			pattern = v.pattern
		}
	}
	return
}
721549
func Match(pattern, s string, flags int) bool {
	// The implementation for this function was patterned after the BSD fnmatch.c
	// source found at http://src.gnu-darwin.org/src/contrib/csup/fnmatch.c.html
	noescape := (flags&FNM_NOESCAPE != 0)
	pathname := (flags&FNM_PATHNAME != 0)
	period := (flags&FNM_PERIOD != 0)
	leadingdir := (flags&FNM_LEADING_DIR != 0)
	casefold := (flags&FNM_CASEFOLD != 0)
	// the following is some bookkeeping that the original fnmatch.c implementation did not do
	// We are forced to do this because we're not keeping indexes into C strings but rather
	// processing utf8-encoded strings. Use a custom unpacker to maintain our state for us
	sAtStart := true
	sLastAtStart := true
	sLastSlash := false
	sLastUnpacked := rune(0)
	unpackS := func() rune {
		sLastSlash = (sLastUnpacked == '/')
		sLastUnpacked = unpackRune(&s)
		sLastAtStart = sAtStart
		sAtStart = false
		return sLastUnpacked
	}
	for len(pattern) > 0 {
		c := unpackRune(&pattern)
		switch c {
		case '?':
			if len(s) == 0 {
				return false
			}
			sc := unpackS()
			if pathname && sc == '/' {
				return false
			}
			if period && sc == '.' && (sLastAtStart || (pathname && sLastSlash)) {
				return false
			}
		case '*':
			// collapse multiple *'s
			// don't use unpackRune here, the only char we care to detect is ASCII
			for len(pattern) > 0 && pattern[0] == '*' {
				pattern = pattern[1:]
			}
			if period && s[0] == '.' && (sAtStart || (pathname && sLastUnpacked == '/')) {
				return false
			}
			// optimize for patterns with * at end or before /
			if len(pattern) == 0 {
				if pathname {
					return leadingdir || (strchr(s, '/') == -1)
				} else {
					return true
				}
				return !(pathname && strchr(s, '/') >= 0)
			} else if pathname && pattern[0] == '/' {
				offset := strchr(s, '/')
				if offset == -1 {
					return false
				} else {
					// we already know our pattern and string have a /, skip past it
					s = s[offset:] // use unpackS here to maintain our bookkeeping state
					unpackS()
					pattern = pattern[1:] // we know / is one byte long
					break
				}
			}
			// general case, recurse
			for test := s; len(test) > 0; unpackRune(&test) {
				// I believe the (flags &^ FNM_PERIOD) is a bug when FNM_PATHNAME is specified
				// but this follows exactly from how fnmatch.c implements it
				if Match(pattern, test, (flags &^ FNM_PERIOD)) {
					return true
				} else if pathname && test[0] == '/' {
					break
				}
			}
			return false
		case '[':
			if len(s) == 0 {
				return false
			}
			if pathname && s[0] == '/' {
				return false
			}
			sc := unpackS()
			if !rangematch(&pattern, sc, flags) {
				return false
			}
		case '\\':
			if !noescape {
				if len(pattern) > 0 {
					c = unpackRune(&pattern)
				}
			}
			fallthrough
		default:
			if len(s) == 0 {
				return false
			}
			sc := unpackS()
			switch {
			case sc == c:
			case casefold && unicode.ToLower(sc) == unicode.ToLower(c):
			default:
				return false
			}
		}
	}
	return len(s) == 0 || (leadingdir && s[0] == '/')
}
464725
func patternRE(k string) *regexp.Regexp {
	re := bytes.Buffer{}
	re.WriteString(`^\Q`)
	for i := 0; i < len(k); i++ {
		p := k[i]
		switch p {
		case '*':
			re.WriteString(`\E.*\Q`)
		case '?':
			re.WriteString(`\E.\Q`)
		case '[':
			charClass := bytes.Buffer{}
			i++
			for ; i < len(k); i++ {
				if k[i] == ']' {
					break
				}
				if k[i] == '\\' {
					if i == len(k)-1 {
						// Ends with a '\'. U-huh.
						return nil
					}
					charClass.WriteByte(k[i])
					i++
					charClass.WriteByte(k[i])
					continue
				}
				charClass.WriteByte(k[i])
			}
			if charClass.Len() == 0 {
				// '[]' is valid in Redis, but matches nothing.
				return nil
			}
			re.WriteString(`\E[`)
			re.Write(charClass.Bytes())
			re.WriteString(`]\Q`)

		case '\\':
			if i == len(k)-1 {
				// Ends with a '\'. U-huh.
				return nil
			}
			// Forget the \, keep the next char.
			i++
			re.WriteByte(k[i])
			continue
		default:
			re.WriteByte(p)
		}
	}
	re.WriteString(`\E$`)
	return regexp.MustCompile(re.String())
}
781891
func (m Match) RawPattern() PatternType {
	switch v := m.Pattern.(type) {
	case regexpPattern:
		return v.re
	case stringPattern:
		return v.raw
	default:
		return v
	}
}