zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

blob 65cd2b1e (1905B) - Raw


      1 const std = @import("std");
      2 const io = std.io;
      3 const process = std.process;
      4 const fs = std.fs;
      5 const mem = std.mem;
      6 const warn = std.log.warn;
      7 
      8 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
      9 const allocator = &general_purpose_allocator.allocator;
     10 
     11 pub fn main() !void {
     12     defer _ = general_purpose_allocator.deinit();
     13 
     14     var args_it = process.args();
     15     const exe = try unwrapArg(args_it.next(allocator).?);
     16     defer allocator.free(exe);
     17     var catted_anything = false;
     18     const stdout_file = io.getStdOut();
     19 
     20     const cwd = fs.cwd();
     21 
     22     while (args_it.next(allocator)) |arg_or_err| {
     23         const arg = try unwrapArg(arg_or_err);
     24         defer allocator.free(arg);
     25         if (mem.eql(u8, arg, "-")) {
     26             catted_anything = true;
     27             try cat_file(stdout_file, io.getStdIn());
     28         } else if (arg[0] == '-') {
     29             return usage(exe);
     30         } else {
     31             const file = cwd.openFile(arg, .{}) catch |err| {
     32                 warn("Unable to open file: {}\n", .{@errorName(err)});
     33                 return err;
     34             };
     35             defer file.close();
     36 
     37             catted_anything = true;
     38             try cat_file(stdout_file, file);
     39         }
     40     }
     41     if (!catted_anything) {
     42         try cat_file(stdout_file, io.getStdIn());
     43     }
     44 }
     45 
     46 fn usage(exe: []const u8) !void {
     47     warn("Usage: {} [FILE]...\n", .{exe});
     48     return error.Invalid;
     49 }
     50 
     51 // TODO use copy_file_range
     52 fn cat_file(stdout: fs.File, file: fs.File) !void {
     53     var fifo = std.fifo.LinearFifo(u8, .{ .Static = 1024 * 4 }).init();
     54 
     55     fifo.pump(file.reader(), stdout.writer()) catch |err| {
     56         warn("Unable to read from stream or write to stdout: {}\n", .{@errorName(err)});
     57         return err;
     58     };
     59 }
     60 
     61 fn unwrapArg(arg: anyerror![]u8) ![]u8 {
     62     return arg catch |err| {
     63         warn("Unable to parse command line: {}\n", .{err});
     64         return err;
     65     };
     66 }