mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Reimplement Sys_ListFiles
and Sys_ListFilteredFiles
They had several bugs, like showing the current and parent directory entires twice, not seeing files but only directories, etc.
This commit is contained in:
parent
92190220aa
commit
6b91846b0c
2 changed files with 312 additions and 268 deletions
|
@ -369,7 +369,9 @@ DIRECTORY SCANNING
|
|||
Sys_ListFilteredFiles
|
||||
==================
|
||||
*/
|
||||
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles )
|
||||
void Sys_ListFilteredFiles(
|
||||
const char *basedir, char *subdirs, char *filter, qboolean wantsubs, char **list, int *numfiles
|
||||
)
|
||||
{
|
||||
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
|
||||
char filename[MAX_OSPATH];
|
||||
|
@ -387,8 +389,7 @@ void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, ch
|
|||
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf(search, sizeof(search), "%s/%s", basedir, subdirs);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Com_sprintf(search, sizeof(search), "%s", basedir);
|
||||
}
|
||||
|
||||
|
@ -397,27 +398,42 @@ void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, ch
|
|||
}
|
||||
|
||||
while ((d = readdir(fdir)) != NULL) {
|
||||
Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
|
||||
if (stat(filename, &st) == -1)
|
||||
// Fixed in OPM:
|
||||
// don't show current and parent dir entries twice
|
||||
if (!(Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..")) && Q_stricmp(d->d_name, "cvs")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (st.st_mode & S_IFDIR) {
|
||||
if (Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..")) {
|
||||
Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
|
||||
if (stat(filename, &st) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((st.st_mode & S_IFDIR) != 0 && wantsubs) {
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
|
||||
}
|
||||
Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
|
||||
}
|
||||
|
||||
// recursively iterate into subdirectory
|
||||
Sys_ListFilteredFiles(basedir, newsubdirs, filter, wantsubs, list, numfiles);
|
||||
}
|
||||
|
||||
if (*numfiles >= MAX_FOUND_FILES - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf(filename, sizeof(filename), "%s/%s", subdirs, d->d_name);
|
||||
if (!Com_FilterPath( filter, filename, qfalse ))
|
||||
} else {
|
||||
Q_strncpyz(filename, d->d_name, sizeof(filename));
|
||||
}
|
||||
|
||||
if (!Com_FilterPath(filter, filename, qfalse)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list[*numfiles] = CopyString(filename);
|
||||
(*numfiles)++;
|
||||
}
|
||||
|
@ -434,26 +450,39 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
{
|
||||
struct dirent *d;
|
||||
DIR *fdir;
|
||||
qboolean dironly = wantsubs;
|
||||
char search[MAX_OSPATH];
|
||||
int nfiles;
|
||||
char **listCopy;
|
||||
char *list[MAX_FOUND_FILES];
|
||||
int i;
|
||||
struct stat st;
|
||||
char buffer[64];
|
||||
|
||||
int extLen;
|
||||
if (directory[0] == '\0') {
|
||||
*numfiles = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!extension) {
|
||||
extension = "";
|
||||
}
|
||||
|
||||
// passing a slash as extension will find directories,
|
||||
// anything else looks only for files with that extension
|
||||
if (!filter && (extension[0] != '/' || extension[1])) {
|
||||
Q_snprintf(buffer, sizeof(buffer), "*%s", extension);
|
||||
filter = buffer;
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
|
||||
nfiles = 0;
|
||||
Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
|
||||
Sys_ListFilteredFiles(directory, "", filter, wantsubs, list, &nfiles);
|
||||
|
||||
list[nfiles] = NULL;
|
||||
*numfiles = nfiles;
|
||||
|
||||
if (!nfiles)
|
||||
if (!nfiles) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listCopy = Z_Malloc((nfiles + 1) * sizeof(*listCopy));
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
|
@ -464,20 +493,7 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
return listCopy;
|
||||
}
|
||||
|
||||
if ( directory[0] == '\0' ) {
|
||||
*numfiles = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !extension)
|
||||
extension = "";
|
||||
|
||||
if ( extension[0] == '/' && extension[1] == 0 ) {
|
||||
extension = "";
|
||||
dironly = qtrue;
|
||||
}
|
||||
|
||||
extLen = strlen( extension );
|
||||
// only enumerate directories from this point onward
|
||||
|
||||
// search
|
||||
nfiles = 0;
|
||||
|
@ -489,23 +505,24 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
|
||||
while ((d = readdir(fdir)) != NULL) {
|
||||
Com_sprintf(search, sizeof(search), "%s/%s", directory, d->d_name);
|
||||
if (stat(search, &st) == -1)
|
||||
if (stat(search, &st) == -1) {
|
||||
continue;
|
||||
if ((dironly && !(st.st_mode & S_IFDIR)) ||
|
||||
(!dironly && (st.st_mode & S_IFDIR)))
|
||||
continue;
|
||||
|
||||
if (*extension) {
|
||||
if ( strlen( d->d_name ) < extLen ||
|
||||
Q_stricmp(
|
||||
d->d_name + strlen( d->d_name ) - extLen,
|
||||
extension ) ) {
|
||||
continue; // didn't match
|
||||
}
|
||||
}
|
||||
|
||||
if ( nfiles == MAX_FOUND_FILES - 1 )
|
||||
// Fixed in OPM:
|
||||
// don't show current and parent dir entries twice
|
||||
if (!(Q_stricmp(d->d_name, ".") && Q_stricmp(d->d_name, "..") && Q_stricmp(d->d_name, "cvs"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((st.st_mode & S_IFDIR) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nfiles == MAX_FOUND_FILES - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
list[nfiles] = CopyString(d->d_name);
|
||||
nfiles++;
|
||||
}
|
||||
|
|
|
@ -477,7 +477,9 @@ DIRECTORY SCANNING
|
|||
Sys_ListFilteredFiles
|
||||
==============
|
||||
*/
|
||||
void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles )
|
||||
void Sys_ListFilteredFiles(
|
||||
const char *basedir, const char *subdirs, char *filter, qboolean wantsubs, char **list, int *numfiles
|
||||
)
|
||||
{
|
||||
char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
|
||||
char filename[MAX_OSPATH];
|
||||
|
@ -494,8 +496,7 @@ void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, ch
|
|||
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf(search, sizeof(search), "%s\\%s\\*", basedir, subdirs);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Com_sprintf(search, sizeof(search), "%s\\*", basedir);
|
||||
}
|
||||
|
||||
|
@ -505,24 +506,45 @@ void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, ch
|
|||
}
|
||||
|
||||
do {
|
||||
if (findinfo.attrib & _A_SUBDIR) {
|
||||
if (Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..")) {
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findinfo.name);
|
||||
// Fixed in OPM:
|
||||
// don't show current and parent dir entries twice
|
||||
if (!(Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..") && Q_stricmp(findinfo.name, "cvs"))) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
if ((findinfo.attrib & _A_SUBDIR) != 0 && wantsubs) {
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s\\%s\\*", subdirs, findinfo.name);
|
||||
} else {
|
||||
Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", findinfo.name);
|
||||
}
|
||||
Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
|
||||
}
|
||||
|
||||
// recursively iterate into subdirectory
|
||||
Sys_ListFilteredFiles(basedir, newsubdirs, filter, wantsubs, list, numfiles);
|
||||
}
|
||||
|
||||
if (*numfiles >= MAX_FOUND_FILES - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (strlen(subdirs)) {
|
||||
Com_sprintf(filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name);
|
||||
if (!Com_FilterPath( filter, filename, qfalse ))
|
||||
} else {
|
||||
Q_strncpyz(filename, findinfo.name, sizeof(filename));
|
||||
}
|
||||
|
||||
if (!Com_FilterPath(filter, filename, qfalse)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list[*numfiles] = CopyString(filename);
|
||||
|
||||
// replace backslashes with forward slashes, if any
|
||||
// FS_ReplaceSeparators would be nice but it does the opposite
|
||||
for (char *c = strchr(list[*numfiles], '\\'); c; c = strchr(list[*numfiles], '\\')) {
|
||||
*c = '/';
|
||||
}
|
||||
|
||||
(*numfiles)++;
|
||||
} while (_findnext(findhandle, &findinfo) != -1);
|
||||
|
||||
|
@ -566,23 +588,38 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
char search[MAX_OSPATH];
|
||||
int nfiles;
|
||||
char **listCopy;
|
||||
char *list[MAX_FOUND_FILES];
|
||||
char *list[MAX_FOUND_FILES] = {NULL};
|
||||
struct _finddata_t findinfo;
|
||||
intptr_t findhandle;
|
||||
int flag;
|
||||
qboolean swapped;
|
||||
int i;
|
||||
int extLen;
|
||||
char buffer[64];
|
||||
|
||||
if (directory[0] == NULL) {
|
||||
*numfiles = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!extension) {
|
||||
extension = "";
|
||||
}
|
||||
|
||||
// passing a slash as extension will find directories,
|
||||
// anything else looks only for files with that extension
|
||||
if (!filter && (extension[0] != '/' || extension[1])) {
|
||||
Q_snprintf(buffer, sizeof(buffer), "*%s", extension);
|
||||
filter = buffer;
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
|
||||
nfiles = 0;
|
||||
Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
|
||||
Sys_ListFilteredFiles(directory, "", filter, wantsubs, list, &nfiles);
|
||||
|
||||
list[ nfiles ] = 0;
|
||||
list[nfiles] = NULL;
|
||||
*numfiles = nfiles;
|
||||
|
||||
if (!nfiles)
|
||||
if (!nfiles) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
listCopy = Z_Malloc((nfiles + 1) * sizeof(*listCopy));
|
||||
for (i = 0; i < nfiles; i++) {
|
||||
|
@ -593,30 +630,11 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
return listCopy;
|
||||
}
|
||||
|
||||
if ( directory[0] == '\0' ) {
|
||||
*numfiles = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !extension) {
|
||||
extension = "";
|
||||
}
|
||||
|
||||
// passing a slash as extension will find directories
|
||||
if ( extension[0] == '/' && extension[1] == 0 ) {
|
||||
extension = "";
|
||||
flag = 0;
|
||||
} else {
|
||||
flag = _A_SUBDIR;
|
||||
}
|
||||
|
||||
extLen = strlen( extension );
|
||||
|
||||
Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension );
|
||||
// only enumerate directories from this point onward
|
||||
Com_sprintf(search, 256, "%s\\*", directory);
|
||||
|
||||
// search
|
||||
nfiles = 0;
|
||||
|
||||
findhandle = _findfirst(search, &findinfo);
|
||||
if (findhandle == -1) {
|
||||
*numfiles = 0;
|
||||
|
@ -624,24 +642,32 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
}
|
||||
|
||||
do {
|
||||
if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) {
|
||||
if (*extension) {
|
||||
if ( strlen( findinfo.name ) < extLen ||
|
||||
Q_stricmp(
|
||||
findinfo.name + strlen( findinfo.name ) - extLen,
|
||||
extension ) ) {
|
||||
continue; // didn't match
|
||||
// Fixed in OPM:
|
||||
// don't show current and parent dir entries twice
|
||||
if (!(Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..") && Q_stricmp(findinfo.name, "cvs"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((findinfo.attrib & _A_SUBDIR) == 0) {
|
||||
continue;
|
||||
}
|
||||
if ( nfiles == MAX_FOUND_FILES - 1 ) {
|
||||
|
||||
if (nfiles >= MAX_FOUND_FILES - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
list[nfiles] = CopyString(findinfo.name);
|
||||
nfiles++;
|
||||
|
||||
// replace backslashes with forward slashes
|
||||
// FS_ReplaceSeparators would be nice but it does the opposite
|
||||
for (char *c = strchr(list[nfiles], '\\'); c; c = strchr(list[nfiles], '\\')) {
|
||||
*c = '/';
|
||||
}
|
||||
|
||||
++nfiles;
|
||||
} while (_findnext(findhandle, &findinfo) != -1);
|
||||
|
||||
list[ nfiles ] = 0;
|
||||
list[nfiles] = NULL;
|
||||
|
||||
_findclose(findhandle);
|
||||
|
||||
|
@ -658,17 +684,18 @@ char **Sys_ListFiles( const char *directory, const char *extension, const char *
|
|||
}
|
||||
listCopy[i] = NULL;
|
||||
|
||||
// bubble-sort name entries alphabetically, in ascending order
|
||||
do {
|
||||
flag = 0;
|
||||
swapped = qfalse;
|
||||
for (i = 1; i < nfiles; i++) {
|
||||
if (strgtr(listCopy[i - 1], listCopy[i])) {
|
||||
char *temp = listCopy[i];
|
||||
listCopy[i] = listCopy[i - 1];
|
||||
listCopy[i - 1] = temp;
|
||||
flag = 1;
|
||||
swapped = qtrue;
|
||||
}
|
||||
}
|
||||
} while(flag);
|
||||
} while (swapped);
|
||||
|
||||
return listCopy;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue