From 19a0e409771dc82158fb5edb154736fd4dd3575b Mon Sep 17 00:00:00 2001 From: Nicole O'Connor Date: Fri, 14 Feb 2025 12:57:52 -0800 Subject: [PATCH] improvements to cellar translate --- src/core/paths.cpp | 57 ++++++++++++++++++++++++++++++------- src/paths/drive_letters.cpp | 8 +++++- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/core/paths.cpp b/src/core/paths.cpp index bcda715..5d04482 100644 --- a/src/core/paths.cpp +++ b/src/core/paths.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,6 +8,7 @@ #include #include "tclap/CmdLine.h" +#include "bottles.hpp" #include "output.hpp" #include "paths.hpp" #include "version.hpp" @@ -22,10 +24,6 @@ string cellar::paths::translate(std::string in_path, bool lazy) { windows_input = regex_match(in_path.substr(0, 3), drive_letter_rgx); - if (!lazy) { - output::warning("non-lazy path translation is not implemented yet"); - } - if (windows_input) { if (lazy) { if (boost::algorithm::to_lower_copy(in_path.substr(0,1)) != "z") { @@ -44,14 +42,51 @@ string cellar::paths::translate(std::string in_path, bool lazy) { return paths::resolve_drive_letter(in_path); } } else { - // lazy - string out_path = "Z:"; - out_path.append(in_path); + string out_path; + string str_absolutepath = filesystem::canonical(in_path); - size_t slashpos = out_path.find("/"); - while (slashpos != std::string::npos) { - out_path.replace(slashpos, 1, "\\"); - slashpos = out_path.find("/"); + if (lazy) { + out_path = "Z:"; + out_path.append(str_absolutepath); + + size_t slashpos = out_path.find("/"); + while (slashpos != std::string::npos) { + out_path.replace(slashpos, 1, "\\"); + slashpos = out_path.find("/"); + } + } else { + map dct_drives; + for (auto hnd_curitem : filesystem::directory_iterator(filesystem::path(bottles::active_bottle.canonical_path) / "dosdevices")) { + auto pth_curitem = hnd_curitem.path(); + dct_drives.insert_or_assign(pth_curitem.filename().string(), filesystem::canonical(pth_curitem)); + } + + for (auto hnd_curdrive : dct_drives) { + size_t sz_drivelen = hnd_curdrive.second.length(); + size_t sz_findpos = in_path.rfind(hnd_curdrive.second, 0); + if (sz_findpos == 0) { + out_path.append(hnd_curdrive.first); + out_path.append(in_path.substr(sz_drivelen)); + + size_t slashpos = out_path.find("/"); + while (slashpos != std::string::npos) { + out_path.replace(slashpos, 1, "\\"); + slashpos = out_path.find("/"); + } + + break; + } + } + + // if we're here, it's not on a drive letter. use Z: + out_path = "Z:"; + out_path.append(str_absolutepath); + + size_t slashpos = out_path.find("/"); + while (slashpos != std::string::npos) { + out_path.replace(slashpos, 1, "\\"); + slashpos = out_path.find("/"); + } } return out_path; diff --git a/src/paths/drive_letters.cpp b/src/paths/drive_letters.cpp index 452d22d..9e91110 100644 --- a/src/paths/drive_letters.cpp +++ b/src/paths/drive_letters.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -12,6 +13,7 @@ using namespace std; string cellar::paths::resolve_drive_letter(string in_path) { + filesystem::path lastwd = filesystem::current_path(); bool windows_input; static regex drive_letter_rgx(R"([a-zA-Z]:\\)"); @@ -25,6 +27,7 @@ string cellar::paths::resolve_drive_letter(string in_path) { string link_path = ""; link_path.append(bottles::active_bottle.canonical_path); link_path.append("/dosdevices/"); + filesystem::current_path(filesystem::path(link_path)); link_path.append(drive_letter); char stringbuffer[512]; @@ -32,7 +35,9 @@ string cellar::paths::resolve_drive_letter(string in_path) { if (bufflen != -1) { stringbuffer[bufflen] = '\0'; - out_path.append(stringbuffer); + string str_absolutepath = filesystem::canonical(stringbuffer); + out_path.append(str_absolutepath); + out_path.append("/"); } else { throw runtime_error("readlink isn't having it"); } @@ -47,5 +52,6 @@ string cellar::paths::resolve_drive_letter(string in_path) { out_path.append(rest_of_path); } + filesystem::current_path(lastwd); return out_path; }