Ugly workarounds to not depend on std::filesystem #7131

This commit is contained in:
Thomas Krijnen
2025-09-29 11:29:07 +02:00
parent a492be5971
commit 573e53ebfd
2 changed files with 49 additions and 10 deletions
+47 -8
View File
@@ -6,6 +6,10 @@
#include <rocksdb/convenience.h>
#endif
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
IfcParse::parse_context::~parse_context() {
for (auto& t : tokens_) {
std::visit([](auto& v) {
@@ -570,23 +574,58 @@ IfcParse::IfcFile::~IfcFile() {
}
}
#include <filesystem>
#include <fstream>
namespace {
// Utility functions for path handling in order not to rely on C++17's std::filesystem
#ifdef _WIN32
#define stat_t struct _stat
inline int stat_(const char* p, stat_t* s) { return ::_stat(p, s); }
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & _S_IFDIR) != 0)
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m) & _S_IFREG) != 0)
#endif
#else
using stat_t = struct stat;
inline int stat_(const char* p, stat_t* s) { return ::stat(p, s); }
#endif
inline bool path_exists_(const std::string& p, stat_t* out = nullptr) {
stat_t tmp;
stat_t* s = out ? out : &tmp;
return stat_(p.c_str(), s) == 0;
}
inline bool path_is_directory_(const stat_t& s) { return S_ISDIR(s.st_mode); }
inline bool path_is_regular_file_(const stat_t& s) { return S_ISREG(s.st_mode); }
inline std::string path_join_(const std::string& dir, const std::string& name) {
if (dir.empty()) return name;
const char last = dir.back();
if (last == '/' || last == '\\') return dir + name;
#ifdef _WIN32
const char sep = '\\';
#else
const char sep = '/';
#endif
return dir + sep + name;
}
} // namespace
IfcParse::filetype IfcParse::guess_file_type(const std::string& fn) {
namespace fs = std::filesystem;
if (!fs::exists(fn)) {
stat_t st{};
if (!path_exists_(fn, &st)) {
// @todo this is just weird, but for consistency with earlier behaviour
// for now the only intent for this function is to auto-detect RocksDB
return FT_IFCSPF;
}
if (fs::is_directory(fn)) {
if (path_is_directory_(st)) {
// Typical RocksDB file to look for
auto currentFile = fs::path(fn) / "CURRENT";
auto currentFile = path_join_(fn, "CURRENT");
stat_t cst{};
if (!fs::exists(currentFile) || !fs::is_regular_file(currentFile)) {
if (!path_exists_(currentFile, &cst) || !path_is_regular_file_(cst)) {
return FT_UNKNOWN;
}