Wildcard search in C version 2

A few days ago, I posted my version of a wildcard search algorithm, which you can see here: Wildcard search in C

Today I'm showing version 2. I didn't want to make it in the same post because the code is quite different.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#define MULTICHAR '*'
#define ONECHAR '?'
#define null NULL

bool wildcard(const char *value, char *wcard) {

int vsize = (int)strlen(value);
int wsize = (int)strlen(wcard);
bool match = false;

if (vsize == 0 && wsize == 0) {
match = true;
}

else {
int v = 0;
int w = 0;
bool searchMode = false;
char search = '\0';

while (true) {
if (wcard[w] == MULTICHAR) {
//starts with * and the value matches the wcard
if (w == 0 && strcmp(wcard+1,value) == 0) {
match = true;
break;
}
//the * is the last character in the pattern
if (!wcard[w+1]) {
match = true;
break;
}
else {
//search for the next char in the pattern that is not a ?
while (wcard[++w] == ONECHAR) {
}

//if the next char in the pattern is another * we go to the start (in case we have a pattern like **a, stupid I know, but it might happen)
if (wcard[w] == MULTICHAR) {
continue;
}

search = wcard[w];
searchMode = true;
}
}

else {
if (!value[v] && !wcard[w]) {
if (searchMode) {
match = false;
}
break;
}
if (searchMode) {
if (currentValue == search) {
match = true;

searchMode = false;
search = '\0';
w++;
}

else if (currentValue == '\0') {
match = false;
break;
}

v++;
continue;
}
else if ((wcard[w] == ONECHAR && value[v] == '\0') || (wcard[w] != value[v] && wcard[w] != ONECHAR)) {
match = false;
break;
}
else {
match = true;
}

w++;
v++;
}
}
}

return match;
}


I think there is still room for improvements, so any advice, tips or critiques are all welcome.

To compile, just do make wildcard.

• I'm assuming you'd also like this to be shortened? It's considerably longer than the first version. – Jamal Sep 3 '13 at 12:24
• Yes. This is still in the early stages. It passes the tests but as microtherion mentioned in his response I already have a bug. – AntonioCS Sep 3 '13 at 19:29

abcbcd    ab*cd

One approach that works is a recursive matcher, i.e. when encountering *, try wildcard(value+1, wcard) and if that fails, wildcard(value, wcard+1). This will give you the standard semantics of an * matching as much as possible. For a minimal match, reverse the order of the two recursive calls. This is very easy to implement (much easier than your approach, in fact), but tends to need a lot of stack space for large strings.
• You need both. For the greedy matcher, you first recurse with (value+1, wcard), i.e. you try eating the next character. If that fails, you recurse (or, since this is a tail recursion, iterate) with (value, wcard+1), i.e., match the rest of value without having the wildcard match any more characters. – microtherion Sep 3 '13 at 22:26