Add token counting

This commit is contained in:
Paul Campbell 2021-12-30 21:18:21 +00:00
parent 3ae79d3dfe
commit 1f1e14967e

View file

@ -27,6 +27,7 @@ pub fn main() anyerror!void {
const config: Config = parseArgs(allocator) catch |err| switch (err) { const config: Config = parseArgs(allocator) catch |err| switch (err) {
error.EarlyExit => return, error.EarlyExit => return,
error.FileNotFound => return, error.FileNotFound => return,
error.BadArgs => return,
else => @panic("Unknown error"), else => @panic("Unknown error"),
}; };
defer config.deinit(); defer config.deinit();
@ -42,13 +43,15 @@ pub fn main() anyerror!void {
const errors = error { const errors = error {
EarlyExit, EarlyExit,
FileNotFound FileNotFound,
BadArgs,
}; };
const Config = struct { const Config = struct {
lines: u32, lines: u32,
file: ?fs.File, file: ?fs.File,
line: ?[]const u8 = null, line: ?[]const u8 = null,
token: ?[]const u8 = null,
pub fn deinit(self: @This()) void { pub fn deinit(self: @This()) void {
if (self.file) |f| { if (self.file) |f| {
@ -62,6 +65,7 @@ fn parseArgs(allocator: mem.Allocator) !Config {
clap.parseParam("<N> The number of lines to skip") catch unreachable, clap.parseParam("<N> The number of lines to skip") catch unreachable,
clap.parseParam("[<FILE>] The file to read or stdin if not given") catch unreachable, clap.parseParam("[<FILE>] The file to read or stdin if not given") catch unreachable,
clap.parseParam("-l, --line <STR> Skip until N lines matching this") catch unreachable, clap.parseParam("-l, --line <STR> Skip until N lines matching this") catch unreachable,
clap.parseParam("-t, --token <STR> Skip lines until N tokens found") catch unreachable,
clap.parseParam("-h, --help Display this help and exit") catch unreachable, clap.parseParam("-h, --help Display this help and exit") catch unreachable,
clap.parseParam("-v, --version Display the version") catch unreachable, clap.parseParam("-v, --version Display the version") catch unreachable,
}; };
@ -81,11 +85,25 @@ fn parseArgs(allocator: mem.Allocator) !Config {
try clap.help(io.getStdErr().writer(), &params); try clap.help(io.getStdErr().writer(), &params);
return error.EarlyExit; return error.EarlyExit;
} }
if (args.option("--line")) |_| {
if (args.option("--token")) |_| {
try io.getStdErr().writer().print("Error: only specify one of --line or --token, not both\n", .{});
return error.BadArgs;
}
}
var line: ?[]const u8 = null; var line: ?[]const u8 = null;
if (args.option("--line")) |match| { if (args.option("--line")) |match| {
line = try allocator.dupe(u8, match); line = try allocator.dupe(u8, match);
} }
var token: ?[]const u8 = null;
if (args.option("--token")) |match| {
token = try allocator.dupe(u8, match);
}
var n: u32 = 0; var n: u32 = 0;
var file: ?fs.File = null; var file: ?fs.File = null;
if (args.positionals().len == 0) { if (args.positionals().len == 0) {
@ -109,6 +127,7 @@ fn parseArgs(allocator: mem.Allocator) !Config {
.lines = n, .lines = n,
.file = file, .file = file,
.line = line, .line = line,
.token = token,
}; };
} }
@ -116,7 +135,7 @@ fn dumpInput(config: Config, in: fs.File, out: fs.File, allocator: mem.Allocator
const writer = out.writer(); const writer = out.writer();
const reader = in.reader(); const reader = in.reader();
var it: LineIterator = lineIterator(reader, allocator); var it: LineIterator = lineIterator(reader, allocator);
var c: u32 = 0; var c: usize = 0;
while (c < config.lines) { while (c < config.lines) {
const line = it.next(); const line = it.next();
if (config.line) |match| { if (config.line) |match| {
@ -125,9 +144,15 @@ fn dumpInput(config: Config, in: fs.File, out: fs.File, allocator: mem.Allocator
c += 1; c += 1;
} }
} }
} else {
if (config.token) |token| {
if (line) |memory| {
c += mem.count(u8, memory, token);
}
} else { } else {
c += 1; c += 1;
} }
}
if (line) |memory| { if (line) |memory| {
allocator.free(memory); allocator.free(memory);
} else return; } else return;