fix fullpath with wildcard in file part
[scilab.git] / scilab / modules / fileio / src / cpp / fullpath.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2019-2011 - St├ęphane MOTTELET
4 *
5  *
6  * This file is hereby licensed under the terms of the GNU GPL v2.0,
7  * pursuant to article 5.3.4 of the CeCILL v.2.1.
8  * This file was originally licensed under the terms of the CeCILL v2.1,
9  * and continues to be available under such terms.
10  * For more information, see the COPYING file which you should have received
11  * along with this program.
12 *
13 */
14 /*--------------------------------------------------------------------------*/
15
16 #include <filesystem>
17
18 extern "C"
19 {
20 #include "charEncoding.h"
21 #include "fullpath.h"
22 #include "sci_malloc.h"
23 #include "os_string.h"
24 }
25
26 char *get_full_path(const char *_Path)
27 {
28 #ifdef _MSC_VER
29     char *_FullPath = NULL;
30     wchar_t *wFullPath = NULL;
31     wchar_t *wPath = to_wide_string((char *)_Path);
32
33     if (wPath)
34     {
35         wFullPath = get_full_pathW(wPath);
36         FREE(wPath);
37         if (wFullPath)
38         {
39             _FullPath = wide_string_to_UTF8(wFullPath);
40             FREE(wFullPath);
41         }
42     }
43     return _FullPath;
44 #else // POSIX
45     std::filesystem::path relPath = std::filesystem::path(_Path);
46     std::filesystem::path canonPath = std::filesystem::weakly_canonical(relPath);
47     auto relPathIt = relPath.end();
48     auto canonPathIt = canonPath.end();
49     if ((--relPathIt)->string().empty() && !(--canonPathIt)->string().empty())
50     {
51         canonPath /= "";
52     }
53
54     return os_strdup(std::filesystem::absolute(canonPath).string().c_str());
55 #endif // _MSC_VER
56 }
57
58 /*--------------------------------------------------------------------------*/
59 wchar_t *get_full_pathW(const wchar_t * _wcPath)
60 {
61 #ifdef _MSC_VER
62     std::wstring s(_wcPath);
63     size_t pos = s.find_last_of(L"/\\");
64
65     //remove "file" part
66     bool bAppend = false;
67     if (pos != std::wstring::npos && s.substr(pos + 1) != L"..")
68     {
69         s = s.substr(0, pos);
70         bAppend = true;
71     }
72
73     std::filesystem::path relPath = std::filesystem::path(s);
74     std::filesystem::path canonPath = std::filesystem::weakly_canonical(relPath);
75     auto relPathIt = relPath.end();
76     auto canonPathIt = canonPath.end();
77     if ((--relPathIt)->wstring().empty() && !(--canonPathIt)->wstring().empty())
78     {
79         canonPath /= "";
80     }
81
82     std::filesystem::path p = std::filesystem::absolute(canonPath);
83
84     //add "file" part
85     if (bAppend)
86     {
87         p /= (_wcPath + pos + 1);
88     }
89
90     return os_wcsdup(p.wstring().c_str());
91 #else // POSIX
92     char *_FullPath = NULL;
93     wchar_t *wFullPath = NULL;
94     char *_Path = wide_string_to_UTF8(_wcPath);
95
96     if (_Path)
97     {
98         _FullPath = get_full_path(_Path);
99         FREE(_Path);
100         if (_FullPath)
101         {
102             wFullPath = to_wide_string(_FullPath);
103             FREE(_FullPath);
104         }
105     }
106     return wFullPath;
107 #endif // _MSC_VER
108 }