mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 06:15:38 +00:00
Common: Add a function to get the path to the running program
This commit is contained in:
parent
9456dc5d9b
commit
de4e45a433
|
@ -32,25 +32,6 @@ CDImageCueSheet::~CDImageCueSheet()
|
|||
cd_delete(m_cd);
|
||||
}
|
||||
|
||||
static std::string GetPathDirectory(const char* path)
|
||||
{
|
||||
const char* forwardslash_ptr = std::strrchr(path, '/');
|
||||
const char* backslash_ptr = std::strrchr(path, '\\');
|
||||
const char* slash_ptr;
|
||||
if (forwardslash_ptr && backslash_ptr)
|
||||
slash_ptr = std::max(forwardslash_ptr, backslash_ptr);
|
||||
else if (backslash_ptr)
|
||||
slash_ptr = backslash_ptr;
|
||||
else if (forwardslash_ptr)
|
||||
slash_ptr = forwardslash_ptr;
|
||||
else
|
||||
return {};
|
||||
|
||||
std::string str;
|
||||
str.append(path, slash_ptr - path + 1);
|
||||
return str;
|
||||
}
|
||||
|
||||
static std::string ReplaceExtension(std::string_view path, std::string_view new_extension)
|
||||
{
|
||||
std::string_view::size_type pos = path.rfind('.');
|
||||
|
@ -80,7 +61,7 @@ bool CDImageCueSheet::OpenAndParse(const char* filename)
|
|||
}
|
||||
|
||||
// get the directory of the filename
|
||||
std::string basepath = GetPathDirectory(filename);
|
||||
std::string basepath = FileSystem::GetPathDirectory(filename) + "/";
|
||||
m_filename = filename;
|
||||
|
||||
u32 disc_lba = 0;
|
||||
|
|
|
@ -144,6 +144,11 @@ void CanonicalizePath(String& Destination, bool OSPath /* = true */)
|
|||
CanonicalizePath(Destination, Destination);
|
||||
}
|
||||
|
||||
void CanonicalizePath(std::string& path, bool OSPath /*= true*/)
|
||||
{
|
||||
CanonicalizePath(path.data(), static_cast<u32>(path.size() + 1), path.c_str(), OSPath);
|
||||
}
|
||||
|
||||
static inline bool FileSystemCharacterIsSane(char c, bool StripSlashes)
|
||||
{
|
||||
if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9') && c != ' ' && c != ' ' &&
|
||||
|
@ -217,6 +222,34 @@ void SanitizeFileName(String& Destination, bool StripSlashes /* = true */)
|
|||
return SanitizeFileName(Destination, Destination, StripSlashes);
|
||||
}
|
||||
|
||||
std::string GetPathDirectory(const char* path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
const char* forwardslash_ptr = std::strrchr(path, '/');
|
||||
const char* backslash_ptr = std::strrchr(path, '\\');
|
||||
const char* slash_ptr;
|
||||
if (forwardslash_ptr && backslash_ptr)
|
||||
slash_ptr = std::max(forwardslash_ptr, backslash_ptr);
|
||||
else if (backslash_ptr)
|
||||
slash_ptr = backslash_ptr;
|
||||
else if (forwardslash_ptr)
|
||||
slash_ptr = forwardslash_ptr;
|
||||
else
|
||||
return {};
|
||||
#else
|
||||
const char* slash_ptr = std::strrchr(path, '/');
|
||||
if (!slash_ptr)
|
||||
return {};
|
||||
#endif
|
||||
|
||||
if (slash_ptr == path)
|
||||
return {};
|
||||
|
||||
std::string str;
|
||||
str.append(path, slash_ptr - path);
|
||||
return str;
|
||||
}
|
||||
|
||||
void BuildPathRelativeToFile(char* Destination, u32 cbDestination, const char* CurrentFileName, const char* NewFileName,
|
||||
bool OSPath /* = true */, bool Canonicalize /* = true */)
|
||||
{
|
||||
|
@ -957,6 +990,31 @@ bool FileSystem::DeleteDirectory(const char* Path, bool Recursive)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string GetProgramPath()
|
||||
{
|
||||
const HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
std::string buffer;
|
||||
buffer.resize(MAX_PATH);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DWORD nChars = static_cast<DWORD>(buffer.size());
|
||||
if (!QueryFullProcessImageNameA(GetCurrentProcess(), 0, buffer.data(), &nChars) &&
|
||||
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
buffer.resize(buffer.size() * 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer.resize(nChars);
|
||||
break;
|
||||
}
|
||||
|
||||
CanonicalizePath(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::unique_ptr<ChangeNotifier> CreateChangeNotifier(const char* path, bool recursiveWatch)
|
||||
|
@ -1270,6 +1328,72 @@ bool DeleteDirectory(const char* Path, bool Recursive)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string GetProgramPath()
|
||||
{
|
||||
#if defined(__linux__)
|
||||
static const char* exeFileName = "/proc/self/exe";
|
||||
|
||||
int curSize = PATH_MAX;
|
||||
char* buffer = static_cast<char*>(std::realloc(nullptr, curSize));
|
||||
for (;;)
|
||||
{
|
||||
int len = readlink(exeFileName, buffer, curSize);
|
||||
if (len < 0)
|
||||
{
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
else if (len < curSize)
|
||||
{
|
||||
buffer[len] = '\0';
|
||||
std::string ret(buffer, len);
|
||||
std::free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
curSize *= 2;
|
||||
buffer = static_cast<char*>(std::realloc(buffer, curSize));
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
int curSize = PATH_MAX;
|
||||
char* buffer = static_cast<char*>(std::realloc(nullptr, curSize + 1));
|
||||
for (;;)
|
||||
{
|
||||
uint32 nChars = PATH_MAX - 1;
|
||||
int res = _NSGetExecutablePath(buffer, &nChars);
|
||||
if (res == 0)
|
||||
{
|
||||
buffer[nChars] = 0;
|
||||
|
||||
char* resolvedBuffer = realpath(buffer, nullptr);
|
||||
if (resolvedBuffer == nullptr)
|
||||
{
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string ret(buffer, len);
|
||||
std::free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (curSize >= 1048576)
|
||||
{
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
|
||||
curSize *= 2;
|
||||
buffer = static_cast<char*>(std::realloc(buffer, curSize + 1));
|
||||
}
|
||||
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace FileSystem
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
class ByteStream;
|
||||
|
||||
#ifdef Y_PLATFORM_WINDOWS
|
||||
#ifdef WIN32
|
||||
#define FS_OSPATH_SEPERATOR_CHARACTER '\\'
|
||||
#else
|
||||
#define FS_OSPATH_SEPERATOR_CHARACTER '/'
|
||||
|
@ -111,15 +111,12 @@ protected:
|
|||
// create a change notifier
|
||||
std::unique_ptr<ChangeNotifier> CreateChangeNotifier(const char* path, bool recursiveWatch);
|
||||
|
||||
// appends a path string to the current path string. optionally canonicalizes it.
|
||||
void AppendPath(char* Path, u32 cbPath, const char* NewPath);
|
||||
void AppendPath(String& Path, const char* NewPath);
|
||||
|
||||
// canonicalize a path string (i.e. replace .. with actual folder name, etc), if OS path is used, on windows, the
|
||||
// separators will be \, otherwise /
|
||||
void CanonicalizePath(char* Destination, u32 cbDestination, const char* Path, bool OSPath = true);
|
||||
void CanonicalizePath(String& Destination, const char* Path, bool OSPath = true);
|
||||
void CanonicalizePath(String& Destination, bool OSPath = true);
|
||||
void CanonicalizePath(std::string& path, bool OSPath = true);
|
||||
|
||||
// translates the specified path into a string compatible with the hosting OS
|
||||
void BuildOSPath(char* Destination, u32 cbDestination, const char* Path);
|
||||
|
@ -137,6 +134,9 @@ void SanitizeFileName(char* Destination, u32 cbDestination, const char* FileName
|
|||
void SanitizeFileName(String& Destination, const char* FileName, bool StripSlashes = true);
|
||||
void SanitizeFileName(String& Destination, bool StripSlashes = true);
|
||||
|
||||
/// Returns the directory component of a filename.
|
||||
std::string GetPathDirectory(const char* path);
|
||||
|
||||
// search for files
|
||||
bool FindFiles(const char* Path, const char* Pattern, u32 Flags, FindResultsArray* pResults);
|
||||
|
||||
|
@ -173,4 +173,7 @@ bool CreateDirectory(const char* Path, bool Recursive);
|
|||
// if the directory has files, unless the recursive flag is set, it will fail
|
||||
bool DeleteDirectory(const char* Path, bool Recursive);
|
||||
|
||||
/// Returns the path to the current executable.
|
||||
std::string GetProgramPath();
|
||||
|
||||
}; // namespace FileSystem
|
||||
|
|
Loading…
Reference in a new issue