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
76
77
78
79
80
81
82
|
#include "rc.h"
/* removes glob marks in place */
void
deglob(char *s)
{
char *t = s;
do{
if(*t==GLOB)
t++;
*s++=*t;
}while(*t++);
}
int
match(char *s, char *p, int stop)
{
rune rs, rp, lo, hi;
int neg, hit;
utf8·decode(p, &rp), utf8·decode(s, &rs);
for(; *p && *p != stop; s+=utf8·decode(s,&rs),p+=utf8·decode(p,&rp)){
/* fast path: normal character */
if(*p != GLOB){
if(rp != rs)
return 0;
continue;
}
/* unglob */
switch(*++p){
case GLOB:
if(*s != GLOB)
return 0;
break;
case '*':
for(;;){
p += utf8·decode(p, &rp);
if(match(s, p, stop))
return 1;
s += utf8·decode(s, &rs);
}
return 0;
case '?':
if(*s == 0)
return 0;
break;
case '[':
if(*s==0)
return 0;
if((neg=*++p=='~'))
p++;
hit = 0;
while(*p != ']'){
if(*p==0)
return 0; /* syntax error */
p += utf8·decode(p, &lo);
if(*p != '-')
hi = lo;
else{
if(*++p == 0)
return 0; /* syntax error */
p += utf8·decode(p, &hi);
if(hi < lo)
rp=lo, lo=hi, hi=rp;
}
if(lo <= rs && rs <= hi)
hit = 1;
}
if(neg)
hit=!hit;
if(!hit)
return 0;
break;
}
}
return *s == 0;
}
|