summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2013-04-05 18:53:14 +0400
committerAndrey Nazarov <skuller@skuller.net>2013-04-06 00:56:58 +0400
commitfe95b438f4a7b00c4aa41063531f66c4436d107e (patch)
tree1bcfcf711a9c88a1e20d653cd4acdb2effec4937
parent2e377ff12d90e1b4d6d6505abea44f8429763332 (diff)
Improve FS_ListFiles when operating on pack files.
Fix searching in the root directory of pack files: NULL path finds all files, empty path excludes subdirectories. Add basic support for listing directories inside pack files.
-rw-r--r--inc/common/files.h1
-rw-r--r--src/common/cmd.c2
-rw-r--r--src/common/files.c67
3 files changed, 48 insertions, 22 deletions
diff --git a/inc/common/files.h b/inc/common/files.h
index b86ee6e..c2ab66a 100644
--- a/inc/common/files.h
+++ b/inc/common/files.h
@@ -66,6 +66,7 @@ typedef struct file_info_s {
#define FS_SEARCH_EXTRAINFO 0x00000400
#define FS_SEARCH_STRIPEXT 0x00000800
#define FS_SEARCH_DIRSONLY 0x00001000
+#define FS_SEARCH_MASK 0x00001f00
// bits 8 - 11, flag
#define FS_FLAG_GZIP 0x00000100
diff --git a/src/common/cmd.c b/src/common/cmd.c
index 9e1fce4..65cfb43 100644
--- a/src/common/cmd.c
+++ b/src/common/cmd.c
@@ -1766,7 +1766,7 @@ static void Cmd_Exec_f(void)
void Cmd_Config_g(genctx_t *ctx)
{
- FS_File_g("", "*.cfg", FS_SEARCH_SAVEPATH | FS_SEARCH_BYFILTER | FS_SEARCH_STRIPEXT, ctx);
+ FS_File_g(NULL, "*.cfg", FS_SEARCH_SAVEPATH | FS_SEARCH_BYFILTER | FS_SEARCH_STRIPEXT, ctx);
}
static void Cmd_Exec_c(genctx_t *ctx, int argnum)
diff --git a/src/common/files.c b/src/common/files.c
index fe3680d..b166bd3 100644
--- a/src/common/files.c
+++ b/src/common/files.c
@@ -2657,15 +2657,15 @@ void **FS_ListFiles(const char *path,
unsigned flags,
int *count_p)
{
- searchpath_t *search;
- packfile_t *file;
- void *files[MAX_LISTED_FILES], *info;
- int i, count, total;
- char normalized[MAX_OSPATH], buffer[MAX_OSPATH];
- void **list;
- size_t len, pathlen;
- char *s, *p;
- int valid;
+ searchpath_t *search;
+ packfile_t *file;
+ void *files[MAX_LISTED_FILES], *info;
+ int i, j, count, total;
+ char normalized[MAX_OSPATH], buffer[MAX_OSPATH];
+ void **list;
+ size_t len, pathlen;
+ char *s, *p;
+ int valid;
count = 0;
valid = PATH_NOT_CHECKED;
@@ -2683,6 +2683,11 @@ void **FS_ListFiles(const char *path,
path = normalized;
}
+ // can't mix directory search with other flags
+ if ((flags & FS_SEARCH_DIRSONLY) && (flags & FS_SEARCH_MASK & ~FS_SEARCH_DIRSONLY)) {
+ goto fail;
+ }
+
for (search = fs_searchpaths; search; search = search->next) {
if (flags & FS_PATH_MASK) {
if ((flags & search->mode & FS_PATH_MASK) == 0) {
@@ -2694,11 +2699,6 @@ void **FS_ListFiles(const char *path,
continue; // don't search in paks
}
- // TODO: add directory search support for pak files
- if (flags & FS_SEARCH_DIRSONLY) {
- continue;
- }
-
for (i = 0; i < search->pack->num_files; i++) {
file = &search->pack->files[i];
s = file->name;
@@ -2712,11 +2712,15 @@ void **FS_ListFiles(const char *path,
continue;
}
if (s[pathlen] != '/') {
- continue; // matched prefix must be a directory
+ continue; // matched prefix must be a directory
}
if (flags & FS_SEARCH_BYFILTER) {
s += pathlen + 1;
}
+ } else if (path == normalized) {
+ if (!(flags & FS_SEARCH_DIRSONLY) && strchr(s, '/')) {
+ continue; // must be a file in the root directory
+ }
}
// check filter
@@ -2732,6 +2736,32 @@ void **FS_ListFiles(const char *path,
}
}
+ // copy name off
+ if (flags & (FS_SEARCH_DIRSONLY | FS_SEARCH_STRIPEXT)) {
+ s = strcpy(buffer, s);
+ }
+
+ // hacky directory search support for pak files
+ if (flags & FS_SEARCH_DIRSONLY) {
+ p = s;
+ if (pathlen) {
+ p += pathlen + 1;
+ }
+ p = strchr(p, '/');
+ if (!p) {
+ continue; // does not have directory component
+ }
+ *p = 0;
+ for (j = 0; j < count; j++) {
+ if (!FS_pathcmp(files[j], s)) {
+ break;
+ }
+ }
+ if (j != count) {
+ continue; // already listed this directory
+ }
+ }
+
// strip path
if (!(flags & FS_SEARCH_SAVEPATH)) {
s = COM_SkipPath(s);
@@ -2739,12 +2769,7 @@ void **FS_ListFiles(const char *path,
// strip extension
if (flags & FS_SEARCH_STRIPEXT) {
- p = COM_FileExtension(s);
- if (*p) {
- len = p - s;
- s = memcpy(buffer, s, len);
- s[len] = 0;
- }
+ *COM_FileExtension(s) = 0;
}
if (!*s) {