2017-01-28 04:49:09 +08:00
|
|
|
#include "pch.h"
|
2016-09-19 11:50:08 +08:00
|
|
|
#include "vcpkg_Files.h"
|
2016-12-01 06:08:43 +08:00
|
|
|
#include "vcpkg_System.h"
|
2016-09-19 11:50:08 +08:00
|
|
|
|
2017-01-06 04:47:08 +08:00
|
|
|
namespace vcpkg::Files
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2016-09-24 08:57:18 +08:00
|
|
|
static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])");
|
|
|
|
|
2017-04-09 07:26:26 +08:00
|
|
|
struct RealFilesystem : Filesystem
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
virtual Expected<std::string> read_contents(const fs::path& file_path) const override
|
2016-09-19 11:50:08 +08:00
|
|
|
{
|
2017-04-09 07:26:26 +08:00
|
|
|
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
|
|
|
|
if (file_stream.fail())
|
|
|
|
{
|
|
|
|
return std::errc::no_such_file_or_directory;
|
|
|
|
}
|
|
|
|
|
|
|
|
file_stream.seekg(0, file_stream.end);
|
|
|
|
auto length = file_stream.tellg();
|
|
|
|
file_stream.seekg(0, file_stream.beg);
|
|
|
|
|
|
|
|
if (length > SIZE_MAX)
|
|
|
|
{
|
|
|
|
return std::errc::file_too_large;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string output;
|
|
|
|
output.resize(static_cast<size_t>(length));
|
|
|
|
file_stream.read(&output[0], length);
|
|
|
|
file_stream.close();
|
|
|
|
|
|
|
|
return std::move(output);
|
2016-09-19 11:50:08 +08:00
|
|
|
}
|
2017-04-09 11:19:35 +08:00
|
|
|
virtual Expected<std::vector<std::string>> read_all_lines(const fs::path& file_path) const override
|
|
|
|
{
|
|
|
|
std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary);
|
|
|
|
if (file_stream.fail())
|
|
|
|
{
|
|
|
|
return std::errc::no_such_file_or_directory;
|
|
|
|
}
|
2016-09-19 11:50:08 +08:00
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
std::vector<std::string> output;
|
|
|
|
std::string line;
|
|
|
|
while (std::getline(file_stream, line))
|
|
|
|
{
|
|
|
|
output.push_back(line);
|
|
|
|
}
|
|
|
|
file_stream.close();
|
2016-09-22 12:43:59 +08:00
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
return std::move(output);
|
|
|
|
}
|
|
|
|
virtual fs::path find_file_recursively_up(const fs::path & starting_dir, const std::string & filename) const override
|
2016-12-16 10:19:22 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
fs::path current_dir = starting_dir;
|
|
|
|
for (; !current_dir.empty(); current_dir = current_dir.parent_path())
|
|
|
|
{
|
|
|
|
const fs::path candidate = current_dir / filename;
|
2017-04-12 06:16:39 +08:00
|
|
|
if (exists(candidate))
|
2017-04-09 11:19:35 +08:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return current_dir;
|
2016-12-16 10:19:22 +08:00
|
|
|
}
|
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
virtual std::vector<fs::path> recursive_find_all_files_in_dir(const fs::path & dir) const override
|
2016-12-16 10:19:22 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
std::vector<fs::path> ret;
|
2016-12-16 10:19:22 +08:00
|
|
|
|
2017-04-12 06:16:39 +08:00
|
|
|
fs::stdfs::recursive_directory_iterator b(dir), e{};
|
2017-04-09 11:19:35 +08:00
|
|
|
for (; b != e; ++b)
|
|
|
|
{
|
|
|
|
ret.push_back(b->path());
|
|
|
|
}
|
2016-12-16 10:19:22 +08:00
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
virtual std::vector<fs::path> non_recursive_find_all_files_in_dir(const fs::path & dir) const override
|
2016-12-16 10:19:22 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
std::vector<fs::path> ret;
|
|
|
|
|
2017-04-12 06:16:39 +08:00
|
|
|
fs::stdfs::directory_iterator b(dir), e{};
|
2017-04-09 11:19:35 +08:00
|
|
|
for (; b != e; ++b)
|
|
|
|
{
|
|
|
|
ret.push_back(b->path());
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2016-12-16 10:19:22 +08:00
|
|
|
}
|
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
virtual void write_all_lines(const fs::path & file_path, const std::vector<std::string>& lines) override
|
2016-09-22 12:43:59 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
|
|
|
|
for (const std::string& line : lines)
|
2016-09-22 12:43:59 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
output << line << "\n";
|
2016-09-22 12:43:59 +08:00
|
|
|
}
|
2017-04-09 11:19:35 +08:00
|
|
|
output.close();
|
2016-09-22 12:43:59 +08:00
|
|
|
}
|
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
virtual void rename(const fs::path & oldpath, const fs::path & newpath) override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
fs::stdfs::rename(oldpath, newpath);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
2017-04-12 06:16:39 +08:00
|
|
|
virtual bool remove(const fs::path & path) override
|
2017-04-09 11:19:35 +08:00
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::remove(path);
|
|
|
|
}
|
|
|
|
virtual bool remove(const fs::path & path, std::error_code& ec) override
|
|
|
|
{
|
|
|
|
return fs::stdfs::remove(path, ec);
|
|
|
|
}
|
|
|
|
virtual std::uintmax_t remove_all(const fs::path & path, std::error_code& ec) override
|
|
|
|
{
|
|
|
|
return fs::stdfs::remove_all(path, ec);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
virtual bool exists(const fs::path & path) const override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::exists(path);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
virtual bool is_directory(const fs::path & path) const override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::is_directory(path);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
virtual bool is_regular_file(const fs::path & path) const override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::is_regular_file(path);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
virtual bool is_empty(const fs::path & path) const override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::is_empty(path);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
virtual bool create_directory(const fs::path & path, std::error_code & ec) override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::create_directory(path, ec);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
virtual void copy(const fs::path & oldpath, const fs::path & newpath, fs::copy_options opts) override
|
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
fs::stdfs::copy(oldpath, newpath, opts);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
2017-04-12 06:16:39 +08:00
|
|
|
virtual bool copy_file(const fs::path & oldpath, const fs::path & newpath, fs::copy_options opts, std::error_code & ec) override
|
|
|
|
{
|
|
|
|
return fs::stdfs::copy_file(oldpath, newpath, opts, ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override
|
2017-04-09 11:19:35 +08:00
|
|
|
{
|
2017-04-12 06:16:39 +08:00
|
|
|
return fs::stdfs::status(path, ec);
|
2017-04-09 11:19:35 +08:00
|
|
|
}
|
|
|
|
};
|
2016-11-30 10:08:00 +08:00
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
Filesystem & get_real_filesystem()
|
2016-11-30 10:08:00 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
static RealFilesystem real_fs;
|
|
|
|
return real_fs;
|
2016-11-30 10:08:00 +08:00
|
|
|
}
|
|
|
|
|
2017-04-09 11:19:35 +08:00
|
|
|
bool has_invalid_chars_for_filesystem(const std::string& s)
|
2016-11-30 10:08:00 +08:00
|
|
|
{
|
2017-04-09 11:19:35 +08:00
|
|
|
return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX);
|
2016-11-30 10:08:00 +08:00
|
|
|
}
|
2016-12-01 06:08:43 +08:00
|
|
|
|
|
|
|
void print_paths(const std::vector<fs::path>& paths)
|
|
|
|
{
|
|
|
|
System::println("");
|
|
|
|
for (const fs::path& p : paths)
|
|
|
|
{
|
|
|
|
System::println(" %s", p.generic_string());
|
|
|
|
}
|
|
|
|
System::println("");
|
|
|
|
}
|
2017-01-06 04:47:08 +08:00
|
|
|
}
|