1 /* str/match.c - Simple pattern matching
2  * Copyright (C) 2003,2005  Bruce Guenter <bruce@untroubled.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  */
18 #include <string.h>
19 
20 #include "str.h"
21 
22 /** Simple but fast (linear time) pattern matching on binary pattern. */
str_matchb(const str * s,const char * pptr,unsigned plen)23 int str_matchb(const str* s, const char* pptr, unsigned plen)
24 {
25   const char* sptr;
26   long slen = s->len;
27   if (plen == 0) return slen == 0;
28   for (sptr = s->s; plen > 0; ++sptr, --slen, ++pptr, --plen) {
29     char p = *pptr;
30     if (p == '*') {
31       ++pptr, --plen;
32       if (plen == 0) return 1;
33       p = *pptr;
34       while (slen > 0) {
35 	if (*sptr == p) break;
36 	++sptr, --slen;
37       }
38       if (slen == 0) return 0;
39     }
40     else {
41       if (slen == 0) return 0;
42       if (*sptr != p) return 0;
43     }
44   }
45   return slen == 0;
46 }
47 
48 /** Simple pattern match on dynamic string pattern. */
str_match(const str * s,const str * pattern)49 int str_match(const str* s, const str* pattern)
50 {
51   return str_matchb(s, pattern->s, pattern->len);
52 }
53 
54 /** Simple pattern match on C string pattern. */
str_matchs(const str * s,const char * pattern)55 int str_matchs(const str* s, const char* pattern)
56 {
57   return str_matchb(s, pattern, strlen(pattern));
58 }
59 
60 #ifdef SELFTEST_MAIN
61 static const str s = { "abc", 3, 0 };
t(const char * pattern)62 void t(const char* pattern)
63 {
64   obuf_puts(&outbuf, pattern);
65   obuf_putc(&outbuf, ' ');
66   debugfn(str_matchs(&s, pattern));
67 }
68 MAIN
69 {
70   t("");
71   t("*");
72   t("**");
73   t("abc");
74   t("ABC");
75   t("a");
76   t("a*");
77   t("*a*");
78   t("*a");
79   t("b*");
80   t("*b*");
81   t("*b");
82   t("c*");
83   t("*c*");
84   t("*c");
85   t("d*");
86   t("*d*");
87   t("*d");
88   t("*C");
89 }
90 #endif
91 #ifdef SELFTEST_EXP
92  result=0
93 * result=1
94 ** result=0
95 abc result=1
96 ABC result=0
97 a result=0
98 a* result=1
99 *a* result=1
100 *a result=0
101 b* result=0
102 *b* result=1
103 *b result=0
104 c* result=0
105 *c* result=1
106 *c result=1
107 d* result=0
108 *d* result=0
109 *d result=0
110 *C result=0
111 #endif
112