Skip to content

Instantly share code, notes, and snippets.

@Ryan-rsm-McKenzie
Created December 20, 2020 09:37
Show Gist options
  • Save Ryan-rsm-McKenzie/7734ea10e35583b3d072dd55418960b4 to your computer and use it in GitHub Desktop.
Save Ryan-rsm-McKenzie/7734ea10e35583b3d072dd55418960b4 to your computer and use it in GitHub Desktop.
commonlibsse move files
#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <span>
#include <string>
#include <utility>
#include <vector>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/regex.hpp>
#include <robin_hood.h>
using namespace std::literals;
void cmd_invoke(const char* a_cmd)
{
if (std::system(a_cmd) != EXIT_SUCCESS) {
std::cout << "failed to invoke:\n"
<< '\t' << a_cmd << '\n';
assert(false);
std::exit(EXIT_FAILURE);
}
}
int main()
{
constexpr std::array extensions = {
".h"sv,
".hpp"sv,
".hxx"sv,
".c"sv,
".cpp"sv,
".cxx"sv,
};
const std::filesystem::path clib = getenv("CommonLibSSEPath");
if (clib.empty()) {
std::cout << "could not get CommonLibSSE path from environment\n";
assert(false);
return EXIT_FAILURE;
}
std::filesystem::current_path(clib);
const auto headers = clib / "include"sv;
const auto mappings = [&]() {
robin_hood::unordered_flat_map<std::string, std::string> results; // old -> new
for (const auto& entry : std::filesystem::recursive_directory_iterator(headers / "RE"sv)) {
const auto& path = entry.path();
if (const auto ext = path.extension().string();
std::ranges::find(extensions, ext) != extensions.end()) {
const auto oldp = std::filesystem::relative(path, headers);
const auto newp = [&]() {
const auto filename = oldp.filename();
auto sfilename = filename.generic_string();
sfilename[0] = static_cast<char>(std::toupper(sfilename[0]));
sfilename.resize(1);
std::filesystem::path result = "RE"sv;
result /= sfilename;
result /= filename;
return result;
}();
results.emplace(
oldp.generic_string(),
newp.generic_string());
}
}
return results;
}();
std::ranges::for_each(mappings, [&](const auto& a_mapping) {
const auto& [oldp, newp] = a_mapping;
const auto mkdir = headers / newp;
std::filesystem::create_directories(mkdir.parent_path());
const auto cmd = "git mv \"include/"s + oldp + "\" \"include/"s + newp + "\""s;
cmd_invoke(cmd.c_str());
});
cmd_invoke("git commit -a -m \"restructure files\"");
const boost::regex pattern("#include \"(RE/.*)\"\r\n", boost::regex_constants::ECMAScript | boost::regex_constants::optimize);
std::ranges::for_each(mappings, [&](const auto& a_mapping) {
const auto path = headers / a_mapping.second;
const auto spath = path.string();
boost::iostreams::mapped_file_source file(spath);
assert(file.is_open());
const std::span<const char> data{ file.data(), file.size() };
if (!data.empty() && boost::regex_search(data.begin(), data.end(), pattern)) {
std::vector<std::string_view> lines;
auto it = data.begin();
do {
const auto prev = it;
while (++it != data.end() && *it != '\n') {}
lines.emplace_back(prev, it != data.end() ? ++it : it);
} while (it != data.end());
const auto tmp = spath + ".tmp";
std::ofstream out(tmp, std::ios::out | std::ios::binary);
std::ranges::for_each(lines, [&](const auto& a_line) {
boost::match_results<typename std::string_view::const_iterator> matches;
if (boost::regex_match(a_line.begin(), a_line.end(), matches, pattern)) {
assert(matches.length() > 1);
const auto remap = mappings.find(matches[1].str());
if (remap != mappings.end()) {
out << "#include \""sv << remap->second << "\"\r\n"sv;
return;
}
}
out << a_line;
});
file.close();
out.close();
std::filesystem::rename(tmp, spath);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment