Changeset - r10036:45f5444a2a0e
[Not reviewed]
master
0 3 0
rubidium - 16 years ago 2008-08-31 08:38:30
rubidium@openttd.org
(svn r14196) -Codechange: make the searching for files with a specific extension extendable.
3 files changed with 127 insertions and 73 deletions:
0 comments (0 inline, 0 general)
src/fileio.cpp
Show inline comments
 
@@ -956,3 +956,98 @@ void *ReadFileToMem(const char *filename
 
	*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;
 
}
src/fileio.h
Show inline comments
 
@@ -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 */
src/newgrf_config.cpp
Show inline comments
 
@@ -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 *f
 
	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 *p
 
/* 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;
0 comments (0 inline, 0 general)