mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +00:00
- fixed: The directory scanner for reading a directory into the WAD file system and ScanDirectory were not Unicode capable on Windows.
Both now use the Unicode capable I_Find* interface instead of duplicating all its functionality in multiple platform dependent incarnations.
This commit is contained in:
parent
91589d9799
commit
9e13d3c60d
4 changed files with 86 additions and 211 deletions
|
@ -35,15 +35,11 @@
|
|||
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <fts.h>
|
||||
#endif
|
||||
|
||||
#include "resourcefile.h"
|
||||
#include "cmdlib.h"
|
||||
#include "doomtype.h"
|
||||
#include "i_system.h"
|
||||
|
||||
|
||||
|
||||
|
@ -71,12 +67,13 @@ struct FDirectoryLump : public FResourceLump
|
|||
class FDirectory : public FResourceFile
|
||||
{
|
||||
TArray<FDirectoryLump> Lumps;
|
||||
const bool nosubdir;
|
||||
|
||||
int AddDirectory(const char *dirpath);
|
||||
void AddEntry(const char *fullpath, int size);
|
||||
|
||||
public:
|
||||
FDirectory(const char * dirname);
|
||||
FDirectory(const char * dirname, bool nosubdirflag = false);
|
||||
bool Open(bool quiet);
|
||||
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
|
||||
};
|
||||
|
@ -89,8 +86,8 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FDirectory::FDirectory(const char * directory)
|
||||
: FResourceFile(NULL)
|
||||
FDirectory::FDirectory(const char * directory, bool nosubdirflag)
|
||||
: FResourceFile(NULL), nosubdir(nosubdirflag)
|
||||
{
|
||||
FString dirname;
|
||||
|
||||
|
@ -100,16 +97,15 @@ FDirectory::FDirectory(const char * directory)
|
|||
// Todo for Linux: Resolve the path before using it
|
||||
#endif
|
||||
dirname = directory;
|
||||
#ifdef _WIN32
|
||||
free((void *)directory);
|
||||
#endif
|
||||
FixPathSeperator(dirname);
|
||||
#ifdef _WIN32
|
||||
free((void *)directory);
|
||||
#endif
|
||||
dirname.Substitute("\\", "/");
|
||||
if (dirname[dirname.Len()-1] != '/') dirname += '/';
|
||||
FileName = dirname;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
//==========================================================================
|
||||
//
|
||||
// Windows version
|
||||
|
@ -118,15 +114,15 @@ FDirectory::FDirectory(const char * directory)
|
|||
|
||||
int FDirectory::AddDirectory(const char *dirpath)
|
||||
{
|
||||
struct _finddata_t fileinfo;
|
||||
intptr_t handle;
|
||||
FString dirmatch;
|
||||
void * handle;
|
||||
int count = 0;
|
||||
|
||||
dirmatch = dirpath;
|
||||
FString dirmatch = dirpath;
|
||||
findstate_t find;
|
||||
dirmatch += '*';
|
||||
|
||||
if ((handle = _findfirst(dirmatch, &fileinfo)) == -1)
|
||||
handle = I_FindFirst(dirmatch.GetChars(), &find);
|
||||
if (handle == ((void *)(-1)))
|
||||
{
|
||||
Printf("Could not scan '%s': %s\n", dirpath, strerror(errno));
|
||||
}
|
||||
|
@ -134,113 +130,50 @@ int FDirectory::AddDirectory(const char *dirpath)
|
|||
{
|
||||
do
|
||||
{
|
||||
if (fileinfo.attrib & _A_HIDDEN)
|
||||
// I_FindName only returns the file's name and not its full path
|
||||
auto attr = I_FindAttr(&find);
|
||||
if (attr & FA_HIDDEN)
|
||||
{
|
||||
// Skip hidden files and directories. (Prevents SVN bookkeeping
|
||||
// info from being included.)
|
||||
continue;
|
||||
}
|
||||
if (fileinfo.attrib & _A_SUBDIR)
|
||||
FString fi = I_FindName(&find);
|
||||
if (attr & FA_DIREC)
|
||||
{
|
||||
|
||||
if (fileinfo.name[0] == '.' &&
|
||||
(fileinfo.name[1] == '\0' ||
|
||||
(fileinfo.name[1] == '.' && fileinfo.name[2] == '\0')))
|
||||
if (nosubdir || (fi[0] == '.' &&
|
||||
(fi[1] == '\0' ||
|
||||
(fi[1] == '.' && fi[2] == '\0'))))
|
||||
{
|
||||
// Do not record . and .. directories.
|
||||
continue;
|
||||
}
|
||||
FString newdir = dirpath;
|
||||
newdir << fileinfo.name << '/';
|
||||
newdir << fi << '/';
|
||||
count += AddDirectory(newdir);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strstr(fileinfo.name, ".orig") || strstr(fileinfo.name, ".bak"))
|
||||
if (strstr(fi, ".orig") || strstr(fi, ".bak"))
|
||||
{
|
||||
// We shouldn't add backup files to the lump directory
|
||||
// We shouldn't add backup files to the file system
|
||||
continue;
|
||||
}
|
||||
|
||||
AddEntry(FString(dirpath) + fileinfo.name, fileinfo.size);
|
||||
count++;
|
||||
size_t size = 0;
|
||||
FString fn = FString(dirpath) + fi;
|
||||
if (GetFileInfo(fn, &size, nullptr))
|
||||
{
|
||||
AddEntry(fn, size);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} while (_findnext(handle, &fileinfo) == 0);
|
||||
_findclose(handle);
|
||||
|
||||
} while (I_FindNext (handle, &find) == 0);
|
||||
I_FindClose (handle);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// add_dirs
|
||||
// 4.4BSD version
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FDirectory::AddDirectory(const char *dirpath)
|
||||
{
|
||||
char *argv [2] = { NULL, NULL };
|
||||
argv[0] = new char[strlen(dirpath)+1];
|
||||
strcpy(argv[0], dirpath);
|
||||
FTS *fts;
|
||||
FTSENT *ent;
|
||||
int count = 0;
|
||||
|
||||
fts = fts_open(argv, FTS_LOGICAL, NULL);
|
||||
if (fts == NULL)
|
||||
{
|
||||
Printf("Failed to start directory traversal: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const size_t namepos = strlen(FileName);
|
||||
FString pathfix;
|
||||
|
||||
while ((ent = fts_read(fts)) != NULL)
|
||||
{
|
||||
if (ent->fts_info == FTS_D && ent->fts_name[0] == '.')
|
||||
{
|
||||
// Skip hidden directories. (Prevents SVN bookkeeping
|
||||
// info from being included.)
|
||||
fts_set(fts, ent, FTS_SKIP);
|
||||
}
|
||||
if (ent->fts_info == FTS_D && ent->fts_level == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (ent->fts_info != FTS_F)
|
||||
{
|
||||
// We're only interested in remembering files.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some implementations add an extra separator between
|
||||
// root of the hierarchy and entity's path.
|
||||
// It needs to be removed in order to resolve
|
||||
// lumps' relative paths properly.
|
||||
const char* path = ent->fts_path;
|
||||
|
||||
if ('/' == path[namepos])
|
||||
{
|
||||
pathfix = FString(path, namepos);
|
||||
pathfix.AppendCStrPart(&path[namepos + 1], ent->fts_pathlen - namepos - 1);
|
||||
|
||||
path = pathfix.GetChars();
|
||||
}
|
||||
|
||||
AddEntry(path, ent->fts_statp->st_size);
|
||||
count++;
|
||||
}
|
||||
fts_close(fts);
|
||||
delete[] argv[0];
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -371,6 +371,8 @@ FImageSource * FImageSource::GetImage(int lumpnum, ETextureType usetype)
|
|||
if (ImageForLump[lumpnum] != nullptr) return ImageForLump[lumpnum];
|
||||
|
||||
auto data = Wads.OpenLumpReader(lumpnum);
|
||||
if (!data.isOpen())
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < countof(CreateInfo); i++)
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#endif
|
||||
#endif
|
||||
#include "cmdlib.h"
|
||||
#include "i_system.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -192,13 +193,41 @@ bool DirEntryExists(const char *pathname, bool *isdir)
|
|||
#else
|
||||
// Windows must use the wide version of stat to preserve non-standard paths.
|
||||
auto wstr = WideString(pathname);
|
||||
struct _stat64i32 info;
|
||||
bool res = _wstat64i32(wstr.c_str(), &info) == 0;
|
||||
struct _stat64 info;
|
||||
bool res = _wstat64(wstr.c_str(), &info) == 0;
|
||||
#endif
|
||||
if (isdir) *isdir = !!(info.st_mode & S_IFDIR);
|
||||
return res;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DirEntryExists
|
||||
//
|
||||
// Returns true if the given path exists, be it a directory or a file.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool GetFileInfo(const char* pathname, size_t *size, time_t *time)
|
||||
{
|
||||
if (pathname == NULL || *pathname == 0)
|
||||
return false;
|
||||
|
||||
#ifndef _WIN32
|
||||
struct stat info;
|
||||
bool res = stat(pathname, &info) == 0;
|
||||
#else
|
||||
// Windows must use the wide version of stat to preserve non-standard paths.
|
||||
auto wstr = WideString(pathname);
|
||||
struct _stat64 info;
|
||||
bool res = _wstat64(wstr.c_str(), &info) == 0;
|
||||
#endif
|
||||
if (!res || (info.st_mode & S_IFDIR)) return false;
|
||||
if (size) *size = info.st_size;
|
||||
if (time) *time = info.st_mtime;
|
||||
return res;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DefaultExtension -- FString version
|
||||
|
@ -269,7 +298,7 @@ FString ExtractFileBase (const char *path, bool include_extension)
|
|||
src--;
|
||||
|
||||
// Check for files with drive specification but no path
|
||||
#if defined(_WIN32) || defined(DOS)
|
||||
#if defined(_WIN32)
|
||||
if (src == path && src[0] != 0)
|
||||
{
|
||||
if (src[1] == ':')
|
||||
|
@ -828,8 +857,6 @@ FString NicePath(const char *path)
|
|||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanDirectory
|
||||
|
@ -838,13 +865,13 @@ FString NicePath(const char *path)
|
|||
|
||||
bool ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
||||
{
|
||||
struct _finddata_t fileinfo;
|
||||
intptr_t handle;
|
||||
findstate_t find;
|
||||
FString dirmatch;
|
||||
|
||||
dirmatch << dirpath << "*";
|
||||
|
||||
if ((handle = _findfirst(dirmatch, &fileinfo)) == -1)
|
||||
auto handle = I_FindFirst(dirmatch.GetChars(), &find);
|
||||
if (handle == ((void*)(-1)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -852,25 +879,27 @@ bool ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
|||
{
|
||||
do
|
||||
{
|
||||
if (fileinfo.attrib & _A_HIDDEN)
|
||||
auto attr = I_FindAttr(&find);
|
||||
if (attr & FA_HIDDEN)
|
||||
{
|
||||
// Skip hidden files and directories. (Prevents SVN bookkeeping
|
||||
// info from being included.)
|
||||
continue;
|
||||
}
|
||||
auto fn = I_FindName(&find);
|
||||
|
||||
if (fileinfo.attrib & _A_SUBDIR)
|
||||
if (attr & FA_DIREC)
|
||||
{
|
||||
if (fileinfo.name[0] == '.' &&
|
||||
(fileinfo.name[1] == '\0' ||
|
||||
(fileinfo.name[1] == '.' && fileinfo.name[2] == '\0')))
|
||||
if (fn[0] == '.' &&
|
||||
(fn[1] == '\0' ||
|
||||
(fn[1] == '.' && fn[2] == '\0')))
|
||||
{
|
||||
// Do not record . and .. directories.
|
||||
continue;
|
||||
}
|
||||
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << fileinfo.name;
|
||||
FFileList* fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << fn;
|
||||
fl->isDirectory = true;
|
||||
FString newdir = fl->Filename;
|
||||
newdir << "/";
|
||||
|
@ -878,107 +907,17 @@ bool ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
|||
}
|
||||
else
|
||||
{
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << fileinfo.name;
|
||||
FFileList* fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << fn;
|
||||
fl->isDirectory = false;
|
||||
}
|
||||
}
|
||||
while (_findnext(handle, &fileinfo) == 0);
|
||||
_findclose(handle);
|
||||
while (I_FindNext(handle, &find) == 0);
|
||||
I_FindClose(handle);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(__sun) || defined(__linux__)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanDirectory
|
||||
// Solaris version
|
||||
//
|
||||
// Given NULL-terminated array of directory paths, create trees for them.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
||||
{
|
||||
DIR *directory = opendir(dirpath);
|
||||
if(directory == NULL)
|
||||
return false;
|
||||
|
||||
struct dirent *file;
|
||||
while((file = readdir(directory)) != NULL)
|
||||
{
|
||||
if(file->d_name[0] == '.') //File is hidden or ./.. directory so ignore it.
|
||||
continue;
|
||||
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename << dirpath << file->d_name;
|
||||
|
||||
fl->isDirectory = DirExists(fl->Filename);
|
||||
if(fl->isDirectory)
|
||||
{
|
||||
FString newdir = fl->Filename;
|
||||
newdir += "/";
|
||||
ScanDirectory(list, newdir);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(directory);
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ScanDirectory
|
||||
// 4.4BSD version
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool ScanDirectory(TArray<FFileList> &list, const char *dirpath)
|
||||
{
|
||||
char * const argv[] = {new char[strlen(dirpath)+1], NULL };
|
||||
memcpy(argv[0], dirpath, strlen(dirpath)+1);
|
||||
FTS *fts;
|
||||
FTSENT *ent;
|
||||
|
||||
fts = fts_open(argv, FTS_LOGICAL, NULL);
|
||||
if (fts == NULL)
|
||||
{
|
||||
delete[] argv[0];
|
||||
return false;
|
||||
}
|
||||
while ((ent = fts_read(fts)) != NULL)
|
||||
{
|
||||
if (ent->fts_info == FTS_D && ent->fts_name[0] == '.')
|
||||
{
|
||||
// Skip hidden directories. (Prevents SVN bookkeeping
|
||||
// info from being included.)
|
||||
fts_set(fts, ent, FTS_SKIP);
|
||||
}
|
||||
if (ent->fts_info == FTS_D && ent->fts_level == 0)
|
||||
{
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename = ent->fts_path;
|
||||
fl->isDirectory = true;
|
||||
}
|
||||
if (ent->fts_info == FTS_F)
|
||||
{
|
||||
// We're only interested in remembering files.
|
||||
FFileList *fl = &list[list.Reserve(1)];
|
||||
fl->Filename = ent->fts_path;
|
||||
fl->isDirectory = false;
|
||||
}
|
||||
}
|
||||
fts_close(fts);
|
||||
delete[] argv[0];
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -30,6 +30,7 @@ typedef struct _GUID
|
|||
bool FileExists (const char *filename);
|
||||
bool DirExists(const char *filename);
|
||||
bool DirEntryExists (const char *pathname, bool *isdir = nullptr);
|
||||
bool GetFileInfo(const char* pathname, size_t* size, time_t* time);
|
||||
|
||||
extern FString progdir;
|
||||
|
||||
|
|
Loading…
Reference in a new issue