source: trunk/minix/commands/i386/mtools-3.9.7/match.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 2.4 KB
Line 
1/*
2 * Do shell-style pattern matching for '?', '\', '[..]', and '*' wildcards.
3 * Returns 1 if match, 0 if not.
4 */
5
6#include "sysincludes.h"
7#include "mtools.h"
8
9
10static int casecmp(char a,char b)
11{
12 return toupper(a) == toupper(b);
13}
14
15static int exactcmp(char a,char b)
16{
17 return a == b;
18}
19
20
21static int parse_range(const char **p, const char *s, char *out,
22 int (*compfn)(char a, char b))
23{
24 char table[256];
25 int reverse;
26 int i;
27 short first, last;
28
29 if (**p == '^') {
30 reverse = 1;
31 (*p)++;
32 } else
33 reverse=0;
34 for(i=0; i<256; i++)
35 table[i]=0;
36 while(**p != ']') {
37 if(!**p)
38 return 0;
39 if((*p)[1] == '-') {
40 first = **p;
41 (*p)+=2;
42 if(**p == ']')
43 last = 256;
44 else
45 last = *((*p)++);
46 for(i=first; i<last; i++)
47 table[i] = 1;
48 } else
49 table[(int) *((*p)++)] = 1;
50 }
51 if(out)
52 *out = *s;
53 if(table[(int) *s])
54 return 1 ^ reverse;
55 if(compfn == exactcmp)
56 return reverse;
57 if(table[tolower(*s)]) {
58 if(out)
59 *out = tolower(*s);
60 return 1 ^ reverse;
61 }
62 if(table[toupper(*s)]) {
63 if(out)
64 *out = toupper(*s);
65 return 1 ^ reverse;
66 }
67 return reverse;
68}
69
70
71static int _match(const char *s, const char *p, char *out, int Case,
72 int length,
73 int (*compfn) (char a, char b))
74{
75 for (; *p != '\0' && length; ) {
76 switch (*p) {
77 case '?': /* match any one character */
78 if (*s == '\0')
79 return(0);
80 if(out)
81 *(out++) = *s;
82 break;
83 case '*': /* match everything */
84 while (*p == '*' && length) {
85 p++;
86 length--;
87 }
88
89 /* search for next char in pattern */
90 while(*s) {
91 if(_match(s, p, out, Case, length,
92 compfn))
93 return 1;
94 if(out)
95 *out++ = *s;
96 s++;
97 }
98 continue;
99 case '[': /* match range of characters */
100 p++;
101 length--;
102 if(!parse_range(&p, s, out++, compfn))
103 return 0;
104 break;
105 case '\\': /* Literal match with next character */
106 p++;
107 length--;
108 /* fall thru */
109 default:
110 if (!compfn(*s,*p))
111 return(0);
112 if(out)
113 *(out++) = *p;
114 break;
115 }
116 p++;
117 length--;
118 s++;
119 }
120 if(out)
121 *out = '\0';
122
123 /* string ended prematurely ? */
124 if (*s != '\0')
125 return(0);
126 else
127 return(1);
128}
129
130
131int match(const char *s, const char *p, char *out, int Case, int length)
132{
133 int (*compfn)(char a, char b);
134
135 if(Case)
136 compfn = casecmp;
137 else
138 /*compfn = exactcmp;*/
139 compfn = casecmp;
140 return _match(s, p, out, Case, length, compfn);
141}
142
Note: See TracBrowser for help on using the repository browser.