Discussion:
[Boost-users] boost::filesystem::native
Christopher J. Pisz
2016-11-10 20:05:00 UTC
Permalink
I did a Google search to see how to check if a given path is valid,
preferably using boost.

It brought me here:

http://stackoverflow.com/questions/10426671/how-to-check-if-path-is-valid-in-boostfilesystem

Great! I say to myself.
I then Google up the boost doc here:
http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/portability_guide.htm

I then write myself a test:



#include <iostream>
#include <sstream>

#include <boost/filesystem.hpp>

int main()
{
const std::string test1 = "D:\\Programing Projects\\Git
Workspace\\Common\\x64\\Debug";
const std::string test2 = "D:\Programing Projects\\Git
Workspace\\Common\\x64\\Debug\\";
const std::string test3 = "D:/Programing Projects/Git
Workspace/Common/x64/Debug";
const std::string test4 = "D:/Programing Projects/Git
Workspace/Common/x64/Debug/";

if (!boost::filesystem::native(test1))
{
std::cout << "Boost says the following path is not valid
for the native operating system: " << test1 << std::endl;
}

if (!boost::filesystem::native(test2))
{
std::cout << "Boost says the following path is not valid
for the native operating system: " << test2 << std::endl;
}

if (!boost::filesystem::native(test3))
{
std::cout << "Boost says the following path is not valid for
the native operating system: " << test3 << std::endl;
}

if (!boost::filesystem::native(test4))
{
std::cout << "Boost says the following path is not valid
for the native operating system: " << test4 << std::endl;

}

return 0;
}

The Test's Output:

Boost says the following path is not valid for the native operating
system: D:\Programing Projects\Git Workspace\Common\x64\Debug
Boost says the following path is not valid for the native operating
system: D:Programing Projects\Git Workspace\Common\x64\Debug\
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug/

What is wrong with that path that it says it is not valid for my native
Windows 10 operating system?
Fernando Gomes da Silva
2016-11-10 20:19:18 UTC
Permalink
can you try it:

std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("C:\PATH") << std::endl;
std::cout << boost::filesystem::native("\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl;

RegardsFernando Gomes.
Post by Christopher J. Pisz
I did a Google search to see how to check if a given path is valid,
preferably using boost.
http://stackoverflow.com/questions/10426671/how-to-check-if-
path-is-valid-in-boostfilesystem
Great! I say to myself.
http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/por
tability_guide.htm
#include <iostream>
#include <sstream>
#include <boost/filesystem.hpp>
int main()
{
const std::string test1 = "D:\\Programing Projects\\Git
Workspace\\Common\\x64\\Debug";
const std::string test2 = "D:\Programing Projects\\Git
Workspace\\Common\\x64\\Debug\\";
const std::string test3 = "D:/Programing Projects/Git
Workspace/Common/x64/Debug";
const std::string test4 = "D:/Programing Projects/Git
Workspace/Common/x64/Debug/";
if (!boost::filesystem::native(test1))
{
std::cout << "Boost says the following path is not valid for
the native operating system: " << test1 << std::endl;
}
if (!boost::filesystem::native(test2))
{
std::cout << "Boost says the following path is not valid for
the native operating system: " << test2 << std::endl;
}
if (!boost::filesystem::native(test3))
{
std::cout << "Boost says the following path is not valid for the
native operating system: " << test3 << std::endl;
}
if (!boost::filesystem::native(test4))
{
std::cout << "Boost says the following path is not valid for
the native operating system: " << test4 << std::endl;
}
return 0;
}
Boost says the following path is not valid for the native operating
system: D:\Programing Projects\Git Workspace\Common\x64\Debug
Boost says the following path is not valid for the native operating
system: D:Programing Projects\Git Workspace\Common\x64\Debug\
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug/
What is wrong with that path that it says it is not valid for my native
Windows 10 operating system?
_______________________________________________
Boost-users mailing list
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Christopher J. Pisz
2016-11-10 21:40:45 UTC
Permalink
Post by Fernando Gomes da Silva
std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("C:\PATH") << std::endl;
std::cout << boost::filesystem::native("\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl;
0
0
0
0
1
0
0
0

Not at all the expected results.
Gavin Lambert
2016-11-10 22:19:20 UTC
Permalink
Post by Christopher J. Pisz
Post by Fernando Gomes da Silva
std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("C:\PATH") << std::endl;
std::cout << boost::filesystem::native("\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl;
0
0
0
0
1
0
0
0
Not at all the expected results.
That's especially weird considering that "\P" should be an invalid
escape sequence, which should give you a compiler warning/error and/or
should make "\PATH" give identical results to "\\PATH".

Unless you further escaped these before compiling it?
Fernando Gomes da Silva
2016-11-10 22:25:37 UTC
Permalink
i did another test here, like this:

std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("C:\PATH") << std::endl;
std::cout << boost::filesystem::native("\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl;




*std::cout << boost::filesystem::native("c\PATH") << std::endl;std::cout <<
boost::filesystem::native("c\\PATH") << std::endl;std::cout <<
boost::filesystem::native("c/PATH") << std::endl;std::cout <<
boost::filesystem::native("c//PATH") << std::endl;*

No, in VS2015 - 32bits. Build Success.
Post by Christopher J. Pisz
Post by Fernando Gomes da Silva
std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("C:\PATH") << std::endl;
std::cout << boost::filesystem::native("\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl;
0
0
0
0
1
0
0
0
Not at all the expected results.
That's especially weird considering that "\P" should be an invalid escape
sequence, which should give you a compiler warning/error and/or should make
"\PATH" give identical results to "\\PATH".
Unless you further escaped these before compiling it?
_______________________________________________
Boost-users mailing list
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Christopher J. Pisz
2016-11-10 22:50:15 UTC
Permalink
On 11/10/2016 4:25 PM, Fernando Gomes da Silva wrote:
SNIP
Post by Gavin Lambert
That's especially weird considering that "\P" should be an invalid
escape sequence, which should give you a compiler warning/error
and/or should make "\PATH" give identical results to "\\PATH".
Unless you further escaped these before compiling it?
That is wierd. It seems to be an error on rebuild. Disregard those
results I guess. I don't know how I got it to run.

Here is another test I just tried, making this set of boost functions
and thier documentation appear even more confusing to me.

#include <iostream>
#include <sstream>

#include <boost/filesystem.hpp>


// Just a garbage console application to do some manual testing.
int main()
{
std::cout << boost::filesystem::native("C://PATH") << std::endl;
std::cout << boost::filesystem::native("C:/PATH") << std::endl;
std::cout << boost::filesystem::native("C:\\PATH") << std::endl;
std::cout << boost::filesystem::native("\\PATH") << std::endl;
std::cout << boost::filesystem::native("/PATH") << std::endl;
std::cout << boost::filesystem::native("//PATH") << std::endl <<
std::endl;

std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"C://PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"C:/PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"C:\\PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"\\PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"/PATH")) << std::endl;
std::cout << boost::filesystem::native(reinterpret_cast<char
*>(L"//PATH")) << std::endl;

return 0;
}


0
0
0
0
0
0

1
1
1
0
0
0
Gavin Lambert
2016-11-10 23:02:55 UTC
Permalink
Post by Gavin Lambert
That's especially weird considering that "\P" should be an invalid
escape sequence, which should give you a compiler warning/error
and/or should make "\PATH" give identical results to "\\PATH".
Disregard this and check my other reply. I was confused and incorrect
about how invalid escapes are treated.
reinterpret_cast<char *>(L"C://PATH"))
Never ever do that. Just, no.
Gavin Lambert
2016-11-10 22:51:44 UTC
Permalink
Post by Christopher J. Pisz
Great! I say to myself.
http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/portability_guide.htm
[...]
Post by Christopher J. Pisz
Boost says the following path is not valid for the native operating
system: D:\Programing Projects\Git Workspace\Common\x64\Debug
Boost says the following path is not valid for the native operating
system: D:Programing Projects\Git Workspace\Common\x64\Debug\
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug/
What is wrong with that path that it says it is not valid for my native
Windows 10 operating system?
After looking at the implementation and reading the docs more carefully:

Your assumptions were wrong. :)

It turns out that the portability functions (native() and friends) do
not check *paths* for validity, they check *path components* (eg.
individual filenames).

In particular the path separator characters are considered invalid.

This is why "\PATH" is considered valid, because this is treated as
"PATH", while "\\PATH" is not valid because the backslash is invalid in
a filename.

So if you wanted to use those, you'd need to wrap it in a path() first
and iterate over each element to test if it is valid.
Gavin Lambert
2016-11-10 22:57:30 UTC
Permalink
Post by Gavin Lambert
So if you wanted to use those, you'd need to wrap it in a path() first
and iterate over each element to test if it is valid.
Or, of course, since you're testing a directory name, you can just use
exists() to test the path as a whole (since presumably that's what you
really care about).
Christopher J. Pisz
2016-11-10 23:07:58 UTC
Permalink
Post by Gavin Lambert
Post by Christopher J. Pisz
Great! I say to myself.
http://www.boost.org/doc/libs/1_62_0/libs/filesystem/doc/portability_guide.htm
[...]
Post by Christopher J. Pisz
Boost says the following path is not valid for the native operating
system: D:\Programing Projects\Git Workspace\Common\x64\Debug
Boost says the following path is not valid for the native operating
system: D:Programing Projects\Git Workspace\Common\x64\Debug\
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug
Boost says the following path is not valid for the native operating
system: D:/Programing Projects/Git Workspace/Common/x64/Debug/
What is wrong with that path that it says it is not valid for my native
Windows 10 operating system?
Your assumptions were wrong. :)
It turns out that the portability functions (native() and friends) do
not check *paths* for validity, they check *path components* (eg.
individual filenames).
In particular the path separator characters are considered invalid.
This is why "\PATH" is considered valid, because this is treated as
"PATH", while "\\PATH" is not valid because the backslash is invalid in
a filename.
So if you wanted to use those, you'd need to wrap it in a path() first
and iterate over each element to test if it is valid.
The docs really should clarify that. Google searches all over point to
this function for that purpose and it is even marked as an answer on
Stack Overflow.

If we cannot check for a valid path using this function, then does boost
indeed provide us a means for checking that a path is valid?

...Where valid means the given path does not necessarily point to a file
or directory, but could point to one if it was first created.
Gavin Lambert
2016-11-10 23:23:25 UTC
Permalink
Post by Christopher J. Pisz
The docs really should clarify that. Google searches all over point to
this function for that purpose and it is even marked as an answer on
Stack Overflow.
It is mentioned in the comments on that answer that it only works on the
filename portion of the path.

And it is mentioned in the docs, as long as you don't interpret
"filename" and "path" to be the same thing.

In particular note the description of windows_name().
Post by Christopher J. Pisz
If we cannot check for a valid path using this function, then does boost
indeed provide us a means for checking that a path is valid?
...Where valid means the given path does not necessarily point to a file
or directory, but could point to one if it was first created.
As I mentioned in my other reply, you can use exists(). Or if it
doesn't exist, you can try creating it. Otherwise I'm not aware of
anything that'd do it, other than iterating the path and checking each
component separately.

Most of the time, given a directory path, exists() or
create_directories() would be the simplest option (though the latter
throws on failure).
Christopher J. Pisz
2016-11-10 23:28:22 UTC
Permalink
Post by Gavin Lambert
Post by Christopher J. Pisz
The docs really should clarify that. Google searches all over point to
this function for that purpose and it is even marked as an answer on
Stack Overflow.
It is mentioned in the comments on that answer that it only works on the
filename portion of the path.
And it is mentioned in the docs, as long as you don't interpret
"filename" and "path" to be the same thing.
In particular note the description of windows_name().
Post by Christopher J. Pisz
If we cannot check for a valid path using this function, then does boost
indeed provide us a means for checking that a path is valid?
...Where valid means the given path does not necessarily point to a file
or directory, but could point to one if it was first created.
As I mentioned in my other reply, you can use exists(). Or if it
doesn't exist, you can try creating it. Otherwise I'm not aware of
anything that'd do it, other than iterating the path and checking each
component separately.
Most of the time, given a directory path, exists() or
create_directories() would be the simplest option (though the latter
throws on failure).
Fair enough! Thank you for solving today's mystery!

Loading...