tools/quake3/q3map2/vis.o \
tools/quake3/q3map2/writebsp.o \
libddslib.$(A) \
+ libfilematch.$(A) \
libjpeg6.$(A) \
libl_net.$(A) \
libmathlib.$(A) \
radiant/xmlstuff.o \
radiant/xywindow.o \
libcmdlib.$(A) \
+ libfilematch.$(A) \
libgtkutil.$(A) \
libl_net.$(A) \
libmathlib.$(A) \
libxmllib.$(A) \
$(if $(findstring $(OS),Win32),icons/radiant.o,) \
+libfilematch.$(A): CPPFLAGS_EXTRA := -Ilibs
+libfilematch.$(A): \
+ libs/filematch.o \
+
libcmdlib.$(A): CPPFLAGS_EXTRA := -Ilibs
libcmdlib.$(A): \
libs/cmdlib/cmdlib.o \
--- /dev/null
+#if !defined(INCLUDED_FILEMATCH_H)
+#define INCLUDED_FILEMATCH_H
+
+int matchpattern(const char *in, const char *pattern, int caseinsensitive);
+int matchpattern_with_separator(const char *in, const char *pattern, int caseinsensitive, const char *separators, int wildcard_least_one);
+
+#endif
--- /dev/null
+#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
+}
for(j = 0; j < g_numForbiddenDirs; ++j)
{
- if(!string_compare_nocase_upper(directory, g_strForbiddenDirs[j])
- || (string_length(directory) > string_length(g_strForbiddenDirs[j]) && directory[string_length(directory) - string_length(g_strForbiddenDirs[j]) - 1] == '/' && !string_compare_nocase_upper(directory + string_length(directory) - string_length(g_strForbiddenDirs[j]), g_strForbiddenDirs[j])))
+ const char *p = strrchr(directory, '/');
+ p = (p ? (p+1) : path);
+ if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
break;
}
if(j < g_numForbiddenDirs)
#include <sys/stat.h>
#include "cmdlib.h"
+#include "filematch.h"
#include "mathlib.h"
#include "inout.h"
#include "vfs.h"
for(j = 0; j < g_numForbiddenDirs; ++j)
{
- if(!Q_stricmp(path, g_strForbiddenDirs[j])
- || (strlen(path) > strlen(g_strForbiddenDirs[j]) && path[strlen(path) - strlen(g_strForbiddenDirs[j]) - 1] == '/' && !Q_stricmp(path + strlen(path) - strlen(g_strForbiddenDirs[j]), g_strForbiddenDirs[j])))
+ const char *p = strrchr(path, '/');
+ p = (p ? (p+1) : path);
+ if(matchpattern(p, g_strForbiddenDirs[j], TRUE))
break;
}
if(j < g_numForbiddenDirs)