/* ============ idCmdSystemLocal::ArgCompletion_FolderExtension ============ */ void idCmdSystemLocal::ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) { int i; idStr string; const char *extension; va_list argPtr; string = args.Argv( 0 ); string += " "; string += args.Argv( 1 ); common->FatalError("idCmdSystemLocal::ArgCompletion_FolderExtension TODO"); #ifdef TODO if ( string.Icmp( completionString ) != 0 ) { idStr parm, path; idFileList *names; completionString = string; completionParms.Clear(); parm = args.Argv( 1 ); parm.ExtractFilePath( path ); if ( stripFolder || path.Length() == 0 ) { path = folder + path; } path.StripTrailing( '/' ); // list folders names = fileSystem->ListFiles( path, "/", true, true ); for ( i = 0; i < names->GetNumFiles(); i++ ) { idStr name = names->GetFile( i ); if ( stripFolder ) { name.Strip( folder ); } else { name.Strip( "/" ); } name = args.Argv( 0 ) + ( " " + name ) + "/"; completionParms.Append( name ); } fileSystem->FreeFileList( names ); // list files va_start( argPtr, stripFolder ); for ( extension = va_arg( argPtr, const char * ); extension; extension = va_arg( argPtr, const char * ) ) { names = fileSystem->ListFiles( path, extension, true, true ); for ( i = 0; i < names->GetNumFiles(); i++ ) { idStr name = names->GetFile( i ); if ( stripFolder ) { name.Strip( folder ); } else { name.Strip( "/" ); } name = args.Argv( 0 ) + ( " " + name ); completionParms.Append( name ); } fileSystem->FreeFileList( names ); } va_end( argPtr ); }
/* ================ Sys_ListFiles ================ */ int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) { struct dirent *d; DIR *fdir; bool dironly = false; char search[MAX_OSPATH]; struct stat st; bool debug; list.Clear(); debug = cvarSystem->GetCVarBool( "fs_debug" ); if (!extension) extension = ""; // passing a slash as extension will find directories if (extension[0] == '/' && extension[1] == 0) { extension = ""; dironly = true; } // search // NOTE: case sensitivity of directory path can screw us up here if ((fdir = opendir(directory)) == NULL) { if (debug) { common->Printf("Sys_ListFiles: opendir %s failed\n", directory); } return -1; } while ((d = readdir(fdir)) != NULL) { idStr::snPrintf(search, sizeof(search), "%s/%s", directory, d->d_name); if (stat(search, &st) == -1) continue; if (!dironly) { idStr look(search); idStr ext; look.ExtractFileExtension(ext); if (extension[0] != '\0' && ext.Icmp(&extension[1]) != 0) { continue; } } if ((dironly && !(st.st_mode & S_IFDIR)) || (!dironly && (st.st_mode & S_IFDIR))) continue; list.Append(d->d_name); } closedir(fdir); if ( debug ) { common->Printf( "Sys_ListFiles: %d entries in %s\n", list.Num(), directory ); } return list.Num(); }
/* ======================== idResourceContainer::ReadManifestFile ======================== */ int idResourceContainer::ReadManifestFile( const char* name, idStrList& list ) { idFile* inFile = fileSystem->OpenFileRead( name ); if( inFile != NULL ) { list.SetGranularity( 16384 ); idStr str; int num; list.Clear(); inFile->ReadBig( num ); for( int i = 0; i < num; i++ ) { inFile->ReadString( str ); list.Append( str ); } delete inFile; } return list.Num(); }
void GetFileList(const char* dir, const char* ext, idStrList& list) { //Recurse Subdirectories idStrList dirList; Sys_ListFiles(dir, "/", dirList); for(int i = 0; i < dirList.Num(); i++) { if(dirList[i] == "." || dirList[i] == "..") { continue; } idStr fullName = va("%s/%s", dir, dirList[i].c_str()); GetFileList(fullName, ext, list); } idStrList fileList; Sys_ListFiles(dir, ext, fileList); for(int i = 0; i < fileList.Num(); i++) { idStr fullName = va("%s/%s", dir, fileList[i].c_str()); list.Append(fullName); } }
void LoadGuiParmExcludeList(idStrList& list) { idStr fileName = "guiparm_exclude.cfg"; const char *buffer = NULL; idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT ); if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) { src.LoadMemory( buffer, strlen(buffer), fileName ); if ( src.IsLoaded() ) { idStr classname; idToken token; while ( src.ReadToken( &token ) ) { list.Append(token); } } fileSystem->FreeFile( (void*)buffer ); } }
/* ============== Sys_ListFiles ============== */ int Sys_ListFiles(const char *directory, const char *extension, idStrList &list) { idStr search; struct _finddata_t findinfo; int findhandle; int flag; if (!extension) { extension = ""; } // passing a slash as extension will find directories if (extension[0] == '/' && extension[1] == 0) { extension = ""; flag = 0; } else { flag = _A_SUBDIR; } sprintf(search, "%s\\*%s", directory, extension); // search list.Clear(); findhandle = _findfirst(search, &findinfo); if (findhandle == -1) { return -1; } do { if (flag ^(findinfo.attrib & _A_SUBDIR)) { list.Append(findinfo.name); } } while (_findnext(findhandle, &findinfo) != -1); _findclose(findhandle); return list.Num(); }
/* ================ Sys_ListFiles ================ */ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list ) { struct dirent* d; DIR* fdir; bool dironly = false; char search[MAX_OSPATH]; struct stat st; bool debug; list.Clear(); debug = cvarSystem->GetCVarBool( "fs_debug" ); // DG: we use fnmatch for shell-style pattern matching // so the pattern should at least contain "*" to match everything, // the extension will be added behind that (if !dironly) idStr pattern( "*" ); // passing a slash as extension will find directories if( extension[0] == '/' && extension[1] == 0 ) { dironly = true; } else { // so we have *<extension>, the same as in the windows code basically pattern += extension; } // DG end // NOTE: case sensitivity of directory path can screw us up here if( ( fdir = opendir( directory ) ) == NULL ) { if( debug ) { common->Printf( "Sys_ListFiles: opendir %s failed\n", directory ); } return -1; } // DG: use readdir_r instead of readdir for thread safety // the following lines are from the readdir_r manpage.. fscking ugly. int nameMax = pathconf( directory, _PC_NAME_MAX ); if( nameMax == -1 ) nameMax = 255; int direntLen = offsetof( struct dirent, d_name ) + nameMax + 1; struct dirent* entry = ( struct dirent* )Mem_Alloc( direntLen, TAG_CRAP ); if( entry == NULL ) { common->Warning( "Sys_ListFiles: Mem_Alloc for entry failed!" ); closedir( fdir ); return 0; } while( readdir_r( fdir, entry, &d ) == 0 && d != NULL ) { // DG end idStr::snPrintf( search, sizeof( search ), "%s/%s", directory, d->d_name ); if( stat( search, &st ) == -1 ) continue; if( !dironly ) { // DG: the original code didn't work because d3 bfg abuses the extension // to match whole filenames and patterns in the savegame-code, not just file extensions... // so just use fnmatch() which supports matching shell wildcard patterns ("*.foo" etc) // if we should ever need case insensitivity, use FNM_CASEFOLD as third flag if( fnmatch( pattern.c_str(), d->d_name, 0 ) != 0 ) continue; // DG end } if( ( dironly && !( st.st_mode & S_IFDIR ) ) || ( !dironly && ( st.st_mode & S_IFDIR ) ) ) continue; list.Append( d->d_name ); } closedir( fdir ); Mem_Free( entry ); if( debug ) { common->Printf( "Sys_ListFiles: %d entries in %s\n", list.Num(), directory ); } return list.Num(); }
/* ============ idCmdSystemLocal::ArgCompletion_FolderExtension ============ */ void idCmdSystemLocal::ArgCompletion_FolderExtension( const idCmdArgs &args, void(*callback)( const char *s ), const char *folder, bool stripFolder, ... ) { int i; idStr string; const char *extension; va_list argPtr; string = args.Argv( 0 ); string += " "; string += args.Argv( 1 ); // taaaki: ensure that we clear the auto-complete list for the (d)map commands in case missions are // installed/uninstalled while the game is running if ( string.Icmp( completionString ) != 0 || string.Icmp( "map " ) == 0 || string.Icmp( "dmap " ) == 0 ) { idStr parm, path; idFileList *names; const char* gamedir = NULL; // check if a fan mission has been set and that the "map" or "dmap" command is being used idStr currFm = cvarSystem->GetCVarString("fs_currentfm"); if ( currFm.Icmp( "darkmod" ) != 0 && ( string.Icmp( "map " ) == 0 || string.Icmp( "dmap " ) == 0 ) ) { gamedir = currFm.c_str(); } completionString = string; completionParms.Clear(); parm = args.Argv( 1 ); parm.ExtractFilePath( path ); if ( stripFolder || path.Length() == 0 ) { path = folder + path; } path.StripTrailing( '/' ); // taaaki: don't include folders if we are looking for the currentfm .map file // this is a bit of a hack :/ if ( !gamedir ) { names = fileSystem->ListFiles( path, "/", true, true, gamedir ); for ( i = 0; i < names->GetNumFiles(); i++ ) { idStr name = names->GetFile( i ); if ( stripFolder ) { name.Strip( folder ); } else { name.Strip( "/" ); } name = args.Argv( 0 ) + ( " " + name ) + "/"; completionParms.Append( name ); } fileSystem->FreeFileList( names ); } // list files va_start( argPtr, stripFolder ); for ( extension = va_arg( argPtr, const char * ); extension; extension = va_arg( argPtr, const char * ) ) { names = fileSystem->ListFiles( path, extension, true, true, gamedir ); for ( i = 0; i < names->GetNumFiles(); i++ ) { idStr name = names->GetFile( i ); if ( stripFolder ) { name.Strip( folder ); } else { name.Strip( "/" ); } name = args.Argv( 0 ) + ( " " + name ); completionParms.Append( name ); } fileSystem->FreeFileList( names ); } va_end( argPtr ); }