Add SB_MULTISEARCH flag for search_begin.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5782 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2020-10-27 02:56:18 +00:00
parent 3008072807
commit 5d4f66cffd
3 changed files with 66 additions and 13 deletions

View file

@ -2671,9 +2671,55 @@ void FS_FreeFile(void *file)
BZ_Free(file); BZ_Free(file);
} }
//handle->EnumerateFiles on each a:b:c part of the given matches string.
static qboolean FS_EnumerateFilesEach(searchpathfuncs_t *handle, char *matches, int (QDECL *func)(const char *fname, qofs_t fsize, time_t mtime, void *parm, searchpathfuncs_t *spath), void *parm)
{
char cleanpath[MAX_QPATH];
const char *match;
char *sep;
for (; matches; matches = sep)
{
sep = strchr(matches, ':');
if (sep)
{
*sep = 0;
match = FS_GetCleanPath(matches, true, cleanpath, sizeof(cleanpath));
*sep++ = ':';
}
else
match = FS_GetCleanPath(matches, true, cleanpath, sizeof(cleanpath));
searchpathfuncs_t *COM_EnumerateFilesPackage (const char *match, const char *package, unsigned int flags, int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*), void *parm) if (match && *match)
{ //special version that takes an explicit package name to search inside. if (!handle->EnumerateFiles(handle, match, func, parm))
return false;
}
return true;
}
static int FS_EnumerateFilesEachSys (const char *syspath, char *matches, int (*func)(const char *, qofs_t, time_t modtime, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{
char cleanpath[MAX_QPATH];
const char *match;
char *sep;
for (; matches; matches = sep)
{
sep = strchr(matches, ':');
if (sep)
{
*sep = 0;
match = FS_GetCleanPath(matches, true, cleanpath, sizeof(cleanpath));
*sep++ = ':';
}
else
match = FS_GetCleanPath(matches, true, cleanpath, sizeof(cleanpath));
if (!Sys_EnumerateFiles(syspath, match, func, parm, spath))
return false;
}
return true;
}
searchpathfuncs_t *COM_EnumerateFilesPackage (char *matches, const char *package, unsigned int flags, int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*), void *parm)
{ //special version of COM_EnumerateFiles that takes an explicit package name to search inside.
//additionally accepts multiple patterns (separated by : chsrs)
searchpathfuncs_t *handle; searchpathfuncs_t *handle;
searchpath_t *search; searchpath_t *search;
const char *sp; const char *sp;
@ -2696,8 +2742,8 @@ searchpathfuncs_t *COM_EnumerateFilesPackage (const char *match, const char *pac
continue; //ignore this package continue; //ignore this package
} }
foundpackage = true; foundpackage = true;
// is the element a pak file?
if (!search->handle->EnumerateFiles(search->handle, match, func, parm)) if (!FS_EnumerateFilesEach(search->handle, matches, func, parm))
break; break;
} }
@ -2733,7 +2779,7 @@ searchpathfuncs_t *COM_EnumerateFilesPackage (const char *match, const char *pac
} }
if (handle) if (handle)
handle->EnumerateFiles(handle, match, func, parm); FS_EnumerateFilesEach(handle, matches, func, parm);
return handle; //caller can use this for context, but is expected to tidy it up too. return handle; //caller can use this for context, but is expected to tidy it up too.
} }
else else
@ -2744,11 +2790,11 @@ searchpathfuncs_t *COM_EnumerateFilesPackage (const char *match, const char *pac
if (com_homepathenabled) if (com_homepathenabled)
{ {
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, package); Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, package);
Sys_EnumerateFiles(syspath, match, func, parm, NULL); FS_EnumerateFilesEachSys(syspath, matches, func, parm, NULL);
} }
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, package); Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, package);
Sys_EnumerateFiles(syspath, match, func, parm, NULL); FS_EnumerateFilesEachSys(syspath, matches, func, parm, NULL);
} }
} }
return NULL; return NULL;

View file

@ -3037,12 +3037,13 @@ void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
enum enum
{ {
QCSEARCH_INSENSITIVE = 1u<<0, //for dp, we're always insensitive you prick. // QCSEARCH_INSENSITIVE = 1u<<0, //for dp, we're always insensitive you prick.
QCSEARCH_FULLPACKAGE = 1u<<1, //package names include gamedir prefix etc. QCSEARCH_FULLPACKAGE = 1u<<1, //package names include gamedir prefix etc.
QCSEARCH_ALLOWDUPES = 1u<<2, //don't filter out dupes, allowing entries hidden by later packages to be shown. QCSEARCH_ALLOWDUPES = 1u<<2, //don't filter out dupes, allowing entries hidden by later packages to be shown.
QCSEARCH_FORCESEARCH = 1u<<3, //force the search to succeed even if the gamedir/package is not active. QCSEARCH_FORCESEARCH = 1u<<3, //force the search to succeed even if the gamedir/package is not active.
QCSEARCH_MULTISEARCH = 1u<<4, //to avoid possible string manipulation exploits?
}; };
searchpathfuncs_t *COM_EnumerateFilesPackage (const char *match, const char *package, unsigned int flags, int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*), void *parm); searchpathfuncs_t *COM_EnumerateFilesPackage (char *matches, const char *package, unsigned int flags, int (QDECL *func)(const char *, qofs_t, time_t mtime, void *, searchpathfuncs_t*), void *parm);
typedef struct prvmsearch_s { typedef struct prvmsearch_s {
pubprogfuncs_t *fromprogs; //share across menu/server pubprogfuncs_t *fromprogs; //share across menu/server
@ -3142,7 +3143,7 @@ static int QDECL search_enumerate(const char *name, qofs_t fsize, time_t mtime,
return true; return true;
} }
//float search_begin(string pattern, float caseinsensitive, float quiet) = #74; //float search_begin(string pattern, float flags, float quiet) = #74;
void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //< 0 for error, >= 0 for handle. { //< 0 for error, >= 0 for handle.
//error includes bad search patterns, but not no files //error includes bad search patterns, but not no files
@ -3153,7 +3154,7 @@ void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_
prvmsearch_t *s; prvmsearch_t *s;
size_t j; size_t j;
if (!*pattern || (*pattern == '.' && pattern[1] == '.') || *pattern == '/' || *pattern == '\\' || strchr(pattern, ':')) if (!*pattern || (*pattern == '.' && pattern[1] == '.') || *pattern == '/' || *pattern == '\\' || (!(flags&QCSEARCH_MULTISEARCH)&&strchr(pattern, ':')))
{ {
PF_Warningf(prinst, "PF_search_begin: bad search pattern \"%s\"\n", pattern); PF_Warningf(prinst, "PF_search_begin: bad search pattern \"%s\"\n", pattern);
G_FLOAT(OFS_RETURN) = -1; G_FLOAT(OFS_RETURN) = -1;
@ -3183,7 +3184,7 @@ void QCBUILTIN PF_search_begin (pubprogfuncs_t *prinst, struct globalvars_s *pr_
s->fsflags |= WP_FORCE; s->fsflags |= WP_FORCE;
Q_strncpyz(s->searchinfo.purepath, package?package:"", sizeof(s->searchinfo.purepath)); Q_strncpyz(s->searchinfo.purepath, package?package:"", sizeof(s->searchinfo.purepath));
s->searchinfo.handle = COM_EnumerateFilesPackage(pattern, package?s->searchinfo.purepath:NULL, s->fsflags, search_enumerate, s); s->searchinfo.handle = COM_EnumerateFilesPackage(s->pattern, package?s->searchinfo.purepath:NULL, s->fsflags, search_enumerate, s);
G_FLOAT(OFS_RETURN) = j; G_FLOAT(OFS_RETURN) = j;
} }

View file

@ -10628,7 +10628,13 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"cvar_string", PF_Fixme, 0, 0, 0, 71, D("string(string name)", "Returns the value of a cvar, as a string.")}, {"cvar_string", PF_Fixme, 0, 0, 0, 71, D("string(string name)", "Returns the value of a cvar, as a string.")},
{"crash", PF_Fixme, 0, 0, 0, 72, D("void()", "Demonstrates that no program is bug free.")}, {"crash", PF_Fixme, 0, 0, 0, 72, D("void()", "Demonstrates that no program is bug free.")},
{"stackdump", PF_Fixme, 0, 0, 0, 73, D("void()", "Prints out the QC's stack, for console-based error reports.")}, {"stackdump", PF_Fixme, 0, 0, 0, 73, D("void()", "Prints out the QC's stack, for console-based error reports.")},
{"search_begin", PF_Fixme, 0, 0, 0, 74, "searchhandle(string pattern, enumflags:float{SB_CASEINSENSITIVE=1<<0,SB_FULLPACKAGEPATH=1<<1,SB_ALLOWDUPES=1<<2,SB_FORCESEARCH=1<<3} flags, float quiet, optional string package)"}, {"search_begin", PF_Fixme, 0, 0, 0, 74, "searchhandle(string pattern, enumflags:float{"
"SB_CASEINSENSITIVE=1<<0,"
"SB_FULLPACKAGEPATH=1<<1,"
"SB_ALLOWDUPES=1<<2,"
"SB_FORCESEARCH=1<<3"
"SB_MULTISEARCH=1<<4"
"} flags, float quiet, optional string package)"},
{"search_end", PF_Fixme, 0, 0, 0, 75, "void(searchhandle handle)"}, {"search_end", PF_Fixme, 0, 0, 0, 75, "void(searchhandle handle)"},
{"search_getsize", PF_Fixme, 0, 0, 0, 76, "float(searchhandle handle)"}, {"search_getsize", PF_Fixme, 0, 0, 0, 76, "float(searchhandle handle)"},
{"search_getfilename",PF_Fixme, 0, 0, 0, 77, "string(searchhandle handle, float num)"}, {"search_getfilename",PF_Fixme, 0, 0, 0, 77, "string(searchhandle handle, float num)"},