From 852fe6eade2b65f795cf55e4542f20d58669acd2 Mon Sep 17 00:00:00 2001 From: lifegpc Date: Wed, 15 Oct 2025 23:11:12 +0800 Subject: [PATCH] Add abspath to fileop --- fileop.cpp | 35 +++++++++++++++++++++++++++++++++++ fileop.h | 6 ++++++ 2 files changed, 41 insertions(+) diff --git a/fileop.cpp b/fileop.cpp index 6323c3e..aaee4fb 100644 --- a/fileop.cpp +++ b/fileop.cpp @@ -24,6 +24,7 @@ #include "time_util.h" #include #include +#include #ifdef _WIN32 #if HAVE__ACCESS_S @@ -114,6 +115,16 @@ bool listdir_internal(wchar_t* fn, std::list& list, bool ignore_hid return true; } +std::string realpath_internal(wchar_t* fn) { + DWORD len = GetFullPathNameW(fn, 0, nullptr, nullptr); + wchar_t* buf = (wchar_t*)malloc(sizeof(wchar_t) * len); + GetFullPathNameW(fn, len, buf, nullptr); + std::string re; + wchar_util::wstr_to_str(re, buf, CP_UTF8); + free(buf); + return re; +} + template T fileop_internal(const char* fname, UINT codePage, T(*callback)(wchar_t* fn, Args... args), T failed, Args... args) { int wlen; @@ -708,3 +719,27 @@ std::string fileop::extname(std::string path) { } return path.substr(loc + 1, path.length() - loc - 1); } + +std::string fileop::abspath(std::string path) { +#if _WIN32 + UINT cp[] = { CP_UTF8, CP_OEMCP, CP_ACP }; + int i; + std::string re; + for (i = 0; i < 3; i++) { + re = fileop_internal(path.c_str(), cp[i], &realpath_internal, ""); + if (!re.empty()) return re; + } + DWORD len = GetFullPathNameA(path.c_str(), 0, nullptr, nullptr); + char* buf = (char*)malloc(sizeof(char) * len); + GetFullPathNameA(path.c_str(), len, buf, nullptr); + auto re2 = std::string(buf); + free(buf); + return re2; +#else + char* rp = realpath(path.c_str(), nullptr); + if (!rp) return path; + std::string re(rp); + free(rp); + return re; +#endif +} diff --git a/fileop.h b/fileop.h index e094bb6..cdf80b4 100644 --- a/fileop.h +++ b/fileop.h @@ -205,5 +205,11 @@ namespace fileop { * @return File extension name. If no extension, will return empty string. */ std::string extname(std::string path); + /** + * @brief Convert a relative path to an absolute path + * @param path Path + * @return Absolute path + */ + std::string abspath(std::string path); } #endif