1 /* $Id$
2 * Provides functions to pattern matching. Taken from sh sources
3 *
4 * Copyright (c) 1999-2003
5 * The Husky Developers Team
6 *
7 * Copyright (c) 1991, 1993
8 * The Regents of the University of California. All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * Kenneth Almquist.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 */
42
43 /* standard headers */
44 #include <string.h>
45 #include <ctype.h>
46
47 /* huskylib: compiler.h */
48 #include <compiler.h>
49
50
51 /* huskylib headers */
52 #define DLLEXPORT
53 #include <huskyext.h>
54
55 /* huskylib headers */
56 #include <huskylib.h>
57
58
59 /*** Declarations & defines ***********************************************/
60
61 #define CTLESC '\\'
62
63 /*** Implementation *******************************************************/
64
65 /* Returns true if the pattern matches the string.
66 */
xpatmat(const char * string,const char * pattern,const int ncase)67 int xpatmat(const char *string, const char *pattern, const int ncase)
68 {
69 register const char *p, *q;
70 register char c;
71
72 p = pattern;
73 q = string;
74 for (;;) {
75 c = *p++;
76 switch (c) {
77 case '\0':
78 goto breakloop;
79 case CTLESC:
80 if (*q++ != *p++)
81 return 0;
82 break;
83 case '?':
84 if (*q++ == '\0')
85 return 0;
86 break;
87 case '#':
88 if (*q == '\0')
89 return 0;
90 else if (!isdigit(*q++))
91 return 0;
92 break;
93 case '*':
94 c = *p;
95 if (c != CTLESC && c != '?' && c != '*' && c != '[' && c != '#') {
96 while (*q != c) {
97 if (ncase && toupper(*q) == toupper(c))
98 break;
99 if (*q == '\0')
100 return 0;
101 q++;
102 }
103 }
104 do {
105 if (xpatmat(q, p, ncase))
106 return 1;
107 } while (*q++ != '\0');
108 return 0;
109 case '[': {
110 const char *endp;
111 int invert, found;
112 char chr;
113
114 endp = p;
115 if (*endp == '!')
116 endp++;
117 for (;;) {
118 if (*endp == '\0')
119 goto dft; /* no matching ] */
120 if (*endp == CTLESC)
121 endp++;
122 if (*++endp == ']')
123 break;
124 }
125 invert = 0;
126 if (*p == '!') {
127 invert++;
128 p++;
129 }
130 found = 0;
131 chr = *q++;
132 c = *p++;
133 do {
134 if (c == CTLESC)
135 c = *p++;
136 if (*p == '-' && p[1] != ']') {
137 p++;
138 if (*p == CTLESC)
139 p++;
140 if (chr >= c && chr <= *p)
141 found = 1;
142 p++;
143 } else {
144 if (chr == c)
145 found = 1;
146 }
147 } while ((c = *p++) != ']');
148 if (found == invert)
149 return 0;
150 break;
151 }
152 dft: default:
153 if (ncase) {
154 if (toupper(*q++) != toupper(c))
155 return 0;
156 }
157 else if (*q++ != c)
158 return 0;
159 break;
160 }
161 }
162 breakloop:
163 if (*q != '\0')
164 return 0;
165 return 1;
166 }
167
168 #ifdef TEST
169
170 #include <stdio.h>
171
main(void)172 int main(void)
173 {
174 printf("patmat(\"abcdefghi\", \"*ghi\"): %d\n", patmat("abcdefghi", "*ghi"));
175 printf("patmat(\"abcdefghi\", \"??c??f*\"): %d\n", patmat("abcdefghi", "??c??f*"));
176 printf("patmat(\"abcdefghi\", \"*dh*\"): %d\n", patmat("abcdefghi", "*dh*"));
177 printf("patmat(\"abcdefghi\", \"*def\"): %d\n", patmat("abcdefghi", "*def"));
178 return 0;
179 }
180
181 #endif
182