const std = @import("std"); const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; const types = @import("./lib/types.zig"); const CommandStatus = types.CommandStatus; const CommandContext = types.CommandContext; pub const Sort = struct { pub fn eval(sort: Sort, ctx: CommandContext) !CommandStatus { _ = sort; var lines = ArrayList([]const u8).init(ctx.allocator); defer { for (lines.items) |line| { ctx.allocator.free(line); } lines.deinit(); } // Read input lines from unified input reader var reader = ctx.input_reader; // Check if we're reading from stdin vs file redirection for DOS-authentic behavior switch (ctx.input_reader) { .stdin => { // Reading from interactive stdin - show usage message (DOS behavior) const msg = "SORT: Use input redirection (< file.txt) to sort file contents\n"; var writer = ctx.output_writer; try writer.write(msg); return CommandStatus{ .Code = 0 }; }, .source => { // Read from input redirection while (try reader.readLine(ctx.allocator)) |line| { try lines.append(line); } }, } // Sort the lines std.mem.sort([]const u8, lines.items, {}, struct { fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool { return std.mem.order(u8, lhs, rhs) == .lt; } }.lessThan); // Output sorted lines var output_buffer = ArrayList(u8).init(ctx.allocator); defer output_buffer.deinit(); for (lines.items) |line| { try output_buffer.writer().print("{s}\n", .{line}); } var writer = ctx.output_writer; try writer.write(output_buffer.items); return CommandStatus{ .Code = 0 }; } };