|
1 | 1 | const std = @import("std"); |
2 | 2 | const ansilust = @import("ansilust"); |
| 3 | +const build_options = @import("build_options"); |
| 4 | + |
| 5 | +const version = build_options.version; |
| 6 | + |
| 7 | +// Helper for managed ArrayList in Zig 0.15 |
| 8 | +fn ArrayList(comptime T: type) type { |
| 9 | + return std.array_list.AlignedManaged(T, null); |
| 10 | +} |
| 11 | + |
| 12 | +fn printVersion() void { |
| 13 | + const stdout_file = std.fs.File{ .handle = std.posix.STDOUT_FILENO }; |
| 14 | + stdout_file.writeAll("ansilust " ++ version ++ "\n") catch {}; |
| 15 | +} |
| 16 | + |
| 17 | +fn printHelp(file: std.fs.File) void { |
| 18 | + file.writeAll( |
| 19 | + \\ansilust - Next-generation text art processing system |
| 20 | + \\ |
| 21 | + \\USAGE: |
| 22 | + \\ ansilust [OPTIONS] <file.ans> [<file2.ans> ...] |
| 23 | + \\ |
| 24 | + \\OPTIONS: |
| 25 | + \\ -h, --help Print this help message |
| 26 | + \\ -V, --version Print version information |
| 27 | + \\ |
| 28 | + \\EXAMPLES: |
| 29 | + \\ ansilust artwork.ans Render ANSI art to terminal |
| 30 | + \\ ansilust file1.ans file2.ans Render multiple files |
| 31 | + \\ |
| 32 | + ) catch {}; |
| 33 | +} |
3 | 34 |
|
4 | 35 | fn processFile(allocator: std.mem.Allocator, path: []const u8) !void { |
5 | 36 | const file_data = std.fs.cwd().readFileAlloc(allocator, path, 100 * 1024 * 1024) catch |e| { |
@@ -34,14 +65,50 @@ pub fn main() !void { |
34 | 65 |
|
35 | 66 | _ = args.next(); // skip argv0 |
36 | 67 |
|
37 | | - var file_count: usize = 0; |
38 | | - while (args.next()) |path| { |
39 | | - try processFile(allocator, path); |
40 | | - file_count += 1; |
| 68 | + const stdout_file = std.fs.File{ .handle = std.posix.STDOUT_FILENO }; |
| 69 | + const stderr_file = std.fs.File{ .handle = std.posix.STDERR_FILENO }; |
| 70 | + |
| 71 | + var file_paths = ArrayList([]const u8).init(allocator); |
| 72 | + defer file_paths.deinit(); |
| 73 | + |
| 74 | + var show_help = false; |
| 75 | + var show_version = false; |
| 76 | + |
| 77 | + // Parse all arguments first, collect file paths |
| 78 | + while (args.next()) |arg| { |
| 79 | + if (std.mem.eql(u8, arg, "-h") or std.mem.eql(u8, arg, "--help")) { |
| 80 | + show_help = true; |
| 81 | + } else if (std.mem.eql(u8, arg, "-V") or std.mem.eql(u8, arg, "--version")) { |
| 82 | + show_version = true; |
| 83 | + } else if (std.mem.startsWith(u8, arg, "-")) { |
| 84 | + var buf: [256]u8 = undefined; |
| 85 | + const msg = std.fmt.bufPrint(&buf, "error: unknown option '{s}'\n", .{arg}) catch "error: unknown option\n"; |
| 86 | + stderr_file.writeAll(msg) catch {}; |
| 87 | + stderr_file.writeAll("Try 'ansilust --help' for more information.\n") catch {}; |
| 88 | + std.process.exit(1); |
| 89 | + } else { |
| 90 | + try file_paths.append(arg); |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + // Handle flags before processing files |
| 95 | + if (show_version) { |
| 96 | + printVersion(); |
| 97 | + return; |
41 | 98 | } |
42 | 99 |
|
43 | | - if (file_count == 0) { |
44 | | - std.debug.print("usage: ansilust <file.ans> [<file2.ans> ...]\n", .{}); |
| 100 | + if (show_help) { |
| 101 | + printHelp(stdout_file); |
45 | 102 | return; |
46 | 103 | } |
| 104 | + |
| 105 | + if (file_paths.items.len == 0) { |
| 106 | + printHelp(stderr_file); |
| 107 | + std.process.exit(1); |
| 108 | + } |
| 109 | + |
| 110 | + // Process files after all argument parsing is complete |
| 111 | + for (file_paths.items) |path| { |
| 112 | + try processFile(allocator, path); |
| 113 | + } |
47 | 114 | } |
0 commit comments