diff --git a/src/cat.zig b/src/cat.zig index 0c4bbff..4c215ca 100644 --- a/src/cat.zig +++ b/src/cat.zig @@ -1,61 +1,41 @@ -const std = @import("std"); -const mem = std.mem; -const stdout = std.io.getStdOut().writer(); -const process = std.process; +const std = @import("std"); +const lib = @import("./lib.zig"); -const fs = std.fs; +pub fn main() anyerror!void { + const args = try std.process.argsAlloc(std.heap.page_allocator); -const warn = std.debug.warn; -const print = std.debug.print; + if (args.len <= 1) { + try print_input(); + } -const cli_arguments = @import("./cli_arguments.zig"); + const files = args[1..]; + for (files) |f| { + if (std.mem.eql(u8, f, "-")) { try print_input(); } + else { try print_file (f); } + } +} -pub fn get_file_size(path: []const u8) !u64 { - var file = try fs.cwd().openFile(path, .{}); +fn print_input() !void { + const stdin = std.io.getStdIn().reader(); + var buffer: [4096]u8 = undefined; + while (true) { + const nbytes = try stdin.read(&buffer); + lib.print("{s}", .{buffer[0..nbytes]}); + if (nbytes == 0) break; + } +} + +fn print_file(dest: []const u8) !void { + // open file and defer closing + var file = try std.fs.cwd().openFile(dest, .{ .mode = .read_only }); defer file.close(); - // Find the size of the file and create a buffer with this size. - var file_stat = try file.stat(); - return file_stat.size; -} - -fn print_file(path: []const u8) !void { - const size = try get_file_size(path); - // print("path: {}, size: {}\n", .{path, size}); - - // Create another allocator, for the file. - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - - const allocator = &arena.allocator; - const buffer = try allocator.alloc(u8, size + 1); // Last value will be a null-byte. - buffer[size] = 0; - - const content = try fs.cwd().readFile(path, buffer); - print("{}", .{content}); -} - -pub fn cat() !void { - // Here we use an ArenaAllocator backed by a DirectAllocator because `cat` is a short-lived, - // one shot program. We don't need to waste time freeing memory and finding places to squish - // bytes into. So we free everything all at once at the very end. - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - - const allocator = &arena.allocator; - var args = try process.argsAlloc(allocator); - defer process.argsFree(allocator, args); - - // Skipping the executable binary name. - var arg_idx: usize = 1; - const gui_file_path = cli_arguments.nextArg(args, &arg_idx) orelse { - warn("Expected first argument to be path to gui file\n", .{}); - return error.InvalidArgs; - }; - - try print_file(gui_file_path); -} - -pub fn main() !void { - try cat(); + // read file content and print everything + var buffer: [4096]u8 = undefined; + var nbytes : u64 = 0; + while (true) { + nbytes = try file.read(&buffer); + lib.print("{s}", .{buffer[0..nbytes]}); + if (nbytes == 0) break; + } }