[Project64] Normalize paths

This commit is contained in:
zilmar 2018-11-19 21:16:58 +10:30
parent 485339300d
commit b93736414f
13 changed files with 109 additions and 40 deletions

View File

@ -4,13 +4,14 @@
/* for POSIX method away from Win32 _stricmp--see "Platform.h" */ /* for POSIX method away from Win32 _stricmp--see "Platform.h" */
#include <strings.h> #include <strings.h>
#endif #endif
#include "Platform.h"
#include "FileClass.h" #include "FileClass.h"
#include "CriticalSection.h" #include "CriticalSection.h"
#include "StdString.h"
#include "SmartPointer.h" #include "SmartPointer.h"
#include <string>
#include <map> #include <map>
#include <vector>
#include <list>
class CIniFileBase class CIniFileBase
{ {

View File

@ -306,17 +306,47 @@ CPath::CPath(DIR_MODULE_FILE /*sdt*/)
#ifdef _WIN32 #ifdef _WIN32
void CPath::GetComponents(std::string* pDrive, std::string* pDirectory, std::string* pName, std::string* pExtension) const void CPath::GetComponents(std::string* pDrive, std::string* pDirectory, std::string* pName, std::string* pExtension) const
{ {
char buff_drive[_MAX_DRIVE + 1]; WriteTrace(TracePath, TraceDebug, "Start (m_strPath: \"%s\")", m_strPath.c_str());
char buff_dir[_MAX_DIR + 1];
char buff_name[_MAX_FNAME + 1];
char buff_ext[_MAX_EXT + 1];
ZeroMemory(buff_drive, sizeof(buff_drive)); char buff_drive[_MAX_DRIVE + 1] = { 0 };
ZeroMemory(buff_dir, sizeof(buff_dir)); char buff_dir[_MAX_DIR + 1] = { 0 };
ZeroMemory(buff_name, sizeof(buff_name)); char buff_name[_MAX_FNAME + 1] = { 0 };
ZeroMemory(buff_ext, sizeof(buff_ext)); char buff_ext[_MAX_EXT + 1] = { 0 };
_splitpath(m_strPath.c_str(), pDrive ? buff_drive : NULL, pDirectory ? buff_dir : NULL, pName ? buff_name : NULL, pExtension ? buff_ext : NULL); const char * BasePath = m_strPath.c_str();
const char * DriveDir = strrchr(BasePath, DRIVE_DELIMITER);
if (DriveDir != NULL)
{
int len = sizeof(buff_dir) < (DriveDir - BasePath) ? sizeof(buff_drive) : DriveDir - BasePath;
strncpy(buff_drive, BasePath, len);
BasePath += len + 1;
}
const char * last = strrchr(BasePath, DIRECTORY_DELIMITER);
if (last != NULL)
{
int len = sizeof(buff_dir) < (last - BasePath) ? sizeof(buff_dir) : last - BasePath;
if (len > 0)
{
strncpy(buff_dir, BasePath, len);
}
else
{
buff_dir[0] = DIRECTORY_DELIMITER;
buff_dir[1] = '\0';
}
strncpy(buff_name, last + 1, sizeof(buff_name));
}
else
{
strncpy(buff_dir, BasePath, sizeof(buff_dir));
}
char * ext = strrchr(buff_name, '.');
if (ext != NULL)
{
strncpy(buff_ext, ext + 1, sizeof(buff_ext));
*ext = '\0';
}
if (pDrive) if (pDrive)
{ {
@ -334,24 +364,7 @@ void CPath::GetComponents(std::string* pDrive, std::string* pDirectory, std::str
{ {
*pExtension = buff_ext; *pExtension = buff_ext;
} }
WriteTrace(TracePath, TraceDebug, "Done (dir: \"%s\" name: \"%s\" ext: \"%s\")", buff_dir, buff_name, buff_ext);
// DOS's _splitpath returns "d:", we return "d"
if (pDrive)
{
StripTrailingChar(*pDrive, DRIVE_DELIMITER);
}
// DOS's _splitpath returns "\dir\subdir\", we return "\dir\subdir"
if (pDirectory)
{
StripTrailingBackslash(*pDirectory);
}
// DOS's _splitpath returns ".ext", we return "ext"
if (pExtension)
{
StripLeadingChar(*pExtension, EXTENSION_DELIMITER);
}
} }
#else #else
void CPath::GetComponents(std::string* pDirectory, std::string* pName, std::string* pExtension) const void CPath::GetComponents(std::string* pDirectory, std::string* pName, std::string* pExtension) const
@ -423,8 +436,8 @@ void CPath::GetDriveDirectory(std::string& rDriveDirectory) const
if (!Drive.empty()) if (!Drive.empty())
{ {
rDriveDirectory += DRIVE_DELIMITER; rDriveDirectory += DRIVE_DELIMITER;
rDriveDirectory += Directory;
} }
rDriveDirectory += Directory;
} }
std::string CPath::GetDriveDirectory(void) const std::string CPath::GetDriveDirectory(void) const
@ -1438,6 +1451,53 @@ bool CPath::ChangeDirectory()
#endif #endif
} }
void CPath::NormalizePath(CPath BaseDir)
{
#ifdef _WIN32
stdstr Directory = BaseDir.GetDriveDirectory();
#else
stdstr Directory = BaseDir.GetDirectory();
#endif
bool Changed = false;
if (IsRelative())
{
EnsureTrailingBackslash(Directory);
Directory += GetDirectory();
Changed = true;
}
strvector Parts = Directory.Tokenize(DIRECTORY_DELIMITER);
strvector NormalizesParts;
for (strvector::const_iterator itr = Parts.begin(); itr != Parts.end(); itr++)
{
if (*itr == ".")
{
Changed = true;
}
else if (*itr == "..")
{
NormalizesParts.pop_back();
Changed = true;
}
else
{
NormalizesParts.push_back(*itr);
}
}
if (Changed)
{
Directory.clear();
for (strvector::const_iterator itr = NormalizesParts.begin(); itr != NormalizesParts.end(); itr++)
{
Directory += *itr + DIRECTORY_DELIMITER;
}
#ifdef _WIN32
SetDriveDirectory(Directory.c_str());
#else
SetDirectory(Directory.c_str());
#endif
}
}
//------------------------------------------------------------- //-------------------------------------------------------------
// Pre : If bCreateIntermediates is TRUE, create all eventually // Pre : If bCreateIntermediates is TRUE, create all eventually
// missing parent directories too // missing parent directories too

View File

@ -127,6 +127,7 @@ public:
//Directory operations //Directory operations
bool DirectoryCreate(bool bCreateIntermediates = true); bool DirectoryCreate(bool bCreateIntermediates = true);
bool ChangeDirectory(); bool ChangeDirectory();
void NormalizePath(CPath BaseDir);
//File operations //File operations
bool Delete(bool bEvenIfReadOnly = true) const; bool Delete(bool bEvenIfReadOnly = true) const;

View File

@ -148,6 +148,7 @@ void CEeprom::LoadEeprom()
{ {
FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!FileName.DirectoryExists()) if (!FileName.DirectoryExists())
{ {

View File

@ -125,6 +125,7 @@ bool CFlashram::LoadFlashram()
{ {
FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!FileName.DirectoryExists()) if (!FileName.DirectoryExists())
{ {

View File

@ -34,6 +34,7 @@ void CMempak::LoadMempak(int32_t Control, bool Create)
{ {
MempakPath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); MempakPath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
MempakPath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!Create && !MempakPath.Exists()) if (!Create && !MempakPath.Exists())
{ {

View File

@ -28,6 +28,7 @@ bool CSram::LoadSram()
{ {
FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!FileName.DirectoryExists()) if (!FileName.DirectoryExists())
{ {

View File

@ -1547,6 +1547,7 @@ bool CN64System::SaveState()
{ {
SaveFile.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); SaveFile.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
SaveFile.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
SaveFile.SetName(g_Settings->LoadStringVal(Rdb_GoodName).c_str()); SaveFile.SetName(g_Settings->LoadStringVal(Rdb_GoodName).c_str());
g_Settings->SaveDword(Game_LastSaveSlot, g_Settings->LoadDword(Game_CurrentSaveState)); g_Settings->SaveDword(Game_LastSaveSlot, g_Settings->LoadDword(Game_CurrentSaveState));
} }
@ -1702,6 +1703,7 @@ bool CN64System::LoadState()
{ {
FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (g_Settings->LoadDword(Game_CurrentSaveState) != 0) if (g_Settings->LoadDword(Game_CurrentSaveState) != 0)
{ {
FileName.SetNameExtension(stdstr_f("%s.pj%d", g_Settings->LoadStringVal(Rdb_GoodName).c_str(), g_Settings->LoadDword(Game_CurrentSaveState)).c_str()); FileName.SetNameExtension(stdstr_f("%s.pj%d", g_Settings->LoadStringVal(Rdb_GoodName).c_str(), g_Settings->LoadDword(Game_CurrentSaveState)).c_str());

View File

@ -11,6 +11,7 @@
#pragma once #pragma once
#include <Common/path.h> #include <Common/path.h>
#include <Common/IniFileClass.h> #include <Common/IniFileClass.h>
#include <Common/StdString.h>
#include <Common/md5.h> #include <Common/md5.h>
#include <Common/Thread.h> #include <Common/Thread.h>
#include <Project64-core/N64System/N64Types.h> #include <Project64-core/N64System/N64Types.h>

View File

@ -91,17 +91,14 @@ void CSettingTypeApplication::Initialize(const char * /*AppName*/)
{ {
delete m_SettingsIniFile; delete m_SettingsIniFile;
} }
#ifdef _WIN32 CPath SettingPath(SettingsFile.c_str());
CPath SettingsDir(CPath(SettingsFile).GetDriveDirectory(), ""); SettingPath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
#else if (!SettingPath.DirectoryExists())
CPath SettingsDir(CPath(SettingsFile).GetDirectory(), "");
#endif
if (!SettingsDir.DirectoryExists())
{ {
SettingsDir.DirectoryCreate(); SettingPath.DirectoryCreate();
} }
m_SettingsIniFile = new CIniFile(SettingsFile.c_str()); m_SettingsIniFile = new CIniFile(SettingPath);
} }
m_SettingsIniFile->SetAutoFlush(false); m_SettingsIniFile->SetAutoFlush(false);

View File

@ -52,6 +52,7 @@ CPath CSymbols::GetSymFilePath()
{ {
symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
symFilePath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!symFilePath.DirectoryExists()) if (!symFilePath.DirectoryExists())
{ {
symFilePath.DirectoryCreate(); symFilePath.DirectoryCreate();

View File

@ -632,7 +632,8 @@ std::wstring CMainMenu::GetSaveSlotString(int Slot)
{ {
FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str()); FileName.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
} }
if (Slot != 0) FileName.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (Slot != 0)
{ {
FileName.SetNameExtension(stdstr_f("%s.pj%d", g_Settings->LoadStringVal(Rdb_GoodName).c_str(), Slot).c_str()); FileName.SetNameExtension(stdstr_f("%s.pj%d", g_Settings->LoadStringVal(Rdb_GoodName).c_str(), Slot).c_str());
} }

View File

@ -8,4 +8,5 @@ Windows 2.4
- fixed fpu issue - Indiana Jones (#76) - fixed fpu issue - Indiana Jones (#76)
- Fix bug in key assignment (#1309) - Fix bug in key assignment (#1309)
- Add Shygoo's debugger code - Add Shygoo's debugger code
- New audio plugin - New audio plugin
- large address aware