Code:
#include<stdio.h>
#include<string.h>
int match(char *f, char *s) {
char *t;
while(1) {
if(*f == '?' || *s == '?') ;
else if(*f == '*') {
t = s;
while(1) {
if(match(f+1, t)) return 1;
if(!*t++) break;
}
return 0;
}
else if(*s == '*') {
t = f;
while(1) {
if(match(s+1, t)) return 1;
if(!*t++) break;
}
return 0;
}
else if(*f != *s) return 0;
if(!*s || !*f) break;
s++, f++;
}
return *f || *s ? 0 : 1;
}
int qmatch( char *f, char *s )
{
while( *f && *s )
{
if( *f == '*' )
{
while( *f && (*f == '*' || *f == '?') ) f++;
while( *s && *s != *f )*s++;
}
if( !*s || !*f ) break;
if( *s == '*' )
{
while( *s && (*s == '*' || *s == '?') ) s++;
while( *f && *f != *s )*f++;
}
if( !*s || !*f ) break;
if( *f == *s || *f == '?' || *s == '?' )
{
f++;
s++;
}
else
return 0;
}
return (*f || *s) || (*f==*s) ? 1 : 0;
}
int main( void )
{
char *s[] =
{
"foo.c",
"?oo.c",
"*.c",
"f?*",
"?*?",
"*",
"?.*",
"foo.*"
};
char *f[] =
{
"foo.c",
"?oo.c",
"*.c",
"?*.c",
"*?.?",
"foo.?",
"foo.*",
"f?o?c",
"f*o*"
"*",
"?????"
};
int x,y;
for( y = 0; y < sizeof f / sizeof f[0]; y++ )
{
for( x = 0; x < sizeof s / sizeof s[0]; x++ )
{
printf("%8s vs %8s = %d, %d\n", f[ y ], s[ x ],
match( f[ y ], s[ x ] ),
qmatch( f[ y ], s[ x ] )
);
}
}
return 0;
}
/*
foo.c vs foo.c = 1, 1
foo.c vs ?oo.c = 1, 1
foo.c vs *.c = 1, 1
foo.c vs f?* = 1, 1
foo.c vs ?*? = 1, 1
foo.c vs * = 1, 1
foo.c vs ?.* = 0, 0
foo.c vs foo.* = 1, 1
?oo.c vs foo.c = 1, 1
?oo.c vs ?oo.c = 1, 1
?oo.c vs *.c = 0, 1
?oo.c vs f?* = 1, 1
?oo.c vs ?*? = 1, 1
?oo.c vs * = 0, 1
?oo.c vs ?.* = 0, 0
?oo.c vs foo.* = 1, 1
*.c vs foo.c = 1, 1
*.c vs ?oo.c = 0, 1
*.c vs *.c = 1, 1
*.c vs f?* = 1, 1
*.c vs ?*? = 1, 1
*.c vs * = 1, 1
*.c vs ?.* = 1, 1
*.c vs foo.* = 1, 1
?*.c vs foo.c = 1, 1
?*.c vs ?oo.c = 1, 1
?*.c vs *.c = 1, 1
?*.c vs f?* = 1, 1
?*.c vs ?*? = 1, 1
?*.c vs * = 0, 1
?*.c vs ?.* = 1, 1
?*.c vs foo.* = 1, 1
*?.? vs foo.c = 1, 1
*?.? vs ?oo.c = 0, 1
*?.? vs *.c = 1, 1
*?.? vs f?* = 1, 1
*?.? vs ?*? = 0, 1
*?.? vs * = 0, 1
*?.? vs ?.* = 1, 1
*?.? vs foo.* = 1, 1
foo.? vs foo.c = 1, 1
foo.? vs ?oo.c = 1, 1
foo.? vs *.c = 1, 1
foo.? vs f?* = 1, 1
foo.? vs ?*? = 1, 1
foo.? vs * = 1, 1
foo.? vs ?.* = 0, 0
foo.? vs foo.* = 1, 1
foo.* vs foo.c = 1, 1
foo.* vs ?oo.c = 1, 1
foo.* vs *.c = 1, 1
foo.* vs f?* = 1, 1
foo.* vs ?*? = 1, 1
foo.* vs * = 1, 1
foo.* vs ?.* = 0, 0
foo.* vs foo.* = 1, 1
f?o?c vs foo.c = 1, 1
f?o?c vs ?oo.c = 1, 1
f?o?c vs *.c = 1, 1
f?o?c vs f?* = 1, 1
f?o?c vs ?*? = 0, 1
f?o?c vs * = 1, 1
f?o?c vs ?.* = 1, 1
f?o?c vs foo.* = 1, 1
f*o** vs foo.c = 1, 1
f*o** vs ?oo.c = 1, 1
f*o** vs *.c = 1, 1
f*o** vs f?* = 1, 1
f*o** vs ?*? = 1, 1
f*o** vs * = 1, 1
f*o** vs ?.* = 1, 1
f*o** vs foo.* = 1, 1
????? vs foo.c = 1, 1
????? vs ?oo.c = 1, 1
????? vs *.c = 0, 1
????? vs f?* = 0, 1
????? vs ?*? = 0, 1
????? vs * = 0, 1
????? vs ?.* = 0, 1
????? vs foo.* = 1, 1
*/
Mine was an attempt to really cover all the cases I could think up for valid matching. I don't know if they fit all of your rules, but that's my take on it.