File: glob.go

package info (click to toggle)
ipp-usb 0.9.30-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 756 kB
  • sloc: sh: 80; makefile: 40
file content (75 lines) | stat: -rw-r--r-- 1,547 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/* ipp-usb - HTTP reverse proxy, backed by IPP-over-USB connection to device
 *
 * Copyright (C) 2020 and up by Alexander Pevzner (pzz@apevzner.com)
 * See LICENSE for license terms and conditions
 *
 * Glob-style pattern matching
 */

package main

// GlobMatch matches string against glob-style pattern.
// Pattern  may contain wildcards and has a following syntax:
//   *   - matches any sequence of characters
//   ?   - matches exactly one character
//   \ C - matches character C
//   C   - matches character C (C is not *, ? or \)
//
// It return a counter of matched non-wildcard characters, -1 if no match
func GlobMatch(str, pattern string) int {
	return globMatchInternal(str, pattern, 0)
}

// globMatchInternal does the actual work of GlobMatch() function
func globMatchInternal(str, pattern string, count int) int {
	for str != "" && pattern != "" {
		p := pattern[0]
		pattern = pattern[1:]

		switch p {
		case '*':
			for pattern != "" && pattern[0] == '*' {
				pattern = pattern[1:]
			}

			if pattern == "" {
				return count
			}

			for i := 0; i < len(str); i++ {
				c2 := globMatchInternal(str[i:], pattern, count)
				if c2 >= 0 {
					return c2
				}
			}

		case '?':
			str = str[1:]

		case '\\':
			if pattern == "" {
				return -1
			}
			p, pattern = pattern[0], pattern[1:]
			fallthrough

		default:
			if str[0] != p {
				return -1
			}
			str = str[1:]
			count++

		}
	}

	for pattern != "" && pattern[0] == '*' {
		pattern = pattern[1:]
	}

	if str == "" && pattern == "" {
		return count
	}

	return -1
}