11 base_path = base_path_;
12 similarity = similarity_;
15 std::cerr <<
"SIMILARITY SHOULD BE GREATER OR EQUAL 0 TO USE DUPLICATION FINDER BY DIFF COMMAND";
19std::vector<std::string> DiffMethod::find_files(
const fs::path& folder_path) {
20 std::vector<std::string> file_paths;
21 for (
const auto& dirEntry : std::filesystem::recursive_directory_iterator(folder_path)) {
22 fs::path file_path = dirEntry.path();
23 if (std::filesystem::exists(file_path) && std::filesystem::is_regular_file(file_path)) {
24 file_paths.push_back(file_path.string());
30bool DiffMethod::is_empty_line(std::string line) {
31 size_t line_size = line.size();
33 for (
size_t i = 1; i < line_size; i++) {
39std::vector<std::string> DiffMethod::remove_blank_lines(std::vector<std::string> content) {
40 std::vector<std::string> ret;
41 for (
auto line : content) {
42 if (!is_empty_line(line)) {
49bool DiffMethod::is_equal_files(std::vector<std::string> content1, std::vector<std::string> content2) {
50 if (content1.size() != content2.size()) {
53 size_t sz = content1.size();
54 for (
size_t i = 0; i < sz; i++) {
55 if (content1[i] != content2[i]) {
62double DiffMethod::find_similarity(std::string path1, std::string path2) {
66 content1 = remove_blank_lines(content1);
67 content2 = remove_blank_lines(content2);
69 if (is_equal_files(content1, content2)) {
74 fs::path output_file = base_path /
"diff.txt";
78 std::string command =
"diff " + path1 +
" " + path2 +
" -c > " + output_file.string() +
" 2>&1";
79 system(command.c_str());
83 size_t number_lines = content.size();
85 int different_lines = 0;
87 for (
size_t i = 4; i < number_lines; i++) {
88 auto& line = content[i];
89 if (is_empty_line(line)) {
92 if (line[0] ==
'!' || line[0] ==
'-' || line[0] ==
'+') {
97 int equal_lines = (int)content1.size() + (int)content2.size();
98 equal_lines -= different_lines;
100 if (different_lines + equal_lines == 0) {
104 double db_equal_lines = equal_lines;
105 double db_different_lines = different_lines;
106 double similarity_metric = db_equal_lines / (db_different_lines + db_equal_lines);
107 similarity_metric *= 100;
108 return similarity_metric;
111std::vector<DuplicationEntry> DiffMethod::find_similar_pairs(std::vector<std::string>& file_paths) {
112 size_t number_files = file_paths.size();
113 std::vector<DuplicationEntry> ret;
114 for (
size_t i = 0; i < number_files; i++) {
115 for (
size_t j = 0; j < number_files; j++)
117 std::string file_path1 = file_paths[i];
118 std::string file_path2 = file_paths[j];
119 double similarity_metric = find_similarity(file_path1, file_path2);
120 if (similarity_metric >= similarity) {
121 ret.push_back({similarity_metric, file_path1, file_path2});
125 sort(ret.rbegin(), ret.rend());
129void DiffMethod::save_duplications(std::vector<DuplicationEntry>& file_duplication_pairs) {
132 auto fout = std::ofstream(output_file_path.string());
134 fout << file_duplication_pairs.size() <<
'\n';
135 for (
const auto& [similarity, path1, path2] : file_duplication_pairs) {
136 fout << path1 <<
' ' << path2 <<
' ';
137 fout << std::fixed << std::setprecision(2) << similarity <<
'\n';
150 fs::path relative(fd.
path);
151 std::string filename = fd.
function_name + relative.extension().string();
152 fs::path path = base / relative / filename;
159 std::vector<std::string> file_paths = find_files(base);
161 std::vector<DuplicationEntry> file_duplication_pairs = find_similar_pairs(file_paths);
163 for (
auto& [sim, path1, path2] : file_duplication_pairs) {
164 path1 = fs::relative(path1, base).string();
165 path2 = fs::relative(path2, base).string();
170 save_duplications(file_duplication_pairs);
void on_function(const FunctionData &fd) override
void execute() override
Executes the preprocessing pipeline.
DiffMethod(const fs::path &base_path_, double similarity_)
Constructs preprocessor with configuration.
std::string function_name
Name of the function.
std::shared_ptr< T > get_feature() const
fs::path build_similarity_path() const
Builds similarity file path.
Configuration management interface.
Code duplication preprocessing system.
Provides access to function storage locations.
void write_file(const fs::path &path, const std::string &content)
Writes content to a file at specified path.
std::vector< std::string > read_file_with_vector(const fs::path &path)
Reads a file line by line into a vector of strings.
bool is_empty_char(char c)
Checks if a character is considered empty/whitespace.
fs::path source_feature_path
Defines utility functions used across all files.