(svn r14196) -Codechange: make the searching for files with a specific extension extendable.

pull/155/head
rubidium 16 years ago
parent 01ce633a93
commit d452683aa6

@ -956,3 +956,98 @@ void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize)
*lenp = len;
return mem;
}
/**
* Scan a single directory (and recursively it's children) and add
* any graphics sets that are found.
* @param extension the extension of files to search for.
* @param path full path we're currently at
* @param basepath_length from where in the path are we 'based' on the search path
*/
static uint ScanPath(FileScanner *fs, const char *extension, const char *path, size_t basepath_length)
{
extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
uint num = 0;
struct stat sb;
struct dirent *dirent;
DIR *dir;
if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0;
while ((dirent = readdir(dir)) != NULL) {
const char *d_name = FS2OTTD(dirent->d_name);
char filename[MAX_PATH];
if (!FiosIsValidFile(path, dirent, &sb)) continue;
snprintf(filename, lengthof(filename), "%s%s", path, d_name);
if (sb.st_mode & S_IFDIR) {
/* Directory */
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
AppendPathSeparator(filename, lengthof(filename));
num += ScanPath(fs, extension, filename, basepath_length);
} else if (sb.st_mode & S_IFREG) {
/* File */
char *ext = strrchr(filename, '.');
/* If no extension or extension isn't .grf, skip the file */
if (ext == NULL) continue;
if (strcasecmp(ext, extension) != 0) continue;
if (fs->AddFile(filename, basepath_length)) num++;
}
}
closedir(dir);
return num;
}
/**
* Scan the given tar and add graphics sets when it finds one.
* @param extension the extension of files to search for.
* @param tar the tar to search in.
*/
static uint ScanTar(FileScanner *fs, const char *extension, TarFileList::iterator tar)
{
uint num = 0;
const char *filename = (*tar).first.c_str();
const char *ext = strrchr(filename, '.');
/* If no extension or extension isn't .grf, skip the file */
if (ext == NULL) return false;
if (strcasecmp(ext, extension) != 0) return false;
if (fs->AddFile(filename, 0)) num++;
return num;
}
/**
* Scan for files with the given extention in the given search path.
* @param extension the extension of files to search for.
* @param sp the sub directory to search in.
* @param tars whether to search in the tars too.
* @return the number of found files, i.e. the number of times that
* AddFile returned true.
*/
uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars)
{
Searchpath sp;
char path[MAX_PATH];
TarFileList::iterator tar;
uint num = 0;
FOR_ALL_SEARCHPATHS(sp) {
FioAppendDirectory(path, MAX_PATH, sp, sd);
num += ScanPath(this, extension, path, strlen(path));
}
FOR_ALL_TARS(tar) {
num += ScanTar(this, extension, tar);
}
return num;
}

@ -96,4 +96,20 @@ bool FileExists(const char *filename);
extern char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc.
/** Helper for scanning for files with a given name */
class FileScanner
{
public:
uint Scan(const char *extension, Subdirectory sd, bool tars = true);
/**
* Add a file with the given filename.
* @param filename the full path to the file to read
* @param basepath_length amount of characters to chop of before to get a
* filename relative to the search path.
* @return true if the file is added.
*/
virtual bool AddFile(const char *filename, size_t basepath_length) = 0;
};
#endif /* FILEIO_H */

@ -15,10 +15,8 @@
#include "gamelog.h"
#include "network/network_type.h"
#include "tar_type.h"
#include "fileio.h"
#include "fios.h"
#include <sys/stat.h>
GRFConfig *_all_grfs;
@ -267,10 +265,23 @@ compatible_grf:
return res;
}
static bool ScanPathAddGrf(const char *filename)
/** Helper for scanning for files with GRF as extension */
class GRFFileScanner : FileScanner {
public:
/* virtual */ bool AddFile(const char *filename, size_t basepath_length);
/** Do the scan for GRFs. */
static uint DoScan()
{
GRFFileScanner fs;
return fs.Scan(".grf", DATA_DIR);
}
};
bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length)
{
GRFConfig *c = CallocT<GRFConfig>(1);
c->filename = strdup(filename);
c->filename = strdup(filename + basepath_length);
bool added = true;
if (FillGRFDetails(c, false)) {
@ -313,63 +324,6 @@ static bool ScanPathAddGrf(const char *filename)
return added;
}
/* Scan a path for NewGRFs */
static uint ScanPath(const char *path, size_t basepath_length)
{
extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
uint num = 0;
struct stat sb;
struct dirent *dirent;
DIR *dir;
if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0;
while ((dirent = readdir(dir)) != NULL) {
const char *d_name = FS2OTTD(dirent->d_name);
char filename[MAX_PATH];
if (!FiosIsValidFile(path, dirent, &sb)) continue;
snprintf(filename, lengthof(filename), "%s%s", path, d_name);
if (sb.st_mode & S_IFDIR) {
/* Directory */
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
AppendPathSeparator(filename, lengthof(filename));
num += ScanPath(filename, basepath_length);
} else if (sb.st_mode & S_IFREG) {
/* File */
char *ext = strrchr(filename, '.');
/* If no extension or extension isn't .grf, skip the file */
if (ext == NULL) continue;
if (strcasecmp(ext, ".grf") != 0) continue;
if (ScanPathAddGrf(filename + basepath_length)) num++;
}
}
closedir(dir);
return num;
}
static uint ScanTar(TarFileList::iterator tar)
{
uint num = 0;
const char *filename = (*tar).first.c_str();
const char *ext = strrchr(filename, '.');
/* If no extension or extension isn't .grf, skip the file */
if (ext == NULL) return false;
if (strcasecmp(ext, ".grf") != 0) return false;
if (ScanPathAddGrf(filename)) num++;
return num;
}
/**
* Simple sorter for GRFS
* @param p1 the first GRFConfig *
@ -388,21 +342,10 @@ static int CDECL GRFSorter(const void *p1, const void *p2)
/* Scan for all NewGRFs */
void ScanNewGRFFiles()
{
Searchpath sp;
char path[MAX_PATH];
TarFileList::iterator tar;
uint num = 0;
ClearGRFConfigList(&_all_grfs);
DEBUG(grf, 1, "Scanning for NewGRFs");
FOR_ALL_SEARCHPATHS(sp) {
FioAppendDirectory(path, MAX_PATH, sp, DATA_DIR);
num += ScanPath(path, strlen(path));
}
FOR_ALL_TARS(tar) {
num += ScanTar(tar);
}
uint num = GRFFileScanner::DoScan();
DEBUG(grf, 1, "Scan complete, found %d files", num);
if (num == 0 || _all_grfs == NULL) return;

Loading…
Cancel
Save