mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 11:28:56 +00:00
Consolidate case-sensitive filesystem functions
Descent 3 is case-insensitive. It doesn’t matter if a file is named “ppics.hog” or “PPPICS.HOG”. Descent 3 will load the file regardless. In order to accomplish this, Descent 3 has to have special code for case-sensitive filesystems. That code must take a fake case-insensitive path and turn it into a real case-sensitive path. Before this change, there was multiple chunks of code that helped turn fake case-insensitive paths into real case-sensitive paths. There was cf_FindRealFileNameCaseInsenstive(), mve_FindMovieFileRealName() and a chunk of code in open_file_in_directory() that only exists if __LINUX__ is defined. This removes each of those pieces of code and replaces them with a new cf_LocatePath() function. Using the new cf_LocatePath() function has two main advantages over the old way of doing things. First, having a single function is simpler than having three different pieces of code. Second, the new cf_LocatePath() function will make it easier to create a future commit. That future commit will make Descent 3 look for files in more than just the -setdir directory. Having a single function that’s responsible for determining the true path of a file will make it much easier to create that future commit.
This commit is contained in:
parent
fc5f732347
commit
9d08314986
@ -565,7 +565,7 @@ bool InitGameModule(const char *name, module *mod) {
|
||||
std::filesystem::path dll_name;
|
||||
std::filesystem::path tmp_dll_name;
|
||||
// Make the hog filename
|
||||
lib_name = Base_directory / "netgames" / name;
|
||||
lib_name = std::filesystem::path("netgames") / name;
|
||||
lib_name.replace_extension(".d3m");
|
||||
// Make the dll filename
|
||||
dll_name = name;
|
||||
|
@ -921,7 +921,7 @@ bool LoadMission(const char *mssn) {
|
||||
|
||||
if (IS_MN3_FILE(mssn)) {
|
||||
strcpy(mission, mssn);
|
||||
ddio_MakePath(pathname, D3MissionsDir, mission, NULL);
|
||||
ddio_MakePath(pathname, "missions", mission, NULL);
|
||||
} else {
|
||||
strcpy(mission, mssn);
|
||||
strcpy(pathname, mssn);
|
||||
@ -1645,9 +1645,7 @@ void DoMissionMovie(const char *movie) {
|
||||
return;
|
||||
#endif
|
||||
if (movie && *movie) {
|
||||
char mpath[_MAX_PATH];
|
||||
ddio_MakePath(mpath, LocalD3Dir, "movies", movie, NULL);
|
||||
PlayMovie(mpath);
|
||||
PlayMovie(movie);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1835,11 +1833,11 @@ bool mn3_Open(const char *mn3file) {
|
||||
char voice_hog[_MAX_PATH*2];
|
||||
if ((stricmp(filename, "d3") == 0) || (stricmp(filename, "training") == 0)) {
|
||||
// Open audio hog file
|
||||
ddio_MakePath(voice_hog, D3MissionsDir, "d3voice1.hog", nullptr); // Audio for levels 1-4
|
||||
ddio_MakePath(voice_hog, "missions", "d3voice1.hog", nullptr); // Audio for levels 1-4
|
||||
Mission_voice_hog_handle = cf_OpenLibrary(voice_hog);
|
||||
} else if (stricmp(filename, "d3_2") == 0) {
|
||||
// Open audio hog file
|
||||
ddio_MakePath(voice_hog, D3MissionsDir, "d3voice2.hog", nullptr); // Audio for levels 5-17
|
||||
ddio_MakePath(voice_hog, "missions", "d3voice2.hog", nullptr); // Audio for levels 5-17
|
||||
Mission_voice_hog_handle = cf_OpenLibrary(voice_hog);
|
||||
}
|
||||
strcat(filename, ".gam");
|
||||
@ -1855,7 +1853,7 @@ bool mn3_GetInfo(const char *mn3file, tMissionInfo *msn) {
|
||||
char pathname[_MAX_PATH];
|
||||
char filename[PSFILENAME_LEN + 1];
|
||||
|
||||
ddio_MakePath(pathname, D3MissionsDir, mn3file, nullptr);
|
||||
ddio_MakePath(pathname, "missions", mn3file, nullptr);
|
||||
handle = cf_OpenLibrary(pathname);
|
||||
if (handle == 0) {
|
||||
LOG_ERROR << "MISSION: MN3 failed to open.";
|
||||
|
@ -132,9 +132,7 @@ bool PPic_InitDatabase(void) {
|
||||
|
||||
// attempt to open the hog database
|
||||
// --------------------------------
|
||||
char fullpath[_MAX_PATH];
|
||||
ddio_MakePath(fullpath, LocalD3Dir, PILOTPIC_DATABASE_HOG, NULL);
|
||||
PilotPic_database_hog_handle = cf_OpenLibrary(fullpath);
|
||||
PilotPic_database_hog_handle = cf_OpenLibrary(PILOTPIC_DATABASE_HOG);
|
||||
|
||||
if (PilotPic_database_hog_handle == 0) {
|
||||
// there was an error opening the hog database
|
||||
|
@ -71,47 +71,11 @@ void mve_SetCallback(MovieFrameCallback_fp callBack) {
|
||||
// used to tell movie library how to render movies.
|
||||
void mve_SetRenderProperties(int16_t x, int16_t y, int16_t w, int16_t h, renderer_type type, bool hicolor) {}
|
||||
|
||||
#if defined(POSIX)
|
||||
// locates the case-sensitive movie file name
|
||||
std::filesystem::path mve_FindMovieFileRealName(const std::filesystem::path &movie) {
|
||||
// split into directory and file...
|
||||
std::filesystem::path t_file = movie.filename();
|
||||
std::filesystem::path t_dir = movie.parent_path();
|
||||
std::filesystem::path t_out;
|
||||
|
||||
// found a directory?
|
||||
if (!t_dir.empty()) {
|
||||
// map the bits (or fail)
|
||||
t_out = cf_FindRealFileNameCaseInsensitive(t_file, t_dir);
|
||||
if (t_out.empty())
|
||||
return t_out;
|
||||
// re-assemble
|
||||
return (t_dir / t_out);
|
||||
} else {
|
||||
// just a file, map that
|
||||
t_out = cf_FindRealFileNameCaseInsensitive(t_file);
|
||||
if (t_out.empty())
|
||||
return t_out;
|
||||
// re-assemble
|
||||
return t_out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// plays a movie using the current screen.
|
||||
int mve_PlayMovie(const std::filesystem::path &pMovieName, oeApplication *pApp) {
|
||||
#ifndef NO_MOVIES
|
||||
// first, find that movie..
|
||||
std::filesystem::path real_name;
|
||||
#if defined(POSIX)
|
||||
real_name = mve_FindMovieFileRealName(pMovieName);
|
||||
if (real_name.empty()) {
|
||||
LOG_WARNING.printf("MOVIE: No such file %s", pMovieName.u8string().c_str());
|
||||
return MVELIB_FILE_ERROR;
|
||||
}
|
||||
#else
|
||||
real_name = pMovieName;
|
||||
#endif
|
||||
std::filesystem::path real_name = cf_LocatePath("movies" / pMovieName);
|
||||
// open movie file.
|
||||
FILE *hFile = fopen(real_name.u8string().c_str(), "rb");
|
||||
if (hFile == nullptr) {
|
||||
@ -354,17 +318,7 @@ void CallbackShowFrameNoFlip(unsigned char *buf, unsigned int bufw, unsigned int
|
||||
intptr_t mve_SequenceStart(const char *mvename, void *fhandle, oeApplication *app, bool looping) {
|
||||
#ifndef NO_MOVIES
|
||||
// first, find that movie..
|
||||
std::filesystem::path real_name;
|
||||
#if defined(POSIX)
|
||||
real_name = mve_FindMovieFileRealName(mvename);
|
||||
if (real_name.empty()) {
|
||||
LOG_WARNING.printf("MOVIE: No such file %s", mvename);
|
||||
fhandle = nullptr;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
real_name = mvename;
|
||||
#endif
|
||||
std::filesystem::path real_name = cf_LocatePath(std::filesystem::path("movies") / mvename);
|
||||
fhandle = fopen(real_name.u8string().c_str(), "rb");
|
||||
|
||||
if (fhandle == nullptr) {
|
||||
|
@ -490,7 +490,7 @@ void Descent3() {
|
||||
};
|
||||
|
||||
for (auto const &intro : intros) {
|
||||
PlayMovie(Base_directory / "movies" / intro);
|
||||
PlayMovie(intro);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1311,10 +1311,10 @@ void CheckHogfile() {
|
||||
if (new_mn3) {
|
||||
// close the mission hog file and open the new one
|
||||
mn3_Close();
|
||||
char hogpath[_MAX_PATH * 2];
|
||||
ddio_MakePath(hogpath, D3MissionsDir, new_mn3, nullptr);
|
||||
if (cfexist(hogpath)) {
|
||||
mn3_Open(hogpath);
|
||||
auto relative_path = std::filesystem::path("missions") / new_mn3;
|
||||
auto absolute_path = cf_LocatePath(relative_path);
|
||||
if (std::filesystem::exists(absolute_path)) {
|
||||
mn3_Open(relative_path.u8string().c_str());
|
||||
mem_free(Current_mission.filename);
|
||||
Current_mission.filename = mem_strdup(new_mn3);
|
||||
} else {
|
||||
|
@ -124,7 +124,7 @@ int gspy_Init() {
|
||||
}
|
||||
|
||||
// Read the config, resolve the name if needed and setup the server addresses
|
||||
cfgpath = Base_directory / gspy_cfgfilename;
|
||||
cfgpath = cf_LocatePath(gspy_cfgfilename);
|
||||
|
||||
gspy_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
|
@ -1465,42 +1465,36 @@ void InitIOSystems(bool editor) {
|
||||
// Init hogfiles
|
||||
INIT_MESSAGE(("Checking for HOG files."));
|
||||
int d3_hid, extra_hid, sys_hid, extra13_hid;
|
||||
char fullname[_MAX_PATH];
|
||||
std::filesystem::path hog_name;
|
||||
|
||||
#ifdef DEMO
|
||||
// DAJ d3_hid = cf_OpenLibrary("d3demo.hog");
|
||||
ddio_MakePath(fullname, LocalD3Dir, "d3demo.hog", NULL);
|
||||
hog_name = "d3demo.hog";
|
||||
#else
|
||||
ddio_MakePath(fullname, LocalD3Dir, "d3.hog", NULL);
|
||||
hog_name = "d3.hog";
|
||||
#endif
|
||||
d3_hid = cf_OpenLibrary(fullname);
|
||||
d3_hid = cf_OpenLibrary(hog_name);
|
||||
|
||||
// JC: Steam release uses extra1.hog instead of extra.hog, so try loading it first
|
||||
// Open this file if it's present for stuff we might add later
|
||||
ddio_MakePath(fullname, LocalD3Dir, "extra1.hog", NULL);
|
||||
extra_hid = cf_OpenLibrary(fullname);
|
||||
extra_hid = cf_OpenLibrary("extra1.hog");
|
||||
if (extra_hid == 0) {
|
||||
ddio_MakePath(fullname, LocalD3Dir, "extra.hog", NULL);
|
||||
extra_hid = cf_OpenLibrary(fullname);
|
||||
extra_hid = cf_OpenLibrary("extra.hog");
|
||||
}
|
||||
|
||||
// JC: Steam release uses extra.hog instead of merc.hog, so try loading it last (so we don't conflict with the above)
|
||||
// Open mercenary hog if it exists
|
||||
ddio_MakePath(fullname, LocalD3Dir, "merc.hog", NULL);
|
||||
merc_hid = cf_OpenLibrary(fullname);
|
||||
merc_hid = cf_OpenLibrary("merc.hog");
|
||||
if (merc_hid == 0) {
|
||||
ddio_MakePath(fullname, LocalD3Dir, "extra.hog", NULL);
|
||||
merc_hid = cf_OpenLibrary(fullname);
|
||||
merc_hid = cf_OpenLibrary("extra.hog");
|
||||
}
|
||||
|
||||
// Open this for extra 1.3 code (Black Pyro, etc)
|
||||
ddio_MakePath(fullname, LocalD3Dir, "extra13.hog", NULL);
|
||||
extra13_hid = cf_OpenLibrary(fullname);
|
||||
extra13_hid = cf_OpenLibrary("extra13.hog");
|
||||
|
||||
// last library opened is the first to be searched for dynamic libs, so put
|
||||
// this one at the end to find our newly build script libraries first
|
||||
ddio_MakePath(fullname, LocalD3Dir, PRIMARY_HOG, NULL);
|
||||
sys_hid = cf_OpenLibrary(fullname);
|
||||
sys_hid = cf_OpenLibrary(PRIMARY_HOG);
|
||||
|
||||
// Check to see if there is a -mission command line option
|
||||
// if there is, attempt to open that hog/mn3 so it can override such
|
||||
|
@ -330,9 +330,7 @@ void mmInterface::Create() {
|
||||
m_movie = NULL;
|
||||
static_menu_background = true;
|
||||
} else {
|
||||
char filename[_MAX_PATH];
|
||||
ddio_MakePath(filename, Base_directory.u8string().c_str(), "movies", "mainmenu", NULL);
|
||||
m_movie = StartMovie(filename, true);
|
||||
m_movie = StartMovie("mainmenu", true);
|
||||
|
||||
if (!m_movie) //[ISB] Didn't find the menu movie?
|
||||
{
|
||||
|
@ -608,7 +608,7 @@ int LoadMultiDLL(const char *name) {
|
||||
});
|
||||
|
||||
// Make the hog filename
|
||||
lib_name = Base_directory / "online" / name;
|
||||
lib_name = std::filesystem::path("online") / name;
|
||||
lib_name.replace_extension(".d3c");
|
||||
// Make the dll filename
|
||||
dll_name = name;
|
||||
|
159
cfile/cfile.cpp
159
cfile/cfile.cpp
@ -78,6 +78,68 @@ void cf_SetBaseDirectory(const std::filesystem::path &base_directory) {
|
||||
Base_directory = base_directory;
|
||||
}
|
||||
|
||||
std::filesystem::path cf_LocatePathCaseInsensitiveHelper(const std::filesystem::path &relative_path) {
|
||||
#ifdef WIN32
|
||||
std::filesystem::path result = Base_directory / relative_path;
|
||||
if (std::filesystem::exists(result)) {
|
||||
return result;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
#else
|
||||
auto &starting_dir = Base_directory;
|
||||
// Dumb check, maybe there already all ok?
|
||||
if (exists((starting_dir / relative_path))) {
|
||||
return starting_dir / relative_path;
|
||||
}
|
||||
|
||||
std::filesystem::path result, search_path, search_file;
|
||||
|
||||
search_path = starting_dir / relative_path.parent_path();
|
||||
search_file = relative_path.filename();
|
||||
|
||||
// If directory does not exist, nothing to search.
|
||||
if (!std::filesystem::is_directory(search_path) || search_file.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
// Search component in search_path
|
||||
auto const &it = std::filesystem::directory_iterator(search_path);
|
||||
|
||||
auto found = std::find_if(it, end(it), [&search_file, &search_path, &result](const auto& dir_entry) {
|
||||
return stricmp(dir_entry.path().filename().u8string().c_str(), search_file.u8string().c_str()) == 0;
|
||||
});
|
||||
|
||||
if (found != end(it)) {
|
||||
// Match, append to result
|
||||
result = found->path();
|
||||
search_path = result;
|
||||
} else {
|
||||
// Component not found, mission failed
|
||||
return {};
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find a relative path inside of Base_directory.
|
||||
*
|
||||
* @param relative_path A relative path that we’ll hopefully find in
|
||||
* Base_directory. You don’t have to get the capitalization
|
||||
* of relative_path correct, even on macOS and Linux.
|
||||
*
|
||||
* @return If the path is found, an absolute path that’s inside
|
||||
* Base_directory. Otherwise, a path that probably doesn’t exist
|
||||
* will be returned.
|
||||
*/
|
||||
std::filesystem::path cf_LocatePath(const std::filesystem::path &relative_path) {
|
||||
ASSERT(("realative_path should be a relative path.", relative_path.is_relative()));
|
||||
return cf_LocatePathCaseInsensitiveHelper(relative_path);
|
||||
}
|
||||
|
||||
// Generates a cfile error
|
||||
void ThrowCFileError(int type, CFILE *file, const char *msg) {
|
||||
cfe.read_write = type;
|
||||
@ -92,9 +154,9 @@ static void cf_Close();
|
||||
static CFILE *open_file_in_lib(const char *filename);
|
||||
|
||||
// Opens a HOG file. Future calls to cfopen(), etc. will look in this HOG.
|
||||
// Parameters: libname - the path & filename of the HOG file
|
||||
// NOTE: libname must be valid for the entire execution of the program. Therefore, it should either
|
||||
// be a fully-specified path name, or the current directory must not change.
|
||||
// Parameters: libname - path to the HOG file, relative to Base_directory.
|
||||
// NOTE: libname must be valid for the entire execution of the program. Therefore, Base_directory
|
||||
// must not change.
|
||||
// Returns: 0 if error, else library handle that can be used to close the library
|
||||
int cf_OpenLibrary(const std::filesystem::path &libname) {
|
||||
FILE *fp;
|
||||
@ -106,25 +168,7 @@ int cf_OpenLibrary(const std::filesystem::path &libname) {
|
||||
|
||||
// allocation library structure
|
||||
std::shared_ptr<library> lib = std::make_shared<library>();
|
||||
|
||||
// resolve library name
|
||||
std::filesystem::path resolve_dir = libname.parent_path();
|
||||
std::filesystem::path resolve_name = libname;
|
||||
|
||||
if (!resolve_dir.empty()) {
|
||||
resolve_name = libname.filename();
|
||||
}
|
||||
|
||||
std::filesystem::path t_out = cf_FindRealFileNameCaseInsensitive(resolve_name, resolve_dir);
|
||||
if (t_out.empty()) {
|
||||
return 0; // CF_NO_FILE
|
||||
}
|
||||
// re-assemble
|
||||
if (!resolve_dir.empty())
|
||||
lib->name = resolve_dir / t_out;
|
||||
else
|
||||
lib->name = t_out;
|
||||
|
||||
lib->name = cf_LocatePath(libname);
|
||||
fp = fopen(lib->name.u8string().c_str(), "rb");
|
||||
if (fp == nullptr) {
|
||||
return 0; // CF_NO_FILE;
|
||||
@ -363,42 +407,6 @@ CFILE *open_file_in_lib(const char *filename) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::filesystem::path cf_FindRealFileNameCaseInsensitive(const std::filesystem::path &relative_path,
|
||||
const std::filesystem::path &starting_dir) {
|
||||
// Dumb check, maybe there already all ok?
|
||||
if (exists((starting_dir / relative_path))) {
|
||||
return relative_path.filename();
|
||||
}
|
||||
|
||||
std::filesystem::path result, search_path, search_file;
|
||||
|
||||
search_path = starting_dir / relative_path.parent_path();
|
||||
search_file = relative_path.filename();
|
||||
|
||||
// If directory does not exist, nothing to search.
|
||||
if (!std::filesystem::is_directory(search_path) || search_file.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Search component in search_path
|
||||
auto const &it = std::filesystem::directory_iterator(search_path);
|
||||
|
||||
auto found = std::find_if(it, end(it), [&search_file, &search_path, &result](const auto &dir_entry) {
|
||||
return stricmp(dir_entry.path().filename().u8string().c_str(), search_file.u8string().c_str()) == 0;
|
||||
});
|
||||
|
||||
if (found != end(it)) {
|
||||
// Match, append to result
|
||||
result = found->path();
|
||||
search_path = result;
|
||||
} else {
|
||||
// Component not found, mission failed
|
||||
return {};
|
||||
}
|
||||
|
||||
return result.filename();
|
||||
}
|
||||
|
||||
// look for the file in the specified directory
|
||||
static CFILE *open_file_in_directory(const std::filesystem::path &filename, const char *mode,
|
||||
const std::filesystem::path &directory);
|
||||
@ -413,9 +421,12 @@ CFILE *open_file_in_directory(const std::filesystem::path &filename, const char
|
||||
if (std::filesystem::is_directory(directory)) {
|
||||
// Make a full path
|
||||
using_filename = directory / filename;
|
||||
} else {
|
||||
// no directory specified, so just use filename passed
|
||||
} else if (filename.is_absolute()) {
|
||||
// no directory specified, and filename is an absolute path
|
||||
using_filename = filename;
|
||||
} else {
|
||||
// no directory specified, and filename is a relative path
|
||||
using_filename = cf_LocatePath(filename);
|
||||
}
|
||||
|
||||
// set read or write mode
|
||||
@ -426,34 +437,8 @@ CFILE *open_file_in_directory(const std::filesystem::path &filename, const char
|
||||
fp = fopen(using_filename.u8string().c_str(), tmode);
|
||||
|
||||
if (!fp) {
|
||||
#if defined(POSIX)
|
||||
// If we tried to open file for reading, assume there maybe case-sensitive files
|
||||
if (tmode[0] == 'r') {
|
||||
// Try different cases of the filename
|
||||
using_filename = cf_FindRealFileNameCaseInsensitive(filename, directory);
|
||||
if (using_filename.empty()) {
|
||||
// just give up
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (std::filesystem::is_directory(directory)) {
|
||||
// Make a full path
|
||||
using_filename = directory / using_filename;
|
||||
}
|
||||
|
||||
fp = fopen(using_filename.u8string().c_str(), tmode);
|
||||
if (!fp) {
|
||||
// no dice
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// Error on writing file
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
// We on incase-sensitive filesystem, no file means no file.
|
||||
// File not found
|
||||
return nullptr;
|
||||
#endif
|
||||
} else {
|
||||
using_filename = filename;
|
||||
}
|
||||
|
@ -148,13 +148,24 @@ extern std::filesystem::path Base_directory;
|
||||
*/
|
||||
void cf_SetBaseDirectory(const std::filesystem::path &base_directory);
|
||||
|
||||
/**
|
||||
* Tries to find a relative path inside of Base_directory.
|
||||
*
|
||||
* @param relative_path A relative path that we’ll hopefully find in
|
||||
* Base_directory. You don’t have to get the capitalization
|
||||
* of relative_path correct, even on macOS and Linux.
|
||||
*
|
||||
* @return An absolute path that’s inside Base_directory.
|
||||
*/
|
||||
std::filesystem::path cf_LocatePath(const std::filesystem::path &relative_path);
|
||||
|
||||
// See if a file is in a hog
|
||||
bool cf_IsFileInHog(const std::filesystem::path &filename, const std::filesystem::path &hogname);
|
||||
|
||||
// Opens a HOG file. Future calls to cfopen(), etc. will look in this HOG.
|
||||
// Parameters: libname - the path & filename of the HOG file
|
||||
// NOTE: libname must be valid for the entire execution of the program. Therefore, it should either
|
||||
// be a fully-specified path name, or the current directory must not change.
|
||||
// Parameters: libname - path to the HOG file, relative to Base_directory.
|
||||
// NOTE: libname must be valid for the entire execution of the program. Therefore, Base_directory
|
||||
// must not change.
|
||||
// Returns: 0 if error, else library handle that can be used to close the library
|
||||
int cf_OpenLibrary(const std::filesystem::path &libname);
|
||||
|
||||
@ -162,17 +173,6 @@ int cf_OpenLibrary(const std::filesystem::path &libname);
|
||||
// Parameters: handle: the handle returned by cf_OpenLibrary()
|
||||
void cf_CloseLibrary(int handle);
|
||||
|
||||
/**
|
||||
* Returns fixed case file name to actual case on disk for case-sensitive filesystems (Linux).
|
||||
* @param relative_path the fixed case name to map to reality
|
||||
* @param starting_dir optional directory to search within (default - current path)
|
||||
* @return filename with actual case name or empty path if there no mapping in filesystem
|
||||
* @note This function returns only filename without directory part, i.e.
|
||||
* cf_FindRealFileNameCaseInsensitive("test/test.txt") will return only "test.txt" on success.
|
||||
*/
|
||||
std::filesystem::path cf_FindRealFileNameCaseInsensitive(const std::filesystem::path &relative_path,
|
||||
const std::filesystem::path &starting_dir = ".");
|
||||
|
||||
/**
|
||||
* Add directory path into paths to look in for files. If ext_list is empty,
|
||||
* look in this directory for all files. Otherwise, the directory will only
|
||||
|
@ -76,55 +76,41 @@ TEST(D3, CFileLibrary) {
|
||||
EXPECT_EQ(file_handle, nullptr);
|
||||
}
|
||||
|
||||
TEST(D3, CFileCaseSensitiveSearchNew) {
|
||||
TEST(D3, CFileLocatePath) {
|
||||
const std::vector<std::filesystem::path> test_paths = {
|
||||
std::filesystem::path("TestDir") / "CamelCase.txt",
|
||||
std::filesystem::path("TestDir") / "lowercase.txt",
|
||||
std::filesystem::path("TestDir") / "UPPERCASE.TXT",
|
||||
};
|
||||
|
||||
std::filesystem::path filename_new = cf_FindRealFileNameCaseInsensitive("no-exist-file.txt", "no-exist-dir");
|
||||
std::filesystem::path filename_new = cf_LocatePath(std::filesystem::path("no-exist-dir") / "no-exist-file.txt");
|
||||
EXPECT_TRUE(filename_new.empty());
|
||||
|
||||
filename_new = cf_FindRealFileNameCaseInsensitive("no-exist-file.txt");
|
||||
filename_new = cf_LocatePath("no-exist-file.txt");
|
||||
EXPECT_TRUE(filename_new.empty());
|
||||
|
||||
auto cwd = std::filesystem::current_path();
|
||||
|
||||
for (auto const &item : test_paths) {
|
||||
auto directory = cwd / item.parent_path();
|
||||
cf_SetBaseDirectory(directory);
|
||||
std::filesystem::path file = item.filename();
|
||||
std::string file_lc = item.filename().u8string();
|
||||
std::transform(file_lc.begin(), file_lc.end(), file_lc.begin(), ::tolower);
|
||||
std::string file_uc = item.filename().u8string();
|
||||
std::transform(file_uc.begin(), file_uc.end(), file_uc.begin(), ::toupper);
|
||||
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_lc, directory).empty());
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_uc, directory).empty());
|
||||
EXPECT_FALSE(cf_LocatePath(file_lc).empty());
|
||||
EXPECT_FALSE(cf_LocatePath(file_uc).empty());
|
||||
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(directory / file_lc).empty());
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(directory / file_uc).empty());
|
||||
|
||||
// Now try case-insensitive path with non-existing directory in search.
|
||||
// Now try case-insensitive path with non-existing path.
|
||||
// Expected not found on case-sensitive fs.
|
||||
file_lc = item.u8string();
|
||||
std::transform(file_lc.begin(), file_lc.end(), file_lc.begin(), ::tolower);
|
||||
file_uc = item.u8string();
|
||||
std::transform(file_uc.begin(), file_uc.end(), file_uc.begin(), ::toupper);
|
||||
|
||||
if (std::filesystem::is_regular_file(file_lc)) {
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_lc, cwd).empty());
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_lc).empty());
|
||||
} else {
|
||||
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_lc, cwd).empty());
|
||||
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_lc).empty());
|
||||
}
|
||||
if (std::filesystem::is_regular_file(file_uc)) {
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_uc, cwd).empty());
|
||||
EXPECT_FALSE(cf_FindRealFileNameCaseInsensitive(file_uc).empty());
|
||||
} else {
|
||||
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_uc, cwd).empty());
|
||||
EXPECT_TRUE(cf_FindRealFileNameCaseInsensitive(file_uc).empty());
|
||||
}
|
||||
EXPECT_TRUE(cf_LocatePath(file_lc).empty());
|
||||
EXPECT_TRUE(cf_LocatePath(file_uc).empty());
|
||||
}
|
||||
}
|
||||
|
@ -183,8 +183,8 @@ bool mod_LoadModule(module *handle, const std::filesystem::path &imodfilename, i
|
||||
handle->handle = dlopen(modfilename.u8string().c_str(), f);
|
||||
if (!handle->handle) {
|
||||
// ok we couldn't find the given name...try other ways
|
||||
std::filesystem::path parent_path = modfilename.parent_path();
|
||||
std::filesystem::path new_filename = cf_FindRealFileNameCaseInsensitive(modfilename.filename(), parent_path);
|
||||
std::filesystem::path parent_path = modfilename.parent_path().filename();
|
||||
std::filesystem::path new_filename = cf_LocatePath(parent_path / modfilename.filename());
|
||||
|
||||
if (new_filename.empty()) {
|
||||
LOG_ERROR.printf("Module Load Err: %s", dlerror());
|
||||
|
Loading…
Reference in New Issue
Block a user