Last active
June 20, 2024 19:23
-
-
Save AdriDevelopsThings/eb8248d891e7be3f3444ad64e6601655 to your computer and use it in GitHub Desktop.
Find a pattern in a file and mark the position
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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