zig-toybox/src/cat.zig

62 lines
1.9 KiB
Zig

const std = @import("std");
const mem = std.mem;
const stdout = std.io.getStdOut().writer();
const process = std.process;
const fs = std.fs;
const warn = std.debug.warn;
const print = std.debug.print;
const cli_arguments = @import("./cli_arguments.zig");
pub fn get_file_size(path: []const u8) !u64 {
var file = try fs.cwd().openFile(path, .{});
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();
}