What does the path need to look like for boost::canonical to work?

Nov 29, 2015 at 1:29am
Why does boost::filesystem::canonical give error on this?

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>

using namespace std;

int main()
{
    string example_path = "D:\\Portables\\REAPER\\_TEST PROJECT\\..\\name.wav";
    string actual_path = boost::filesystem::canonical(example_path).string();
}


The path in question exists on my computer (obviously it will fail if you run code on cpp).

Maybe I am confused as to how canonical() expects the path to be formatted. Could you give an example path that would work with canonical?
Last edited on Nov 29, 2015 at 1:45am
Nov 29, 2015 at 1:44am
What error does it give?

for example, on my linux box, it throws an exception saying

boost::filesystem::canonical: No such file or directory: "/home/cubbi/D:\Portables\REAPER\_TEST PROJECT\..\name.wav"

and here using Visual Studio in an online compiler http://rextester.com/JUI81102
it says boost::filesystem::canonical: No such file or directory: "D:\Portables\REAPER\_TEST PROJECT\..\name.wav"
Last edited on Nov 29, 2015 at 1:52am
Nov 29, 2015 at 2:11am
Ok, that is the error I am getting.

So, name.wav is in _TEST_PROJECT

wouldn't the .. be REAPER? It's one folder up, which would be REAPER.
Last edited on Nov 29, 2015 at 2:12am
Nov 29, 2015 at 2:23am
omg wait a minute... is canonical expecting the name.wav to be there?
Nov 29, 2015 at 2:50am
yes that is the reason........ Cubbi, thanks for your help.
Last edited on Nov 29, 2015 at 2:51am
Nov 29, 2015 at 7:09pm
wait a minute wait wait wait... this is not resolved. I need to convert .. to actual path and the path may not exist. What am I to do? I am making a multiplatform program. Can I assume every .. is just "remove the previous folder in path"? I could make a simple string parsing function for that and not use canonical at all.
Last edited on Nov 29, 2015 at 7:10pm
Nov 29, 2015 at 7:25pm
JUMP past drive letter

D:\Software\Portables\..\REAPER\..\..\..\_TEST PROJECT\..\name.wav

SAVE in buffer until encounter \ . . \
REPLACE from buffer position start to end - 1

\Software\\Portables\..\REAPER\..\..\..\_TEST PROJECT\..\name.wav -> CONTINUE

\Software\REAPER\..\..\..\_TEST PROJECT\..\name.wav -> CONTINUE

\Software\..\..\_TEST PROJECT\..\name.wav -> CONTINUE

\..\_TEST PROJECT\..\name.wav -> ERROR

1
2
3
4
5
6
7
8
9
10
11
D:\Portables\REAPER\_TEST PROJECT\..\name.wav -> D:\Portables\REAPER\name.wav

D:\Portables\REAPER\..\_TEST PROJECT\name.wav -> D:\Portables\_TEST PROJECT\name.wav

D:\Portables\REAPER\..\..\_TEST PROJECT\name.wav -> D:\_TEST PROJECT\name.wav

D:\Portables\REAPER\..\..\_TEST PROJECT\..\name.wav -> D:\name.wav

D:\Portables\..\REAPER\..\..\_TEST PROJECT\..\name.wav -> (!!ERROR!!) D:\..\name.wav

D:\Portables\REAPER\_TEST PROJECT\name.wav\.. -> (STILL GOOD) D:\Portables\REAPER\_TEST PROJECT\
Last edited on Nov 29, 2015 at 7:36pm
Nov 29, 2015 at 7:55pm
why "a simple string parsing function" if you have boost.filesystem already?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <boost/filesystem.hpp>
#include <vector>
#include <iostream>

namespace fs = boost::filesystem;
int main()
{
    std::vector<fs::path> v = {
       "D:\\Portables\\REAPER\\_TEST PROJECT\\..\\name.wav",
       "D:\\Portables\\REAPER\\..\\_TEST PROJECT\\name.wav",
       "D:\\Portables\\REAPER\\..\\..\\_TEST PROJECT\\name.wav",
       "D:\\Portables\\REAPER\\..\\..\\_TEST PROJECT\\..\\name.wav",
       "D:\\Portables\\..\\REAPER\\..\\..\\_TEST PROJECT\\..\\name.wav",
       "D:\\Portables\\REAPER\\_TEST PROJECT\\name.wav\\.."};

    for(fs::path p: v) {
        std::cout << p << " -> ";
        fs::path root = p.is_absolute() ? p.root_path() : absolute(p).root_path();
        fs::path result;
        for(fs::path f: absolute(p)) {
            if(f == ".") {
                continue;
            } else if(f == "..") {
                if(result == root) {
                    result.clear();
                    break;
                } else {
                   result.remove_filename();
                }
                continue;
            } else {
                result /= f;
            }
        }
        std::cout << result << '\n';
    }
}


live demo: http://rextester.com/IDXG70343

"D:\Portables\REAPER\_TEST PROJECT\..\name.wav" -> "D:/Portables\REAPER\name.wav"
"D:\Portables\REAPER\..\_TEST PROJECT\name.wav" -> "D:/Portables\_TEST PROJECT\name.wav"
"D:\Portables\REAPER\..\..\_TEST PROJECT\name.wav" -> "D:/_TEST PROJECT\name.wav"
"D:\Portables\REAPER\..\..\_TEST PROJECT\..\name.wav" -> "D:/name.wav"
"D:\Portables\..\REAPER\..\..\_TEST PROJECT\..\name.wav" -> ""
"D:\Portables\REAPER\_TEST PROJECT\name.wav\.." -> "D:/Portables\REAPER\_TEST PROJECT"
Nov 29, 2015 at 8:36pm
Thanks! resolved.
Topic archived. No new replies allowed.