reman3/tooling/cmd_scan.cpp

110 lines
3.3 KiB
C++

#include "tool.hpp"
#include <CLI11.hpp>
static std::vector<std::string> files;
static std::string list_file;
static std::string type_str;
FileType file_type; // Add type string variable
std::vector<std::string> getFilesToProcess() {
std::vector<std::string> files_to_process;
if (!list_file.empty()) {
auto list_files = readFileList(list_file);
files_to_process.insert(files_to_process.end(), list_files.begin(),
list_files.end());
}
for (const auto &input : files) {
if (input.starts_with("@")) {
auto list_files = readFileList(input.substr(1));
files_to_process.insert(files_to_process.end(), list_files.begin(),
list_files.end());
} else if (std::filesystem::exists(input)) {
files_to_process.push_back(input);
} else {
spdlog::warn("File not found: {}", input);
}
}
return files_to_process;
}
static void setupCommand(CLI::App &app, std::string mode) {
auto cmd = app.add_subcommand(mode, "Scan for functions and globals");
cmd->add_option("files", files,
"Input C++ files to parse (supports @listfile.txt syntax)");
cmd->add_option("-l,--list", list_file,
"File containing list of files to process");
cmd->add_option("-t,--type", type_str,
"File type: 'auto', 'fix', 'stub', or 'ref'")
->default_val("auto")
->check(CLI::IsMember({"auto", "fix", "stub", "ref"}));
cmd->final_callback([mode]() {
if (files.empty() && list_file.empty()) {
spdlog::error("No files to process. Use --help for usage information.");
exit(1);
}
// Convert string to FileType enum
try {
file_type = stringToFileType(type_str);
} catch (const std::invalid_argument &e) {
spdlog::error("Invalid file type: {}", type_str);
exit(1);
}
auto files_to_process = getFilesToProcess();
if (files_to_process.empty()) {
spdlog::error("No files to process. Use --help for usage information.");
exit(1);
}
auto &options = Options::get();
DatabaseManager db(options.db_path);
const size_t batch_size = 50;
size_t current_batch = 0;
int processed_count = 0;
db.beginTransaction();
for (const auto &filepath : files_to_process) {
spdlog::info("=== Processing: {} (type: {}) ===", filepath, type_str);
bool success = false;
if (mode == "functions") {
success = processFile(filepath, db, file_type);
} else if (mode == "globals") {
success = processGlobalsFile(filepath, db);
}
if (success)
processed_count++;
if (++current_batch >= batch_size) {
db.commitTransaction();
spdlog::info("Committed batch of {} files to database", current_batch);
db.beginTransaction();
current_batch = 0;
}
}
if (current_batch > 0) {
db.commitTransaction();
spdlog::info("Committed final batch of {} files to database",
current_batch);
}
spdlog::info("=== Summary ===");
spdlog::info("Processed {} files successfully", processed_count);
spdlog::info("Mode: {}", mode);
spdlog::info("File type: {}", type_str);
spdlog::info("Database saved to: {}", options.db_path);
});
}
void register_cmd_scan(CLI::App &app) {
setupCommand(app, "functions");
setupCommand(app, "globals");
}