Skip to content

Instantly share code, notes, and snippets.

@AdriDevelopsThings
Last active June 20, 2024 19:23
Show Gist options
  • Save AdriDevelopsThings/eb8248d891e7be3f3444ad64e6601655 to your computer and use it in GitHub Desktop.
Save AdriDevelopsThings/eb8248d891e7be3f3444ad64e6601655 to your computer and use it in GitHub Desktop.
Find a pattern in a file and mark the position
const std = @import("std");
const COLOR_RED = "\x1b[0;31m";
const COLOR_RESET = "\x1b[0m";
fn print_usage(exec: [*:0]u8) void {
std.debug.print("Usage: {s} FILE PATTERN\n", .{exec});
}
fn string_contains_substring(allocator: std.mem.Allocator, string: []u8, substring: []u8) !std.ArrayList([2]usize) {
var list = std.ArrayList([2]usize).init(allocator);
var start: ?usize = null;
var substring_index: usize = 0;
for (string, 0..) |c, i| {
if (c == substring[substring_index]) {
substring_index += 1;
if (substring_index == substring.len) {
try list.append(.{ start orelse i, i });
start = null;
substring_index = 0;
continue;
}
if (start == null) {
start = i;
}
} else if (start != null) {
start = null;
substring_index = 0;
}
}
return list;
}
pub fn main() !void {
if (std.os.argv.len != 3) {
print_usage(std.os.argv[0]);
std.process.exit(1);
unreachable;
}
const stdout = std.io.getStdOut().writer();
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
defer {
const status = gpa.deinit();
if (status == .leak) @panic("there are leaks");
}
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
const file = try std.fs.cwd().openFile(args[1], .{});
defer file.close();
const reader = file.reader();
while (true) {
const line = reader.readUntilDelimiterAlloc(allocator, '\n', 1024 * 1024) catch break;
defer allocator.free(line);
const contains = try string_contains_substring(allocator, line, args[2]);
defer contains.deinit();
if (contains.items.len == 0) {
try stdout.print(" {s}\n", .{line});
} else {
try stdout.print("> ", .{});
var previous: usize = 0;
for (contains.items) |element| {
try stdout.print("{s}{s}{s}{s}", .{ line[previous..element[0]], COLOR_RED, line[element[0] .. element[1] + 1], COLOR_RESET });
previous = element[1] + 1;
}
try stdout.print("{s}\n", .{line[previous..]});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment