-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fs::path <> string interoperability #7817
Conversation
it will cause some test errors with stuff like |
+1 for path return type everywhere. for the failing tests they should be updated to explicitly perform the string conversion: ofxTestEq(ofPathToString(ofToDataPath("movies\\",true)).back(), '\\', "absolute ofToDataPath with \\ should end in \\"); (incidentally it's more or less what someone holding to some legacy code using string methods directly on the return of ofDataPath might need to do, but method chaining is not prevalent in user code) |
Great. if we decide to proceed with this idea I'll complete the work in this same PR. |
I've finally finished this one. I've updated the tests accordingly. opinions? @ofTheo @NickHardeman @artificiel @danoli3 |
Wow. Awesome!
Did you run into anything with the tests that might indicate breaking changes for old projects?
|
In the tests the things I had to change is something like ofToDataPath("").back() string resultado = ofSystem("open " + ofToDataPath(fullFileName)); I had to switch to something like: string resultado = ofSystem("open " + ofPathToString(ofToDataPath(fullFileName)));
or
string resultado = ofSystem("open " + ofToDataPath(fullFileName).string()); |
I think this one is ready to go |
What do you think @ofTheo ? |
and just to collect what was discussed elsewhere in the context here, given an string resultado = ofSystem("open " + ofPathToString(ofToDataPath(fullFileName)));
// will not crash but will do something unpredictable (as the string returned will be "") string resultado = ofSystem("open " + ofToDataPath(fullFileName).string());
// will throw/crash I know @dimitre wants C++14 but the proper way of handling such a disappointment is solved with if (auto conformant = ofConformPathToNarrowString(ofToDataPath(fullFileName))) {
auto resultado = ofSystem("open " + conformant.value());
// use resultado with confidence
} else {
ofLogWarning("Your path contains incompatible wide unicode characters)
} a similar behaviour is obtainable with checking for an empty string but it's exactly the pattern that optional wants to eradicate (magic numbers etc). auto conformant = ofConformPathToNarrowString(ofToDataPath(fullFileName));
if (!conform.empty()) {
auto resultado = ofSystem("open " + conformant);
// use resultado with confidence
} else {
ofLogWarning("Your path is empty or contains incompatible wide unicode characters)
} |
@ofTheo please check this one when you have time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah finding some issues with FS vs string this will sort it.
I think the api break is really minor compared to the positive side of having fs::path end to end. |
for devs: paths can be made into strings with .string() on any path (or c_str()). |
the potential problem with path.string() is that if the native path is wide (windows), and contains untranslatable unicode, .string() may throw (
staying C++17, and because we want to minimize the use of try-catch, my suggestion above is to embrace the in all case the idea is that the try-catch is not under the responsibility of the dev- or end-user (i.e. the core itself will not throw unexpectedly because of an untranslatable filesystem path encountered on a (presumably asian) windows filesystem,). |
C++ 20 + for next version of oF I think is do-able
|
OK so for C++17 it's a question of letting usage of .string() un-tryed-catched and risk crashes on windows with asian file paths, or wrapping .string() in a function that catches the exception either with an optional or an empty string. |
I’ll add some utf8 narrowing tests with simplified Chinese and other utf8
charsets.
Related:
https://en.cppreference.com/w/cpp/filesystem/path/u8path
…On Wed, 17 Jul 2024 at 4:26 AM, alexandre burton ***@***.***> wrote:
OK so for C++17 it's a question of letting usage of .string()
un-tryed-catched and risk crashes on windows with asian file paths, or
wrapping .string() in a function that catches the exception either with an
optional or an empty string.
—
Reply to this email directly, view it on GitHub
<#7817 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGK2HDJEIMGUAMLTTKBEY3ZMVQVZAVCNFSM6AAAAABAQXM4QCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMZRGU2DGMRTHA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
@dimitre - Thanks for all the work on this!! Downside obviously is any addon or project that is expecting a string return but gets a path return. It's really hard to gauge how big an impact this would have - I guess I could try it with a large project and see how many errors we have to fix as a general sense. ( curious if it will be as big as the ofVec3f -> glm::vec3 transition ) @ all |
@ofTheo throwing projects and addons at the changes is perhaps the best way to quantify actual disruption, but to be clear there are 2 distinct considerations:
more precisely: something that is implicitly expecting a string, and chains a method (not part of path's interface) onto it. so this will fail (@dimitre's original example above): ofLogNotice("last") << usedToReturnAStringButNowPath().back(); but this will work: (path will self-convert to string) std::string tmp_str = usedToReturnAStringButNowPath();
ofLogNotice("last") << tmp_str.back(); as well as this: (implicit conversion) takesAString(usedToReturnAStringButNowPath()); (note that this behaviour is what makes it possible to transparently toggle between #ifdef WIN32 to call wchar-flavoured versions of library filesystem-related apis) it is difficult to create test cases around unicode narrowing as This will compile, but runtime error on macOS: std::wstring w = L"C:\\example\\path\\";
w += L"\xD83D\xDE00"; // funny stuff
w += L"\\file.txt";
std::filesystem::path p { w }; // << runtime error here note that we don't get to test the but as-is, the proposed changes will work, until a "strange" character is runtime-encountered. |
Thanks for the explanation @artificiel Going to pull these changes into a couple of projects today and see if any errors show up. Thanks all! |
@dimitre I tested this on a large project with a fair number of addons on macOS and it did not cause any compiler or linking errors. I know that's not a perfect indicator but it's a good sign. So I think good to merge from my perspective :) @artificiel @danoli3 what do you think? |
@ofTheo only obscure wide characters, which is specifically windows-specific (or maybe a config file exported in the incompatible character set). So the exception might rise for a windows user with such an obscure character in a path, sending it into an addon that implicitly converts to an std::string. That being said, encountering that case would help as we’d have an actual real world situation to test against… |
Yeah it seems like a windows issue only, macOS no issues with c++23, only
windows starting to see issues with Wchar / wstring. I think maybe a
Microsoft developer may have overthought something that was as simple as
cast all strings as wide.
…On Thu, 18 Jul 2024 at 1:46 PM, alexandre burton ***@***.***> wrote:
@ofTheo <https://github.com/ofTheo> only obscure wide characters, which
is specifically windows-specific (or maybe a config file exported in the
incompatible character set). So the exception might rise for a windows user
with such an obscure character in a path, sending it into an addon that
implicitly converts to an std::string. That being said, encountering that
case would help as we’d have an actual real world situation to test against…
—
Reply to this email directly, view it on GitHub
<#7817 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGK2HGH27P2L2BYOEOKOLDZM43A7AVCNFSM6AAAAABAQXM4QCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMZVGI3DCNBXGM>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Thanks all and thanks @dimitre for doing the legwork! |
this PR is to experiment interoperability between fs::path and string.
I think this was not happening before because of some systems were using
std::experimental::filesystem::v1::__cxx11::path
which caused errors when converting fs::path to string.I've updated ofConstants.h in this PR so __cxx11 is not being used anymore