Skip to content

Commit

Permalink
Hogmaker: Only rebuild the hog file if any input file changed
Browse files Browse the repository at this point in the history
  • Loading branch information
sebholt committed Oct 20, 2024
1 parent 652e31f commit 233b05f
Showing 1 changed file with 38 additions and 19 deletions.
57 changes: 38 additions & 19 deletions tools/HogMaker/HogMaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,22 @@
#include "d3_version.h"
#include "HogFormat.h"

// TODO: To our descendants from the future: remove it when code will support C++20
template <typename TP> std::time_t to_time_t(TP tp) {
auto sctp = std::chrono::duration_cast<std::chrono::system_clock::duration>(tp - TP::clock::now()) +
std::chrono::system_clock::now();
return std::chrono::system_clock::to_time_t(sctp);
}

// Find requested file in search paths
std::filesystem::path resolve_path(const std::vector<std::filesystem::path> &search_path,
const std::filesystem::path &file) {
for (const auto &i : search_path) {
if (is_regular_file((i / file))) {
return (i / file);
std::filesystem::path testfile = (i / file);
if (is_regular_file(testfile)) {
return testfile;
}
}
// Return empty path
return std::filesystem::path{};
}

int main(int argc, char *argv[]) {
std::vector<std::filesystem::path> input_files;

// Print usage information on demand
if (argc < 3) {
std::cout << "HogMaker v" << D3_MAJORVER << "." << D3_MINORVER << "." << D3_BUILD << "-g" << D3_GIT_HASH << "\n"
<< "Usage:\n"
Expand All @@ -55,8 +49,26 @@ int main(int argc, char *argv[]) {
return 1;
}

// Filenames
std::filesystem::path hogmaker_filename{argv[0]};
std::filesystem::path hog_filename{argv[1]};
std::filesystem::path input_filename{argv[2]};

// Check if the input file is usable
if (!is_regular_file(input_filename)) {
std::cout << input_filename << " is not a regular file!" << std::endl;
return 1;
}

// Timestamps
auto hog_timestamp = std::filesystem::file_time_type::min();
if (std::filesystem::is_regular_file(hog_filename)) {
hog_timestamp = std::filesystem::last_write_time(hog_filename);
}
auto newer_than_hog = [&hog_timestamp](const std::filesystem::path &file) {
return (std::filesystem::last_write_time(file) >= hog_timestamp);
};

// Default search path
std::vector<std::filesystem::path> search_paths{input_filename.parent_path()};
// Additional search paths
Expand All @@ -66,12 +78,9 @@ int main(int argc, char *argv[]) {
}
}

if (!is_regular_file(input_filename)) {
std::cout << input_filename << " is not a regular file!" << std::endl;
return 1;
}

D3::HogFormat hog_table;
// Check if the hogmaker or the input file is newer than the hog file
bool file_changed = (newer_than_hog(hogmaker_filename) || newer_than_hog(input_filename));

try {
create_directories(absolute(hog_filename).parent_path());
Expand All @@ -80,28 +89,38 @@ int main(int argc, char *argv[]) {
auto resolved_file = resolve_path(search_paths, line);
if (resolved_file.empty()) {
std::cout << "Warning! File " << line << " from " << input_filename << " not found! Skipping..." << std::endl;
file_changed = true;
} else if (line.size() > 36) {
std::cout << "Warning! Length of name of file " << line << " is more than 36 symbols! Skipping..." << std::endl;
} else {
hog_table.AddEntry(D3::HogFileEntry(resolved_file));
// Check if this file is newer than the hog file
if (newer_than_hog(resolved_file)) {
file_changed = true;
}
}
}

} catch (std::exception &e) {
std::cout << "Exception: " << e.what() << std::endl;
return 1;
}

// Don't do anything if there are no changed files
if (!file_changed) {
std::cout << "Already up to date" << std::endl;
return 0;
}

hog_table.SortEntries();

std::cout << "Creating " << absolute(hog_filename) << "..." << std::endl;
std::fstream ofs(hog_filename, std::ios_base::out | std::ios_base::binary);
std::ofstream ofs(hog_filename, std::ios_base::out | std::ios_base::binary);

ofs << hog_table;
for (const auto& i : hog_table.GetEntries()) {
for (const auto &i : hog_table.GetEntries()) {
std::cout << "Adding " << i.GetName() << "... ";
try {
std::fstream ifs(i.GetRealPath(), std::ios_base::in | std::ios_base::binary);
std::ifstream ifs(i.GetRealPath(), std::ios_base::in | std::ios_base::binary);
std::copy((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>(),
std::ostreambuf_iterator<char>(ofs));
} catch (std::exception &e) {
Expand Down

0 comments on commit 233b05f

Please sign in to comment.