mirror of https://gitlab.com/cppit/jucipp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
6.5 KiB
216 lines
6.5 KiB
#include <fstream> |
|
#include <iostream> |
|
#include <sstream> |
|
#include <algorithm> |
|
|
|
#include "filesystem.h" |
|
|
|
//Only use on small files |
|
std::string filesystem::read(const std::string &path) { |
|
std::stringstream ss; |
|
std::ifstream input(path, std::ofstream::binary); |
|
if(input) { |
|
ss << input.rdbuf(); |
|
input.close(); |
|
} |
|
return ss.str(); |
|
} |
|
|
|
//Only use on small files |
|
std::vector<std::string> filesystem::read_lines(const std::string &path) { |
|
std::vector<std::string> res; |
|
std::ifstream input(path, std::ofstream::binary); |
|
if (input) { |
|
do { res.emplace_back(); } while(getline(input, res.back())); |
|
} |
|
input.close(); |
|
return res; |
|
} |
|
|
|
//Only use on small files |
|
bool filesystem::write(const std::string &path, const std::string &new_content) { |
|
std::ofstream output(path, std::ofstream::binary); |
|
if(output) |
|
output << new_content; |
|
else |
|
return false; |
|
output.close(); |
|
return true; |
|
} |
|
|
|
std::string filesystem::escape_argument(const std::string &argument) { |
|
auto escaped=argument; |
|
for(size_t pos=0;pos<escaped.size();++pos) { |
|
if(escaped[pos]==' ' || escaped[pos]=='(' || escaped[pos]==')' || escaped[pos]=='\'' || escaped[pos]=='"') { |
|
escaped.insert(pos, "\\"); |
|
++pos; |
|
} |
|
} |
|
return escaped; |
|
} |
|
|
|
std::string filesystem::unescape_argument(const std::string &argument) { |
|
auto unescaped=argument; |
|
|
|
if(unescaped.size()>=2) { |
|
if((unescaped[0]=='\'' && unescaped[unescaped.size()-1]=='\'') || |
|
(unescaped[0]=='"' && unescaped[unescaped.size()-1]=='"')) { |
|
char quotation_mark=unescaped[0]; |
|
unescaped=unescaped.substr(1, unescaped.size()-2); |
|
size_t backslash_count=0; |
|
for(size_t pos=0;pos<unescaped.size();++pos) { |
|
if(backslash_count%2==1 && (unescaped[pos]=='\\' || unescaped[pos]==quotation_mark)) { |
|
unescaped.erase(pos-1, 1); |
|
--pos; |
|
backslash_count=0; |
|
} |
|
else if(unescaped[pos]=='\\') |
|
++backslash_count; |
|
else |
|
backslash_count=0; |
|
} |
|
return unescaped; |
|
} |
|
} |
|
|
|
size_t backslash_count=0; |
|
for(size_t pos=0;pos<unescaped.size();++pos) { |
|
if(backslash_count%2==1 && (unescaped[pos]=='\\' || unescaped[pos]==' ' || unescaped[pos]=='(' || unescaped[pos]==')' || unescaped[pos]=='\'' || unescaped[pos]=='"')) { |
|
unescaped.erase(pos-1, 1); |
|
--pos; |
|
backslash_count=0; |
|
} |
|
else if(unescaped[pos]=='\\') |
|
++backslash_count; |
|
else |
|
backslash_count=0; |
|
} |
|
return unescaped; |
|
} |
|
|
|
boost::filesystem::path filesystem::get_home_path() noexcept { |
|
std::vector<std::string> environment_variables = {"HOME", "AppData"}; |
|
char *ptr = nullptr; |
|
for (auto &variable : environment_variables) { |
|
ptr=std::getenv(variable.c_str()); |
|
boost::system::error_code ec; |
|
if (ptr!=nullptr && boost::filesystem::exists(ptr, ec)) |
|
return ptr; |
|
} |
|
return boost::filesystem::path(); |
|
} |
|
|
|
boost::filesystem::path filesystem::get_short_path(const boost::filesystem::path &path) noexcept { |
|
#ifdef _WIN32 |
|
return path; |
|
#else |
|
static auto home_path=get_home_path(); |
|
if(!home_path.empty()) { |
|
auto relative_path=filesystem::get_relative_path(path, home_path); |
|
if(!relative_path.empty()) |
|
return "~"/relative_path; |
|
} |
|
return path; |
|
#endif |
|
} |
|
|
|
bool filesystem::file_in_path(const boost::filesystem::path &file_path, const boost::filesystem::path &path) { |
|
if(std::distance(file_path.begin(), file_path.end())<std::distance(path.begin(), path.end())) |
|
return false; |
|
return std::equal(path.begin(), path.end(), file_path.begin()); |
|
} |
|
|
|
boost::filesystem::path filesystem::find_file_in_path_parents(const std::string &file_name, const boost::filesystem::path &path) { |
|
auto current_path=path; |
|
while(true) { |
|
auto test_path=current_path/file_name; |
|
if(boost::filesystem::exists(test_path)) |
|
return test_path; |
|
if(current_path==current_path.root_directory()) |
|
return boost::filesystem::path(); |
|
current_path=current_path.parent_path(); |
|
} |
|
} |
|
|
|
boost::filesystem::path filesystem::get_normal_path(const boost::filesystem::path &path) noexcept { |
|
boost::filesystem::path normal_path; |
|
|
|
for(auto &e: path) { |
|
if(e==".") |
|
continue; |
|
else if(e=="..") { |
|
auto parent_path=normal_path.parent_path(); |
|
if(!parent_path.empty()) |
|
normal_path=parent_path; |
|
else |
|
normal_path/=e; |
|
} |
|
else if(e.empty()) |
|
continue; |
|
else |
|
normal_path/=e; |
|
} |
|
|
|
return normal_path; |
|
} |
|
|
|
boost::filesystem::path filesystem::get_relative_path(const boost::filesystem::path &path, const boost::filesystem::path &base) noexcept { |
|
boost::filesystem::path relative_path; |
|
|
|
if(std::distance(path.begin(), path.end())<std::distance(base.begin(), base.end())) |
|
return boost::filesystem::path(); |
|
|
|
auto base_it=base.begin(); |
|
auto path_it=path.begin(); |
|
while(path_it!=path.end() && base_it!=base.end()) { |
|
if(*path_it!=*base_it) |
|
return boost::filesystem::path(); |
|
++path_it; |
|
++base_it; |
|
} |
|
for(;path_it!=path.end();++path_it) |
|
relative_path/=*path_it; |
|
|
|
return relative_path; |
|
} |
|
|
|
boost::filesystem::path filesystem::get_executable(const boost::filesystem::path &executable_name) noexcept { |
|
#if defined(__APPLE__) || defined(_WIN32) |
|
return executable_name; |
|
#endif |
|
|
|
static std::vector<boost::filesystem::path> bin_paths={"/usr/bin", "/usr/local/bin"}; |
|
|
|
try { |
|
for(auto &path: bin_paths) { |
|
if(boost::filesystem::exists(path/executable_name)) |
|
return executable_name; |
|
} |
|
|
|
auto executable_name_str = executable_name.string(); |
|
for(auto &path: bin_paths) { |
|
boost::filesystem::path executable; |
|
for(boost::filesystem::directory_iterator it(path), end; it != end; ++it) { |
|
auto it_path = it->path(); |
|
auto it_path_filename_str = it_path.filename().string(); |
|
if(!it_path_filename_str.empty() && it_path_filename_str.compare(0, executable_name_str.size(), executable_name_str)==0) { |
|
if(it_path > executable && |
|
((it_path_filename_str.size() > executable_name_str.size() && |
|
it_path_filename_str[executable_name_str.size()]>='0' && |
|
it_path_filename_str[executable_name_str.size()]<='9') || |
|
(it_path_filename_str.size() > executable_name_str.size()+1 && |
|
it_path_filename_str[executable_name_str.size()]=='-' && |
|
it_path_filename_str[executable_name_str.size()+1]>='0' && |
|
it_path_filename_str[executable_name_str.size()+1]<='9')) && |
|
!boost::filesystem::is_directory(it_path)) |
|
executable=it_path; |
|
} |
|
} |
|
if(!executable.empty()) |
|
return executable; |
|
} |
|
} |
|
catch(...) {} |
|
|
|
return executable_name; |
|
}
|
|
|