diff --git a/source/Library/System/Path.cpp b/source/Library/System/Path.cpp index fa8f8b38..dc82dbe6 100644 --- a/source/Library/System/Path.cpp +++ b/source/Library/System/Path.cpp @@ -4,8 +4,8 @@ // ------------------------------------------------------------------------------------------------ #include - -// ------------------------------------------------------------------------------------------------ +#include +#include #include // ------------------------------------------------------------------------------------------------ @@ -14,7 +14,7 @@ #else #include #include -#endif +#endif // SQMOD_OS_WINDOWS // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -32,6 +32,49 @@ namespace SqMod { typedef CharT PChar; #endif // SQMOD_OS_WINDOWS +// ------------------------------------------------------------------------------------------------ +Buffer GetRealFilePath(CSStr path) +{ + // Make sure the specified path is valid + if (!path || *path == '\0') + { + STHROWF("Cannot obtain real path of empty or invalid path"); + } + // Allocate a buffer large enough to hold a full path + Buffer b(SQMOD_MAX_PATH); + +#ifdef SQMOD_OS_WINDOWS + // Attempt to obtain the full path to the file + DWORD ret = ::GetFullPathName(path, b.Size< PChar >(), b.Get< PChar >(), nullptr); + // Should we allocate a bigger buffer? + if (ret > b.Size< PChar >()) + { + // Grab a bigger buffer + b.Adjust(ret); + // Grab the path again + ret = GetFullPathName(path, b.Size< PChar >(), b.Get< PChar >(), nullptr); + } + // Did we fail to obtain a path? + if (ret == 0 && ::GetLastError() != 0) + { + STHROWLASTF("Cannot obtain real path of (%s)", path); + } + // Adjust the buffer cursor + b.Move(ret); +#else + // Attempt to obtain the full path to the file + if (!realpath(path, b.Data())) + { + STHROWLASTF("Cannot obtain real path of (%s)", path); + } + // Adjust the buffer cursor + b.Move(std::strlen(b.Data())); +#endif // SQMOD_OS_WINDOWS + + // Return ownership of the buffer + return std::move(b); +} + // ------------------------------------------------------------------------------------------------ SQInteger SysPath::Typename(HSQUIRRELVM vm) { diff --git a/source/Library/System/Path.hpp b/source/Library/System/Path.hpp index 0a165383..2d778356 100644 --- a/source/Library/System/Path.hpp +++ b/source/Library/System/Path.hpp @@ -10,6 +10,11 @@ // ------------------------------------------------------------------------------------------------ namespace SqMod { +/* ------------------------------------------------------------------------------------------------ + * Retrieve the full path of file. +*/ +Buffer GetRealFilePath(CSStr path); + /* ------------------------------------------------------------------------------------------------ * This class represents filesystem paths in a platform-independent manner. */