Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
c96c60f
file utils simplification
dimitre Mar 7, 2023
c199076
cubemap
dimitre Mar 7, 2023
a8e677a
cubemap fix aCachePath
dimitre Mar 7, 2023
ce61301
parent_path() fix
dimitre Mar 7, 2023
9159896
ofToDataPath string
dimitre Mar 7, 2023
130008a
tiny fix
dimitre Mar 7, 2023
c3914c2
updates
dimitre Mar 7, 2023
27b6370
Merge branch 'openframeworks:master' into fs
dimitre Mar 8, 2023
51b141d
Merge branch 'openframeworks:master' into fs
dimitre Mar 9, 2023
e5e5ff2
things to fix yet
dimitre Mar 9, 2023
9dc6022
Merge branch 'openframeworks:master' into fs
dimitre Mar 12, 2023
679f6dd
more changes
dimitre Mar 12, 2023
d86685a
Merge branch 'openframeworks:master' into fs
dimitre Mar 13, 2023
59db08d
tests
dimitre Mar 15, 2023
0a11ede
up
dimitre Mar 15, 2023
90f344d
changedir to data
dimitre Mar 15, 2023
1a69450
no windows check anymore
dimitre Mar 15, 2023
026663d
data folder missing in this test
dimitre Mar 15, 2023
b9e6299
missing xm data folder
dimitre Mar 15, 2023
7badb5f
cubemap in separate pr
dimitre Mar 15, 2023
ed78257
more changes
dimitre Mar 15, 2023
e403845
Merge branch 'openframeworks:master' into fs
dimitre Mar 15, 2023
7249c12
changes
dimitre Mar 15, 2023
c87c967
ok
dimitre Mar 15, 2023
e6f7815
ok
dimitre Mar 15, 2023
642bd80
offile open relative
dimitre Mar 15, 2023
bef7d34
update relative paths if needed.
dimitre Mar 15, 2023
f722555
more cleanup
dimitre Mar 15, 2023
15d7d91
cout::endl fix
dimitre Mar 15, 2023
fdba45b
more cleanup
dimitre Mar 15, 2023
e2dffe5
Merge branch 'openframeworks:master' into fs
dimitre Mar 17, 2023
b5e8112
getCurrentExePathFS, fs namespace
dimitre Apr 17, 2023
d0d04e2
update submodules
dimitre Nov 23, 2023
d73a5bb
Merge branch 'master' into fs
dimitre Nov 23, 2023
75e93af
fix perms
dimitre Nov 24, 2023
da630d2
Merge branch 'master' into fs
dimitre Dec 1, 2023
4126b05
of::filesystem to fs
dimitre Dec 1, 2023
155894e
fix
dimitre Dec 1, 2023
14a4711
up
dimitre Dec 1, 2023
919656c
revert some
dimitre Dec 5, 2023
902f0ca
revert commit
dimitre Dec 5, 2023
76e84bc
revert
dimitre Dec 5, 2023
d2585db
merge master, fix conflicts
dimitre Jan 7, 2024
36090e6
fix conflicts
dimitre Jan 7, 2024
8561228
update tests
dimitre Jan 7, 2024
ad097db
Merge branch 'openframeworks:master' into fs
dimitre May 10, 2024
ac6eeda
Merge branch 'openframeworks:master' into fs
dimitre May 11, 2024
b0f6e88
up
dimitre May 11, 2024
2a4ac9d
group / endgroup in run_tests
dimitre May 11, 2024
c7e933f
group
dimitre May 11, 2024
fd7d7cc
up
dimitre May 11, 2024
42df8d5
Merge branch 'openframeworks:master' into fs
dimitre May 11, 2024
ac54e24
Merge branch 'openframeworks:master' into fs
dimitre May 11, 2024
c0aeaeb
Merge branch 'openframeworks:master' into fs
dimitre May 11, 2024
5f038a8
try to fix
dimitre May 12, 2024
b73badf
ok
dimitre May 12, 2024
f507a92
Merge branch 'master' into fs
dimitre May 16, 2024
8c1eca8
Merge branch 'openframeworks:master' into fs
dimitre May 19, 2024
d742529
up
dimitre Sep 2, 2024
83a0d3f
more conflicts fix
dimitre Sep 2, 2024
9a8e995
up
dimitre Sep 2, 2024
9192592
up win
dimitre Sep 2, 2024
e27babd
more
dimitre Sep 2, 2024
cb01825
update tests
dimitre Sep 2, 2024
7b52456
gitkeep data folder tests
dimitre Sep 2, 2024
c646e2b
Merge branch 'openframeworks:master' into fs
dimitre Oct 15, 2024
c6b18ee
Merge branch 'openframeworks:master' into fs
dimitre Oct 18, 2024
6659794
merge master
dimitre Dec 9, 2024
8ccb52b
merge master
dimitre Dec 9, 2024
fb55c58
Merge branch 'master' into fs
dimitre May 3, 2025
3678022
merge master
dimitre May 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 102 additions & 115 deletions libs/openFrameworks/utils/ofFileUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,31 @@ using std::istream;
using std::ostream;
using std::ios;

namespace{
using std::cout;
using std::endl;

namespace fs = of::filesystem;

namespace {
bool enableDataPath = true;

//--------------------------------------------------
fs::path defaultDataPath(){
#if defined TARGET_OSX
try {
return fs::canonical(ofFilePath::getCurrentExeDirFS() / "../../../data/");
} catch(...) {
return ofFilePath::getCurrentExeDirFS() / "../../../data/";
return fs::canonical(ofFilePath::getCurrentExeDir() / "../../../data/");
} catch(fs::filesystem_error & e) {
ofLogWarning("ofFileUtils") << "defaultDataPath 1 " << e.what();
return ofFilePath::getCurrentExeDir() / "../../../data/";
}
#elif defined TARGET_ANDROID
return string("sdcard/");
#else
try {
return fs::canonical(ofFilePath::getCurrentExeDirFS() / "data/").make_preferred();
} catch(...) {
return (ofFilePath::getCurrentExeDirFS() / "data/");
return fs::canonical(ofFilePath::getCurrentExeDir() / "data").make_preferred();
} catch(fs::filesystem_error & e) {
ofLogWarning("ofFileUtils") << "defaultDataPath 2 " << e.what();
return (ofFilePath::getCurrentExeDir() / "data");
}
#endif
}
Expand All @@ -53,15 +60,20 @@ namespace{
//--------------------------------------------------
fs::path & dataPathRoot() {
static auto * dataPathRoot = new fs::path(defaultDataPath());
// This is the most important change in the way OF handles paths.
try {
fs::current_path(*dataPathRoot);
} catch(fs::filesystem_error & e) {
ofLogError("ofFileUtils") << "dataPathRoot\n" << e.what();
}
return *dataPathRoot;
}
}

namespace of{
namespace priv{
void initfileutils() {
// FIXME: Why absolute?
defaultWorkingDirectory() = fs::absolute(fs::current_path());
void initfileutils(){
defaultWorkingDirectory() = dataPathRoot();
}
}
}
Expand Down Expand Up @@ -693,7 +705,8 @@ std::string ofFile::getAbsolutePath() const {

//------------------------------------------------------------------------------------------------------------
bool ofFile::canRead() const {

auto perm = fs::status(myFile).permissions();

#ifdef TARGET_WIN32
DWORD attr = GetFileAttributes(myFile.native().c_str());
if (attr == INVALID_FILE_ATTRIBUTES)
Expand All @@ -704,7 +717,7 @@ bool ofFile::canRead() const {
#else
struct stat info;
stat(path().c_str(), &info); // Error check omitted
auto perm = fs::status(myFile).permissions();

#if defined(OF_USING_STD_FS)
if(geteuid() == info.st_uid){
return (perm & fs::perms::owner_read) != fs::perms::none;
Expand All @@ -727,6 +740,9 @@ bool ofFile::canRead() const {

//------------------------------------------------------------------------------------------------------------
bool ofFile::canWrite() const {

auto perm = fs::status(myFile).permissions();

#ifdef TARGET_WIN32
DWORD attr = GetFileAttributes(myFile.native().c_str());
if (attr == INVALID_FILE_ATTRIBUTES){
Expand All @@ -737,8 +753,9 @@ bool ofFile::canWrite() const {
#else
struct stat info;
stat(path().c_str(), &info); // Error check omitted
auto perm = fs::status(myFile).permissions();

#if defined(OF_USING_STD_FS)

if(geteuid() == info.st_uid){
return (perm & fs::perms::owner_write) != fs::perms::none;
}else if (getegid() == info.st_gid){
Expand All @@ -760,13 +777,16 @@ bool ofFile::canWrite() const {

//------------------------------------------------------------------------------------------------------------
bool ofFile::canExecute() const {

auto perm = fs::status(myFile).permissions();
#ifdef TARGET_WIN32
return getExtension() == "exe";
#else
struct stat info;
stat(path().c_str(), &info); // Error check omitted
auto perm = fs::status(myFile).permissions();

#if defined(OF_USING_STD_FS)

if(geteuid() == info.st_uid){
return (perm & fs::perms::owner_exec) != fs::perms::none;
}else if (getegid() == info.st_gid){
Expand Down Expand Up @@ -1216,7 +1236,8 @@ std::string ofDirectory::path() const {
fs::path ofDirectory::getAbsolutePathFS() const {
try {
return fs::canonical(fs::absolute(myDir));
} catch(...) {
} catch(fs::filesystem_error & e) {
ofLogWarning("ofFileUtils") << "ofDirectory::getAbsolutePath " << e.what();
return fs::absolute(myDir);
}
}
Expand Down Expand Up @@ -1335,11 +1356,24 @@ bool ofDirectory::copyTo(const fs::path & _path, bool bRelativeToData, bool over

//------------------------------------------------------------------------------------------------------------
bool ofDirectory::moveTo(const fs::path& path, bool bRelativeToData, bool overwrite){
if(copyTo(path,bRelativeToData,overwrite)){
return remove(true);
if (fs::exists(path)) {
if (overwrite) {
fs::remove_all(path);
}
else {
ofLogError("ofDirectory") << "moveTo(): destination folder exists, overwrite = false " << std::endl;
return false;
}
}

return false;
const fs::path & old = myDir;
try {
fs::rename(old, path);
} catch (fs::filesystem_error const& ex) {
ofLogError("ofDirectory") << "moveTo(): can't rename folder " << ex.code().message() << std::endl;
return false;
}
myDir = path;
return true;
}

//------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1393,7 +1427,7 @@ std::size_t ofDirectory::listDir(){
return 0;
}

if ( fs::exists(myDir) && fs::is_directory(myDir)){
if (fs::exists(myDir) && fs::is_directory(myDir)){
for (const auto & f : fs::directory_iterator{ myDir }) {
files.emplace_back(f.path(), ofFile::Reference);
}
Expand Down Expand Up @@ -1773,6 +1807,7 @@ fs::path ofFilePath::getPathForDirectoryFS(const fs::path & path){
return path / "";
#else
auto sep = fs::path("/").make_preferred();
// FIXME: ALERT funny path.back here()
if(!path.empty() && ofToString(path.back()) != sep.string()){
return path / sep;
}else{
Expand Down Expand Up @@ -1824,7 +1859,7 @@ std::string ofFilePath::getEnclosingDirectory(const fs::path & _filePath, bool b
if(bRelativeToData){
fp = ofToDataPath(fp);
}
return addTrailingSlash(fp.parent_path());
return fp.parent_path().string();
}

//------------------------------------------------------------------------------------------------------------
Expand All @@ -1840,7 +1875,8 @@ fs::path ofFilePath::getAbsolutePathFS(const fs::path & path, bool bRelativeToDa
}else{
try{
return fs::canonical(fs::absolute(path));
}catch(...){
} catch(fs::filesystem_error & e) {
ofLogWarning("ofFileUtils") << "getAbsolutePath " << e.what();
return fs::absolute(path);
}
}
Expand All @@ -1857,8 +1893,9 @@ bool ofFilePath::isAbsolute(const fs::path& path){
}

//------------------------------------------------------------------------------------------------------------
string ofFilePath::getCurrentWorkingDirectory(){
return ofPathToString(fs::current_path());
// FIXME: Deprecate
fs::path ofFilePath::getCurrentWorkingDirectory(){
return fs::current_path();
}

//------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1888,20 +1925,28 @@ fs::path ofFilePath::getCurrentExePathFS(){
}
return path;
#elif defined(TARGET_WIN32)
vector<char> executablePath(MAX_PATH);
DWORD result = ::GetModuleFileNameA(nullptr, &executablePath[0], static_cast<DWORD>(executablePath.size()));
// vector<wchar_t> executablePath(MAX_PATH);
wchar_t executablePath[MAX_PATH];
DWORD result = ::GetModuleFileNameW(
nullptr,
executablePath,
static_cast<DWORD>(MAX_PATH)
);
if (result == 0) {
ofLogError("ofFilePath") << "getCurrentExePath(): couldn't get path, GetModuleFileNameA failed";
// Error
ofLogError("ofFilePath") << "getCurrentExePath(): couldn't get path, GetModuleFileNameW failed";
} else {
return string(executablePath.begin(), executablePath.begin() + result);
// return { executablePath.begin(), executablePath.begin() + result };
return { executablePath };
}

#endif
return "";
}

//------------------------------------------------------------------------------------------------------------
std::string ofFilePath::getCurrentExePath(){
return ofPathToString(getCurrentExePathFS());
fs::path ofFilePath::getCurrentExeDir(){
return ofFilePath::getCurrentExePath().parent_path();
}

//------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1950,7 +1995,8 @@ bool ofRestoreWorkingDirectoryToDefault(){
try{
fs::current_path(defaultWorkingDirectory());
return true;
}catch(...){
} catch(fs::filesystem_error & e) {
ofLogWarning("ofFileUtils") << "ofRestoreWorkingDirectoryToDefault " << e.what();
return false;
}
}
Expand All @@ -1961,94 +2007,35 @@ void ofSetDataPathRoot(const fs::path& newRoot){
}

//--------------------------------------------------
fs::path ofToDataPathFS(const fs::path & path, bool makeAbsolute){
if (makeAbsolute && path.is_absolute()) {
return path;
}

if (!enableDataPath) {
return path;
}

bool hasTrailingSlash = !path.empty() && path.generic_string().back()=='/';

// if our Current Working Directory has changed (e.g. file open dialog)
#ifdef TARGET_WIN32
if (defaultWorkingDirectory() != fs::current_path()) {
// change our cwd back to where it was on app load
bool ret = ofRestoreWorkingDirectoryToDefault();
if(!ret){
ofLogWarning("ofUtils") << "ofToDataPath: error while trying to change back to default working directory " << defaultWorkingDirectory();
}
}
#endif

// this could be performed here, or wherever we might think we accidentally change the cwd, e.g. after file dialogs on windows
const auto & dataPath = dataPathRoot();
fs::path inputPath(path);
fs::path outputPath;

// if path is already absolute, just return it
if (inputPath.is_absolute()) {
try {
auto outpath = fs::canonical(inputPath).make_preferred();
if(fs::is_directory(outpath) && hasTrailingSlash){
return ofFilePath::addTrailingSlash(outpath);
}else{
return outpath;
}
}
catch (...) {
return inputPath;
}
}

// here we check whether path already refers to the data folder by looking for common elements
// if the path begins with the full contents of dataPathRoot then the data path has already been added
// we compare inputPath.toString() rather that the input var path to ensure common formatting against dataPath.toString()
auto dirDataPath = dataPath;
// also, we strip the trailing slash from dataPath since `path` may be input as a file formatted path even if it is a folder (i.e. missing trailing slash)

// FIXME: unneeded after we remove string operations
dirDataPath = ofFilePath::addTrailingSlash(dataPath);

auto relativeDirDataPath = ofFilePath::makeRelative(fs::current_path(), dataPath);

// FIXME: unneeded after we remove string operations
relativeDirDataPath = ofFilePath::addTrailingSlash(relativeDirDataPath);

// FIXME: this can be simplified without using string conversion
// if (inputPath.string().find(dirDataPath.string()) != 0 && inputPath.string().find(relativeDirDataPath.string())!=0) {
if (inputPath.string().find(dirDataPath.string()) != 0 && inputPath.string().find(relativeDirDataPath)!=0) {
// inputPath doesn't contain data path already, so we build the output path as the inputPath relative to the dataPath
if(makeAbsolute){
outputPath = dirDataPath / inputPath;
}else{
outputPath = relativeDirDataPath / inputPath;
fs::path ofToDataPath(const fs::path & path, bool makeAbsolute){
fs::path outPath { path };
if (path.is_absolute()) {
if (makeAbsolute) {
// nothing needed here. outPath is already path
} else {
auto current = fs::current_path();
outPath = fs::relative(path, current);
}
} else {
// inputPath already contains data path, so no need to change
outputPath = inputPath;
}

// finally, if we do want an absolute path and we don't already have one
if(makeAbsolute){
// then we return the absolute form of the path
try {
auto outpath = fs::canonical(fs::absolute(outputPath)).make_preferred();
if(fs::is_directory(outpath) && hasTrailingSlash){
return ofFilePath::addTrailingSlash(outpath);
}else{
return outpath;
}
}
catch (std::exception &) {
return fs::absolute(outputPath);
if (makeAbsolute) {
outPath = dataPathRoot() / path;
} else {
auto current = fs::current_path();
outPath = fs::relative(dataPathRoot() / path, current);
}
}else{
// or output the relative path
return outputPath;
}

return outPath;
//// if our Current Working Directory has changed (e.g. file open dialog)
//#ifdef TARGET_WIN32
// if (defaultWorkingDirectory() != fs::current_path()) {
// // change our cwd back to where it was on app load
// bool ret = ofRestoreWorkingDirectoryToDefault();
// if(!ret){
// ofLogWarning("ofUtils") << "ofToDataPath: error while trying to change back to default working directory " << defaultWorkingDirectory();
// }
// }
//#endif
}

//--------------------------------------------------
Expand Down
5 changes: 2 additions & 3 deletions libs/openFrameworks/utils/ofFileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ class ofFilePath {
/// \warning This location *may* change if you or a library calls the cd()
/// std C function.
/// \returns current working directory
static std::string getCurrentWorkingDirectory();
static of::filesystem::path getCurrentWorkingDirectory();

/// Create a single path by joining path1 & path2 using a slash,
/// ie. "/hello/world" + "foo/bar" -> "/hello/world/foo/bar".
Expand All @@ -443,8 +443,7 @@ class ofFilePath {
/// Mac: the Contents/MacOS folder within the application's .app bundle
///
/// \returns current executable directory
static of::filesystem::path getCurrentExeDirFS();
static std::string getCurrentExeDir();
static of::filesystem::path getCurrentExeDir();

/// Get the absolute path to the user's home directory.
///
Expand Down
Loading
Loading