17 std::string vul_expand_path_internal(std::string path)
23 std::vector<std::string> bits;
27 for (
unsigned int i=0; i<path.size(); ) {
34 while (j<path.size() && path[j]!=
'/')
36 bits.push_back(std::string(path.c_str()+i, path.c_str()+j));
45 for (
unsigned int i=0; i<bits.size(); ++i)
48 if (i>0 && i+1<bits.size() && bits[i] ==
"/" && bits[i+1] ==
"/") {
49 bits.erase(bits.begin() + i);
54 if (i+1 == bits.size() && bits[i] ==
"/") {
60 if (i+2<bits.size() && !(bits[i]==
"/") && bits[i+1]==
"/" && bits[i+2]==
"..") {
61 bits.erase(bits.begin() + i+2);
62 bits.erase(bits.begin() + i);
67 if (i+1<bits.size() && bits[i]==
"/" && bits[i+1]==
".") {
68 bits.erase(bits.begin() + i+1);
69 bits.erase(bits.begin() + i);
79 for (
unsigned int i=0; i<bits.size(); ++i)
82 std::cerr <<
"recomposed : " << path <<
'\n';
94 return vul_expand_path_internal(path);
98 #if VXL_USE_WIN_WCHAR_T 101 std::wstring vul_expand_path_internal(std::wstring path)
107 std::vector<std::wstring> bits;
111 for (
unsigned int i=0; i<path.size(); ) {
112 if (path[i] == L
'/') {
113 bits.push_back(L
"/");
118 while (j<path.size() && path[j]!=L
'/')
120 bits.push_back(std::wstring(path.c_str()+i, path.c_str()+j));
129 for (
unsigned int i=0; i<bits.size(); ++i)
132 if (i>0 && i+1<bits.size() && bits[i] == L
"/" && bits[i+1] == L
"/") {
133 bits.erase(bits.begin() + i);
138 if (i+1 == bits.size() && bits[i] == L
"/") {
144 if (i+2<bits.size() && !(bits[i]==L
"/") && bits[i+1]==L
"/" && bits[i+2]==L
"..") {
145 bits.erase(bits.begin() + i+2);
146 bits.erase(bits.begin() + i);
151 if (i+1<bits.size() && bits[i]==L
"/" && bits[i+1]==L
".") {
152 bits.erase(bits.begin() + i+1);
153 bits.erase(bits.begin() + i);
163 for (
unsigned int i=0; i<bits.size(); ++i)
166 std::cerr <<
"recomposed : " << path <<
'\n';
178 return vul_expand_path_internal(path);
181 #endif //VXL_USE_WIN_WCHAR_T 183 #else // #if defined(_WIN32) 186 # include <vcl_msvc_warnings.h> 188 #include <sys/types.h> 189 #include <sys/stat.h> 194 std::string vul_expand_path_internal(std::string path)
200 if ((path.size()>=2 && path[0] ==
'~' && path[1] ==
'/') || path ==
"~") {
201 char const *HOME = std::getenv(
"HOME");
206 path = std::string(HOME) + std::string(path.c_str() + 1);
211 if (path.size()>=1 && path[0] !=
'/')
212 path = std::string(
"./") + path;
215 if ((path.size()>=2 && path[0] ==
'.' && path[1] ==
'/') || path ==
".") {
217 if( getcwd(cwd,
sizeof cwd) == nullptr ) {
218 path =
"<error: current working directory path > 4096 characters>";
220 path = std::string(cwd) + path.substr(1);
225 std::vector<std::string> bits;
229 for (
unsigned int i=0; i<path.size(); ) {
230 if (path[i] ==
'/') {
231 bits.emplace_back(
"/");
236 while (j<path.size() && path[j]!=
'/')
238 bits.emplace_back(path.c_str()+i, path.c_str()+j);
247 for (
unsigned int i=0; i<bits.size(); ++i)
250 if (i+1<bits.size() && bits[i] ==
"/" && bits[i+1] ==
"/") {
251 bits.erase(bits.begin() + i);
256 if (i+1 == bits.size() && bits[i] ==
"/") {
262 if (i+2<bits.size() && !(bits[i]==
"/") && bits[i+1]==
"/" && bits[i+2]==
"..") {
263 bits.erase(bits.begin() + i+2);
264 bits.erase(bits.begin() + i);
269 if (i+1<bits.size() && bits[i]==
"/" && bits[i+1]==
".") {
270 bits.erase(bits.begin() + i+1);
271 bits.erase(bits.begin() + i);
281 for (
const auto & bit : bits)
284 std::cerr <<
"recomposed : " << path <<
'\n';
289 for (
unsigned int i=1; i<=path.size(); ++i)
291 if (i==path.size() || path[i] ==
'/')
293 std::string sub(path.c_str(), path.c_str() + i);
295 int len = readlink(sub.c_str(), buf,
sizeof buf);
300 std::cerr <<
"before expansion : " << path <<
'\n';
305 path = std::string(buf, buf+len) + std::string(path.c_str() + i);
311 while (j>=0 && path[j] !=
'/')
315 std::string a = std::string(path.c_str(), path.c_str()+j+1);
316 std::string b = std::string(buf, buf+len);
317 std::string c = std::string(path.c_str() + i, path.c_str() + path.size());
319 std::cerr <<
"a = " << a <<
"\nb = " << b <<
"\nc = " << c <<
'\n';
325 path = std::string(buf, buf+len) + std::string(path.c_str() + i);
330 std::cerr <<
"after expansion : " << path <<
'\n';
332 return vul_expand_path_internal(path);
341 typedef std::map<std::string, std::string, std::less<std::string> >
map_t;
346 static map_t the_map;
349 auto i = the_map.find(path);
351 if (i == the_map.end()) {
353 std::string mapped = vul_expand_path_internal(path);
355 i = the_map.insert(map_t::value_type(path, mapped)).first;
364 return vul_expand_path_internal(std::move(path));
Contains two functions to compute expanded form of a given path.
std::string vul_expand_path_uncached(std::string path)
Expand given path.
std::map< std::string, std::string, std::less< std::string > > map_t
std::string vul_expand_path(std::string path)
Expand given path.