Convert utility.c into libbb.a. It is now a whole pile of .c
[oweals/busybox.git] / libbb / check_wildcard_match.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Utility routines.
4  *
5  * Copyright (C) tons of folks.  Tracking down who wrote what
6  * isn't something I'm going to worry about...  If you wrote something
7  * here, please feel free to acknowledge your work.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  *
23  * Based in part on code from sash, Copyright (c) 1999 by David I. Bell 
24  * Permission has been granted to redistribute this code under the GPL.
25  *
26  */
27
28 #include <stdio.h>
29 #include "libbb.h"
30
31
32 /*
33  * Routine to see if a text string is matched by a wildcard pattern.
34  * Returns TRUE if the text is matched, or FALSE if it is not matched
35  * or if the pattern is invalid.
36  *  *           matches zero or more characters
37  *  ?           matches a single character
38  *  [abc]       matches 'a', 'b' or 'c'
39  *  \c          quotes character c
40  * Adapted from code written by Ingo Wilken, and
41  * then taken from sash, Copyright (c) 1999 by David I. Bell
42  * Permission is granted to use, distribute, or modify this source,
43  * provided that this copyright notice remains intact.
44  * Permission to distribute this code under the GPL has been granted.
45  */
46 extern int check_wildcard_match(const char *text, const char *pattern)
47 {
48         const char *retryPat;
49         const char *retryText;
50         int ch;
51         int found;
52         int len;
53
54         retryPat = NULL;
55         retryText = NULL;
56
57         while (*text || *pattern) {
58                 ch = *pattern++;
59
60                 switch (ch) {
61                 case '*':
62                         retryPat = pattern;
63                         retryText = text;
64                         break;
65
66                 case '[':
67                         found = FALSE;
68
69                         while ((ch = *pattern++) != ']') {
70                                 if (ch == '\\')
71                                         ch = *pattern++;
72
73                                 if (ch == '\0')
74                                         return FALSE;
75
76                                 if (*text == ch)
77                                         found = TRUE;
78                         }
79                         len=strlen(text);
80                         if (found == FALSE && len!=0) {
81                                 return FALSE;
82                         }
83                         if (found == TRUE) {
84                                 if (strlen(pattern)==0 && len==1) {
85                                         return TRUE;
86                                 }
87                                 if (len!=0) {
88                                         text++;
89                                         continue;
90                                 }
91                         }
92
93                         /* fall into next case */
94
95                 case '?':
96                         if (*text++ == '\0')
97                                 return FALSE;
98
99                         break;
100
101                 case '\\':
102                         ch = *pattern++;
103
104                         if (ch == '\0')
105                                 return FALSE;
106
107                         /* fall into next case */
108
109                 default:
110                         if (*text == ch) {
111                                 if (*text)
112                                         text++;
113                                 break;
114                         }
115
116                         if (*text) {
117                                 pattern = retryPat;
118                                 text = ++retryText;
119                                 break;
120                         }
121
122                         return FALSE;
123                 }
124
125                 if (pattern == NULL)
126                         return FALSE;
127         }
128
129         return TRUE;
130 }
131
132
133 /* END CODE */
134 /*
135 Local Variables:
136 c-file-style: "linux"
137 c-basic-offset: 4
138 tab-width: 4
139 End:
140 */