summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fileio.cpp95
-rw-r--r--src/fileio.h16
-rw-r--r--src/newgrf_config.cpp89
3 files changed, 127 insertions, 73 deletions
diff --git a/src/fileio.cpp b/src/fileio.cpp
index 8201b7c0f..9e141c6e5 100644
--- a/src/fileio.cpp
+++ b/src/fileio.cpp
@@ -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;
+}
diff --git a/src/fileio.h b/src/fileio.h
index 6d4aed2b4..7c8a80221 100644
--- a/src/fileio.h
+++ b/src/fileio.h
@@ -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 */
diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp
index a8aeb2f63..6faeb8d77 100644
--- a/src/newgrf_config.cpp
+++ b/src/newgrf_config.cpp
@@ -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;