// Filename:- files.h // #include "stdafx.h" #include "includes.h" #include #include "R_Common.h" //#include "R_Image.h" // #include "files.h" /* ============ Com_StringContains ============ */ char *Com_StringContains(char *str1, char *str2, int casesensitive) { int len, i, j; len = strlen(str1) - strlen(str2); for (i = 0; i <= len; i++, str1++) { for (j = 0; str2[j]; j++) { if (casesensitive) { if (str1[j] != str2[j]) { break; } } else { if (toupper(str1[j]) != toupper(str2[j])) { break; } } } if (!str2[j]) { return str1; } } return NULL; } /* ============ Com_Filter ============ */ int Com_Filter(char *filter, char *name, int casesensitive) { char buf[MAX_TOKEN_CHARS]; char *ptr; int i, found; while(*filter) { if (*filter == '*') { filter++; for (i = 0; *filter; i++) { if (*filter == '*' || *filter == '?') break; buf[i] = *filter; filter++; } buf[i] = '\0'; if (strlen(buf)) { ptr = Com_StringContains(name, buf, casesensitive); if (!ptr) return qfalse; name = ptr + strlen(buf); } } else if (*filter == '?') { filter++; name++; } else if (*filter == '[' && *(filter+1) == '[') { filter++; } else if (*filter == '[') { filter++; found = qfalse; while(*filter && !found) { if (*filter == ']' && *(filter+1) != ']') break; if (*(filter+1) == '-' && *(filter+2) && (*(filter+2) != ']' || *(filter+3) == ']')) { if (casesensitive) { if (*name >= *filter && *name <= *(filter+2)) found = qtrue; } else { if (toupper(*name) >= toupper(*filter) && toupper(*name) <= toupper(*(filter+2))) found = qtrue; } filter += 3; } else { if (casesensitive) { if (*filter == *name) found = qtrue; } else { if (toupper(*filter) == toupper(*name)) found = qtrue; } filter++; } } if (!found) return qfalse; while(*filter) { if (*filter == ']' && *(filter+1) != ']') break; filter++; } filter++; name++; } else { if (casesensitive) { if (*filter != *name) return qfalse; } else { if (toupper(*filter) != toupper(*name)) return qfalse; } filter++; name++; } } return qtrue; } /* ============ Com_FilterPath ============ */ int Com_FilterPath(char *filter, char *name, int casesensitive) { int i; char new_filter[MAX_QPATH]; char new_name[MAX_QPATH]; for (i = 0; i < MAX_QPATH-1 && filter[i]; i++) { if ( filter[i] == '\\' || filter[i] == ':' ) { new_filter[i] = '/'; } else { new_filter[i] = filter[i]; } } new_filter[i] = '\0'; for (i = 0; i < MAX_QPATH-1 && name[i]; i++) { if ( name[i] == '\\' || name[i] == ':' ) { new_name[i] = '/'; } else { new_name[i] = name[i]; } } new_name[i] = '\0'; return Com_Filter(new_filter, new_name, casesensitive); } void *Z_Malloc(int size) { return malloc(size); } void Z_Free(void *mem) { free(mem); } void *S_Malloc(int size) { return Z_Malloc(size); } /* ================================================================================= DIRECTORY SCANNING FUNCTIONS ================================================================================= */ #define MAX_FOUND_FILES 0x1000 char *CopyString( const char *in ) { char *out; out = (char *)S_Malloc (strlen(in)+1); strcpy (out, in); return out; } void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **flist, int *numfiles ) { char search[MAX_OSPATH], newsubdirs[MAX_OSPATH]; char filename[MAX_OSPATH]; int findhandle; struct _finddata_t findinfo; if ( *numfiles >= MAX_FOUND_FILES - 1 ) { return; } if (strlen(subdirs)) { Com_sprintf( search, sizeof(search), "%s\\%s\\*", basedir, subdirs ); } else { Com_sprintf( search, sizeof(search), "%s\\*", basedir ); } findhandle = _findfirst (search, &findinfo); if (findhandle == -1) { return; } 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); } else { Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", findinfo.name); } Sys_ListFilteredFiles( basedir, newsubdirs, filter, flist, numfiles ); } } if ( *numfiles >= MAX_FOUND_FILES - 1 ) { break; } Com_sprintf( filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name ); if (!Com_FilterPath( filter, filename, qfalse )) continue; flist[ *numfiles ] = CopyString( filename ); (*numfiles)++; } while ( _findnext (findhandle, &findinfo) != -1 ); _findclose (findhandle); } char **Sys_ListFiles( const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs ) { char search[MAX_OSPATH]; int nfiles; char **listCopy; char *list[MAX_FOUND_FILES]; struct _finddata_t findinfo; int findhandle; int flag; int i; if (filter) { nfiles = 0; Sys_ListFilteredFiles( directory, "", filter, list, &nfiles ); list[ nfiles ] = 0; *numfiles = nfiles; if (!nfiles) return NULL; listCopy = (char **)Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) ); for ( i = 0 ; i < nfiles ; i++ ) { listCopy[i] = list[i]; } listCopy[i] = NULL; return listCopy; } if ( !extension) { extension = ""; } // passing a slash as extension will find directories if ( extension[0] == '/' && extension[1] == 0 ) { extension = ""; flag = 0; } else { flag = _A_SUBDIR; } Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension ); // search nfiles = 0; findhandle = _findfirst (search, &findinfo); if (findhandle == -1) { *numfiles = 0; return NULL; } do { if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) { if ( nfiles == MAX_FOUND_FILES - 1 ) { break; } list[ nfiles ] = CopyString( findinfo.name ); nfiles++; } } while ( _findnext (findhandle, &findinfo) != -1 ); list[ nfiles ] = 0; _findclose (findhandle); // return a copy of the list *numfiles = nfiles; if ( !nfiles ) { return NULL; } listCopy = (char **)Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) ); for ( i = 0 ; i < nfiles ; i++ ) { listCopy[i] = list[i]; } listCopy[i] = NULL; return listCopy; } void Sys_FreeFileList( char **flist ) { int i; if ( !flist ) { return; } for ( i = 0 ; flist[i] ; i++ ) { Z_Free( flist[i] ); } Z_Free( flist ); }