Commit f44c66cf authored by Pádraig Ó Conbhuí's avatar Pádraig Ó Conbhuí
Browse files

megadep.main: Add initial working serial version

parent 15a8e46f
......@@ -2,6 +2,7 @@
Checks: '*,
-llvm-header-guard,
-fuchsia-default-arguments,
-fuchsia-trailing-return,
-cppcoreguidelines-pro-bounds-constant-array-index,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-hicpp-no-array-decay'
......
......@@ -2,6 +2,7 @@
#include <algorithm>
#include <array>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
......@@ -70,26 +71,29 @@ int main(int argc, char *argv[]) {
// Sort the files so we can refer to them by index, and look them up
// quickly by index.
// Also, erase any duplicates using a unique / erase.
std::sort(file_names.begin(), file_names.end());
file_names.erase(std::unique(file_names.begin(), file_names.end()),
file_names.end());
//
// Forward direct include map
//
// Map from a file index to the file indices it #includes.
std::vector<std::vector<uint64_t>> file_to_includes(file_names.size());
for (size_t i = 0; i < file_names.size(); i++) {
const auto &file_name = file_names[i];
for (size_t file_index = 0; file_index < file_names.size(); file_index++) {
const auto &file_name = file_names[file_index];
const auto include_strings = megadep::read_includes(file_name);
std::cout << '\n';
std::cout << "file: " << file_name << '\n';
for (const auto &include : include_strings) {
auto resolved_include =
megadep::resolve_include(include, file_name, include_directories);
// If the resolved include is in the form <filename>, we assume it's
// an external depenency.
// If the resolved include is in the form <filename>, it's not in
// the includes, so it's an external depenency.
if (resolved_include.front() == '<' && resolved_include.back() == '>') {
std::cout << " - include:\n";
std::cout << " external: " << resolved_include << '\n';
continue;
}
......@@ -99,20 +103,95 @@ int main(int argc, char *argv[]) {
if (*file_name_ptr == resolved_include) {
// If we found the exact value in file_names, add it to the includes
auto file_name_index = std::distance(file_names.begin(), file_name_ptr);
auto included_file_index =
std::distance(file_names.begin(), file_name_ptr);
std::cout << " - include:\n";
std::cout << " raw: " << include << '\n';
std::cout << " resolved: " << resolved_include << '\n';
std::cout << " index: " << file_name_index << '\n';
file_to_includes[file_index].emplace_back(included_file_index);
file_to_includes[i].emplace_back(file_name_index);
} else {
// If we haven't found the exact value in file_names, we assume we're
// not tracking this dependency.
std::cout << " - include:\n";
std::cout << " unresolved: " << include << '\n';
// If we haven't found the exact value in file_names, it's in our
// includes, but it's not in the tracked list.
std::cerr << "Error: unresolved include!\n";
std::cerr << " Include: " << include << '\n';
std::cerr << " Attempt: " << resolved_include << '\n';
std::cerr << " Source : " << file_name << '\n';
std::exit(EXIT_FAILURE);
}
}
}
try {
std::ofstream direct_includes_file("direct-includes.yml",
std::ofstream::out);
for (size_t file_index = 0; file_index < file_to_includes.size();
file_index++) {
if (file_index != 0) {
direct_includes_file << '\n';
}
direct_includes_file << file_names[file_index] << ":\n";
for (const auto &include : file_to_includes[file_index]) {
direct_includes_file << " - " << file_names[include] << '\n';
}
}
direct_includes_file.close();
} catch (...) {
}
//
// Inverse direct include map
//
// Invert the map
std::vector<std::vector<uint64_t>> file_to_includers(file_to_includes.size());
for (size_t includer = 0; includer < file_to_includes.size(); includer++) {
for (const auto &included : file_to_includes[includer]) {
file_to_includers[included].push_back(includer);
}
}
//
// Forward recursive include map
//
std::vector<std::vector<uint64_t>> file_to_indirect_includes(
file_to_includers.size());
for (size_t file_index = 0; file_index < file_to_includers.size();
file_index++) {
std::vector<bool> processed(file_to_includers.size(), false);
// For `includer`, add `file_index` as an indirect dependency of
// every file it includes. The recurse on each of those files.
const auto recursive_add_to_includers = [&](auto recursive_add_to_includers,
auto includer) -> void {
for (const auto &sub_includer : file_to_includers[includer]) {
if (processed[sub_includer]) {
continue;
}
processed[sub_includer] = true;
file_to_indirect_includes[sub_includer].push_back(file_index);
recursive_add_to_includers(recursive_add_to_includers, sub_includer);
}
};
recursive_add_to_includers(recursive_add_to_includers, file_index);
}
try {
std::ofstream indirect_includes_file("indirect-includes.yml",
std::ofstream::out);
for (size_t file_index = 0; file_index < file_to_includes.size();
file_index++) {
if (file_index != 0) {
indirect_includes_file << '\n';
}
indirect_includes_file << file_names[file_index] << ":\n";
for (const auto &include : file_to_indirect_includes[file_index]) {
indirect_includes_file << " - " << file_names[include] << '\n';
}
}
indirect_includes_file.close();
} catch (...) {
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment