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 #include "expandPathVariable.h"
25 }
26 
get_full_path(const char * _Path)27 char *get_full_path(const char *_Path)
28 {
29 #ifdef _MSC_VER
30     char *_FullPath = NULL;
31     wchar_t *wFullPath = NULL;
32     wchar_t *wPath = to_wide_string((char *)_Path);
33 
34     if (wPath)
35     {
36         wFullPath = get_full_pathW(wPath);
37         FREE(wPath);
38         if (wFullPath)
39         {
40             _FullPath = wide_string_to_UTF8(wFullPath);
41             FREE(wFullPath);
42         }
43     }
44     return _FullPath;
45 #else // POSIX
46     char* expanded = expandPathVariable(_Path);
47     std::filesystem::path p = std::filesystem::path(expanded);
48     FREE(expanded);
49     if (p.empty())
50     {
51         p = std::filesystem::current_path();
52     }
53     else
54     {
55         if (p.is_relative())
56         {
57             p = std::filesystem::absolute(p);
58         }
59         p = std::filesystem::weakly_canonical(p);
60     }
61 
62     // preserve trailing slash
63     size_t len = strlen(_Path);
64     if (len > 0 && _Path[len - 1] == std::filesystem::path::preferred_separator)
65     {
66         p /= "";
67     }
68 
69     return os_strdup(p.string().c_str());
70 #endif // _MSC_VER
71 }
72 
73 /*--------------------------------------------------------------------------*/
get_full_pathW(const wchar_t * _wcPath)74 wchar_t *get_full_pathW(const wchar_t * _wcPath)
75 {
76 #ifdef _MSC_VER
77     wchar_t* pwstExpand = expandPathVariableW(_wcPath);
78     std::filesystem::path p = std::filesystem::path(pwstExpand);
79     FREE(pwstExpand);
80     if (p.empty())
81     {
82         p = std::filesystem::current_path();
83     }
84     else
85     {
86         if (p.is_relative())
87         {
88             p = std::filesystem::absolute(p);
89         }
90         p = std::filesystem::weakly_canonical(p);
91     }
92 
93     // preserve trailing slash
94     size_t len = wcslen(_wcPath);
95     if (len > 0 && _wcPath[len - 1] == std::filesystem::path::preferred_separator)
96     {
97         p /= "";
98     }
99 
100     return os_wcsdup(p.wstring().c_str());
101 #else // POSIX
102     char *_FullPath = NULL;
103     wchar_t *wFullPath = NULL;
104     char *_Path = wide_string_to_UTF8(_wcPath);
105 
106     if (_Path)
107     {
108         _FullPath = get_full_path(_Path);
109         FREE(_Path);
110         if (_FullPath)
111         {
112             wFullPath = to_wide_string(_FullPath);
113             FREE(_FullPath);
114         }
115     }
116     return wFullPath;
117 #endif // _MSC_VER
118 }
119