charset/tests: add more str[n]casecmp_m() tests to demonstrate the bug
[Samba.git] / lib / util / unix_match.c
blob38edc18322612a9fef02ad94fee896245639ce53
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Jeremy Allison 2001
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include <talloc.h>
22 #include "lib/util/talloc_stack.h"
23 #include "lib/util/charset/charset.h"
24 #include "lib/util/unix_match.h"
26 /*********************************************************
27 Recursive routine that is called by unix_wild_match.
28 *********************************************************/
30 static bool unix_do_match(const char *regexp, const char *str)
32 const char *p;
34 for( p = regexp; *p && *str; ) {
36 switch(*p) {
37 case '?':
38 str++;
39 p++;
40 break;
42 case '*':
45 * Look for a character matching
46 * the one after the '*'.
48 p++;
49 if(!*p) {
50 return true; /* Automatic match */
52 while(*str) {
54 while(*str && (*p != *str)) {
55 str++;
59 * Patch from weidel@multichart.de.
60 * In the case of the regexp
61 * '*XX*' we want to ensure there are
62 * at least 2 'X' characters in the
63 * string after the '*' for a match to
64 * be made.
68 int matchcount=0;
71 * Eat all the characters that
72 * match, but count how many
73 * there were.
76 while(*str && (*p == *str)) {
77 str++;
78 matchcount++;
82 * Now check that if the regexp
83 * had n identical characters
84 * that matchcount had at least
85 * that many matches.
88 while (*(p+1) && (*(p+1)==*p)) {
89 p++;
90 matchcount--;
93 if ( matchcount <= 0 ) {
94 return false;
99 * We've eaten the match char
100 * after the '*'
102 str--;
104 if(unix_do_match(p, str)) {
105 return true;
108 if(!*str) {
109 return false;
110 } else {
111 str++;
114 return false;
116 default:
117 if(*str != *p) {
118 return false;
120 str++;
121 p++;
122 break;
126 if(!*p && !*str) {
127 return true;
130 if (!*p && str[0] == '.' && str[1] == 0) {
131 return true;
134 if (!*str && *p == '?') {
135 while (*p == '?') {
136 p++;
138 return(!*p);
141 if(!*str && (*p == '*' && p[1] == '\0')) {
142 return true;
145 return false;
148 /*******************************************************************
149 Simple case insensitive interface to a UNIX wildcard matcher.
150 Returns True if match, False if not.
151 *******************************************************************/
153 bool unix_wild_match(const char *pattern, const char *string)
155 TALLOC_CTX *ctx = talloc_stackframe();
156 char *p2;
157 char *s2;
158 char *p;
159 bool ret = false;
161 p2 = strlower_talloc(ctx, pattern);
162 s2 = strlower_talloc(ctx, string);
163 if (!p2 || !s2) {
164 TALLOC_FREE(ctx);
165 return false;
168 /* Remove any *? and ** from the pattern as they are meaningless */
169 for(p = p2; *p; p++) {
170 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
171 memmove(&p[1], &p[2], strlen(&p[2])+1);
175 if (p2[0] == '*' && p2[1] == '\0') {
176 TALLOC_FREE(ctx);
177 return true;
180 ret = unix_do_match(p2, s2);
181 TALLOC_FREE(ctx);
182 return ret;