diff --git a/main.zig b/main.zig index b3e725c..5582e65 100644 --- a/main.zig +++ b/main.zig @@ -1,31 +1,18 @@ -// using zig-0.15.2 +//! using zig-0.15.2 +//! zig build-exe main.zig -fsingle-threaded -OReleaseFast +//! ReleaseFast is recomended but do whatever you want +//! usage: main dirname1 dirname2 ... +//! found duplicates in stdout +//! report in stderr +//! if it doesn't work fuck you const std = @import("std"); -const stdout = std.fs.File.stdout(); -const stderr = std.fs.File.stderr(); - -fn err_print(comptime fmt: []const u8, args: anytype) void { - var buf: [1024 * 16]u8 = undefined; - var writer = stderr.writer(&buf); - writer.interface.print(fmt, args) catch unreachable; - writer.interface.flush() catch unreachable; -} - -fn out_print(comptime fmt: []const u8, args: anytype) void { - var buf: [1024 * 16]u8 = undefined; - var writer = stdout.writer(&buf); - writer.interface.print(fmt, args) catch unreachable; - writer.interface.flush() catch unreachable; -} const File = struct { path: []u8, size: u64, solved: bool = false, - hash: ?u256 = null, }; -var hashcount: usize = 0; - fn cmp_file(path1: []const u8, path2: []const u8) !bool { var buf1: [1024 * 16]u8 = undefined; var buf2: [1024 * 16]u8 = undefined; @@ -50,16 +37,24 @@ fn cmp_file(path1: []const u8, path2: []const u8) !bool { } pub fn main() !void { + var stdout_buf: [1024 * 16]u8 = undefined; + var stdout_writer = std.fs.File.stdout().writer(&stdout_buf); + const stdout = &stdout_writer.interface; + var stderr_buf: [1024 * 16]u8 = undefined; + var stderr_writer = std.fs.File.stderr().writer(&stderr_buf); + const stderr = &stderr_writer.interface; + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); defer _ = gpa.deinit(); - var list: std.ArrayList(File) = .empty; - defer list.deinit(allocator); + var files_list: std.ArrayList(File) = .empty; + defer files_list.deinit(allocator); var args_it = std.process.args(); _ = args_it.next(); // skip program name var file_count: usize = 0; + var dup_count: usize = 0; const start_time = try std.time.Instant.now(); while (args_it.next()) |arg| { @@ -69,24 +64,21 @@ pub fn main() !void { while (try walker.next()) |entry| { if (entry.kind == .file) { file_count += 1; - const stat = try entry.dir.statFile(entry.basename); - const path = try entry.dir.realpathAlloc(allocator, entry.basename); - try list.append(allocator, .{ - .path = path, - .size = stat.size, + try files_list.append(allocator, .{ + .path = try entry.dir.realpathAlloc(allocator, entry.basename), + .size = (try entry.dir.statFile(entry.basename)).size, }); } } } - for (list.items, 0..) |*item, idx| { + for (files_list.items, 0..) |*item, idx| { if (item.solved) continue; var duplicates: std.ArrayList(usize) = .empty; defer duplicates.deinit(allocator); - for (list.items, 0..) |*item2, idx2| { + for (files_list.items, 0..) |*item2, idx2| { if (item2.solved) continue; if (std.mem.eql(u8, item.path, item2.path)) continue; - if (item.size == item2.size) { if (try cmp_file(item.path, item2.path)) { if (duplicates.items.len == 0) { @@ -94,6 +86,7 @@ pub fn main() !void { item.solved = true; } try duplicates.append(allocator, idx2); + dup_count += 1; item2.solved = true; } } @@ -101,22 +94,20 @@ pub fn main() !void { if (duplicates.items.len > 0) { for (duplicates.items, 0..) |dup_idx, i| { if (i == 0) { - out_print("duplicate ({}): \n {s}\n", .{ duplicates.items.len, list.items[duplicates.items[0]].path }); + try stdout.print("duplicate ({}): \n {s}\n", .{ duplicates.items.len, files_list.items[duplicates.items[0]].path }); } else if (i == duplicates.items.len - 1) { - out_print(" {s}\n", .{list.items[dup_idx].path}); + try stdout.print(" {s}\n", .{files_list.items[dup_idx].path}); } else { - out_print(" {s}\n", .{list.items[dup_idx].path}); + try stdout.print(" {s}\n", .{files_list.items[dup_idx].path}); } + try stdout.flush(); } } } - for (list.items) |*item| { - allocator.free(item.path); - } + for (files_list.items) |*item| allocator.free(item.path); - const end_time = try std.time.Instant.now(); - const elapsed_nanos = end_time.since(start_time); - const elapsed_seconds = @as(f64, @floatFromInt(elapsed_nanos)) / std.time.ns_per_s; - err_print("found {} files in {:.2}s and hashcount is {}\n", .{ file_count, elapsed_seconds, hashcount }); + const elapsed_seconds = @as(f64, @floatFromInt((try std.time.Instant.now()).since(start_time))) / std.time.ns_per_s; + try stderr.print("found {} duplicates in {} files in {:.2}s\n", .{ dup_count, file_count, elapsed_seconds }); + try stderr.flush(); }