// Tool to get average line length, by file extension
const std = @import("std");
const assert = std.debug.assert;
const mem = std.mem;
pub fn main() !void {
var gpaa = std.heap.GeneralPurposeAllocator(.{}){};
const gpa = gpaa.allocator();
const stdout_file = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_file);
const stdout = bw.writer();
defer {
bw.flush() catch |err| switch (err) {
else => {},
};
}
var i: i64 = 0;
i += 1;
var args_it = std.process.args();
_ = args_it.next();
var filesByExtension = std.StringHashMap([2]u64).init(gpa);
defer filesByExtension.deinit();
while (args_it.next()) |fileName| {
const cl = countFile(fileName) catch |err| {
try stdout.print("could not get file {s}: {any}\n", .{ fileName, err });
try bw.flush();
std.process.exit(1);
};
const ext = getFileExt(fileName);
const entry = filesByExtension.get(ext);
if (entry) |val| {
const chars = cl[0] + val[0];
const lines = @max(1, cl[1]) + val[1];
try filesByExtension.put(ext, [2]u64{ chars, lines });
} else {
try filesByExtension.put(ext, [2]u64{ cl[0], @max(1, cl[1]) });
}
}
var results_it = filesByExtension.iterator();
while (results_it.next()) |k| {
const avg: f64 = @as(f64, @floatFromInt(k.value_ptr.*[0])) / @as(f64, @floatFromInt(k.value_ptr.*[1]));
try stdout.print("{s}: {d:.1} ({d} LOC)\n", .{ k.key_ptr.*, avg, k.value_ptr.*[1] });
}
}
fn getFileExt(path: []const u8) []const u8 {
var i = path.len - 1;
while (i >= 0) {
if (path[i] == '.') {
return path[i..path.len];
}
if (i == 0) {
break;
}
i -= 1;
}
if (i == 0) {
return "NO_EXT";
}
return path[i .. path.len - 1];
}
fn countFile(path: []const u8) ![2]u64 {
const file = try std.fs.cwd().openFile(path, .{});
defer file.close();
var fileIter = file.reader();
var c: u64 = 0;
var l: u64 = 0;
while (fileIter.readByte()) |char| {
if (char == '\r') {
continue;
}
if (char == '\n') {
l += 1;
} else {
c += 1;
}
} else |_| {}
return [2]u64{ c, l };
}