gates_of_skeldal/platform/file_access.cpp
2025-01-31 12:46:48 +01:00

97 lines
3 KiB
C++

#include "platform.h"
#include <cstdarg>
#include <filesystem>
#include "../libs/logfile.h"
std::filesystem::path break_and_compose_path(const std::string_view &pathname, char sep) {
auto p = pathname.rfind(sep);
if (p == pathname.npos) {
if (pathname == "." || pathname == "..") return std::filesystem::canonical(".");
else if (pathname.empty()) return std::filesystem::current_path().root_path();
else if (pathname == std::filesystem::current_path().root_name())
return pathname;
else return std::filesystem::current_path()/pathname;
}
return break_and_compose_path(pathname.substr(0,p), sep) / pathname.substr(p+1);
}
std::filesystem::path convert_pathname_to_path(const std::string_view &pathname) {
auto p = pathname.find('\\');
if (p == pathname.npos) {
p = pathname.find('/');
if (p == pathname.npos) {
return std::filesystem::current_path()/pathname;
}
return break_and_compose_path(pathname, '/');
}
return break_and_compose_path(pathname, '\\');
}
std::filesystem::path try_to_find_file(const std::filesystem::path &p) {
if (!std::filesystem::exists(p)) {
std::filesystem::path parent;
if (p.has_relative_path()) {
parent = try_to_find_file(p.parent_path());
}
if (std::filesystem::exists(parent)) {
auto iter = std::filesystem::directory_iterator(parent);
auto end = std::filesystem::directory_iterator();
std::filesystem::path n = p.filename();
while (iter != end) {
const std::filesystem::directory_entry &e = *iter;
auto fn = e.path().filename();
if (stricmp(n.c_str(), fn.c_str()) == 0) {
return e.path();
}
++iter;
}
}
return p;
}
else return p;
}
char check_file_exists(const char *pathname) {
std::filesystem::path path = try_to_find_file(convert_pathname_to_path(pathname));
return std::filesystem::exists(path)?1:0;
}
FILE *fopen_icase(const char *pathname, const char *mode) {
std::filesystem::path path = try_to_find_file(convert_pathname_to_path(pathname));
return fopen(path.c_str(), mode);
}
static thread_local std::string build_pathname_buffer;
const char * build_pathname(size_t nparts, const char *part1, ...) {
va_list lst;
va_start(lst, part1);
std::filesystem::path p = part1;
for (size_t i = 1; i < nparts; ++i) {
p = p / va_arg(lst, const char *);
}
build_pathname_buffer = p;
SEND_LOG("(BUILD_PATHNAME) %s", build_pathname_buffer.c_str());
return build_pathname_buffer.c_str();
}
char create_directories(const char *path) {
std::filesystem::path p(path);
std::error_code ec;
return std::filesystem::create_directories(p, ec)?1:0;
}
char change_current_directory(const char *path) {
std::error_code ec;
std::filesystem::current_path(std::filesystem::path(path), ec);
return ec == std::error_code{}?1:0;
}