+#include "matchpattern.h"
+
+// LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...
+
+int matchpattern(const char *in, const char *pattern, int caseinsensitive)
+{
+ return matchpattern_with_separator(in, pattern, caseinsensitive, "/\\:", false);
+}
+
+// wildcard_least_one: if true * matches 1 or more characters
+// if false * matches 0 or more characters
+int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, int wildcard_least_one)
+{
+ int c1, c2;
+ while (*pattern)
+ {
+ switch (*pattern)
+ {
+ case 0:
+ return 1; // end of pattern
+ case '?': // match any single character
+ if (*in == 0 || strchr(separators, *in))
+ return 0; // no match
+ in++;
+ pattern++;
+ break;
+ case '*': // match anything until following string
+ if(wildcard_least_one)
+ {
+ if (*in == 0 || strchr(separators, *in))
+ return 0; // no match
+ in++;
+ }
+ pattern++;
+ while (*in)
+ {
+ if (strchr(separators, *in))
+ break;
+ // see if pattern matches at this offset
+ if (matchpattern_with_separator(in, pattern, caseinsensitive, separators, wildcard_least_one))
+ return 1;
+ // nope, advance to next offset
+ in++;
+ }
+ break;
+ default:
+ if (*in != *pattern)
+ {
+ if (!caseinsensitive)
+ return 0; // no match
+ c1 = *in;
+ if (c1 >= 'A' && c1 <= 'Z')
+ c1 += 'a' - 'A';
+ c2 = *pattern;
+ if (c2 >= 'A' && c2 <= 'Z')
+ c2 += 'a' - 'A';
+ if (c1 != c2)
+ return 0; // no match
+ }
+ in++;
+ pattern++;
+ break;
+ }
+ }
+ if (*in)
+ return 0; // reached end of pattern but not end of input
+ return 1; // success
+}