#include "tool.hpp" #include static std::vector files; static std::string list_file; static std::string type_str; FileType file_type; // Add type string variable std::vector getFilesToProcess() { std::vector 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"); }