cat: working cat code.
parent
d780a5d1e7
commit
5c97005205
86
src/cat.zig
86
src/cat.zig
|
@ -1,61 +1,41 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const lib = @import("./lib.zig");
|
||||||
const stdout = std.io.getStdOut().writer();
|
|
||||||
const process = std.process;
|
|
||||||
|
|
||||||
const fs = std.fs;
|
pub fn main() anyerror!void {
|
||||||
|
const args = try std.process.argsAlloc(std.heap.page_allocator);
|
||||||
|
|
||||||
const warn = std.debug.warn;
|
if (args.len <= 1) {
|
||||||
const print = std.debug.print;
|
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 {
|
fn print_input() !void {
|
||||||
var file = try fs.cwd().openFile(path, .{});
|
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();
|
defer file.close();
|
||||||
|
|
||||||
// Find the size of the file and create a buffer with this size.
|
// read file content and print everything
|
||||||
var file_stat = try file.stat();
|
var buffer: [4096]u8 = undefined;
|
||||||
return file_stat.size;
|
var nbytes : u64 = 0;
|
||||||
}
|
while (true) {
|
||||||
|
nbytes = try file.read(&buffer);
|
||||||
fn print_file(path: []const u8) !void {
|
lib.print("{s}", .{buffer[0..nbytes]});
|
||||||
const size = try get_file_size(path);
|
if (nbytes == 0) break;
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue