diff --git a/tools/docgen.zig b/tools/docgen.zig index 18311b0d54..656d6f6ba3 100644 --- a/tools/docgen.zig +++ b/tools/docgen.zig @@ -16,16 +16,17 @@ const max_doc_file_size = 10 * 1024 * 1024; const obj_ext = builtin.object_format.fileExt(builtin.cpu.arch); -const usage = - \\Usage: docgen [options] input output - \\ - \\ Generates an HTML document from a docgen template. - \\ - \\Options: - \\ --code-dir dir Path to directory containing code example outputs - \\ -h, --help Print this help and exit - \\ -; +const Args = struct { + pub const description = "Generates an HTML document from a docgen template."; + named: struct { + @"code-dir": [:0]const u8, + pub const @"code-dir_help" = "Path to directory containing code example outputs"; + }, + positional: struct { + input: [:0]const u8, + output: [:0]const u8, + }, +}; pub fn main() !void { var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); @@ -33,38 +34,10 @@ pub fn main() !void { const arena = arena_instance.allocator(); - var args_it = try process.argsWithAllocator(arena); - if (!args_it.skip()) @panic("expected self arg"); - - var opt_code_dir: ?[]const u8 = null; - var opt_input: ?[]const u8 = null; - var opt_output: ?[]const u8 = null; - - while (args_it.next()) |arg| { - if (mem.startsWith(u8, arg, "-")) { - if (mem.eql(u8, arg, "-h") or mem.eql(u8, arg, "--help")) { - try fs.File.stdout().writeAll(usage); - process.exit(0); - } else if (mem.eql(u8, arg, "--code-dir")) { - if (args_it.next()) |param| { - opt_code_dir = param; - } else { - fatal("expected parameter after --code-dir", .{}); - } - } else { - fatal("unrecognized option: '{s}'", .{arg}); - } - } else if (opt_input == null) { - opt_input = arg; - } else if (opt_output == null) { - opt_output = arg; - } else { - fatal("unexpected positional argument: '{s}'", .{arg}); - } - } - const input_path = opt_input orelse fatal("missing input file", .{}); - const output_path = opt_output orelse fatal("missing output file", .{}); - const code_dir_path = opt_code_dir orelse fatal("missing --code-dir argument", .{}); + const args = try std.cli.parse(Args, arena, .{}); + const input_path = args.positional.input; + const output_path = args.positional.output; + const code_dir_path = args.named.@"code-dir"; var in_file = try fs.cwd().openFile(input_path, .{}); defer in_file.close(); diff --git a/tools/dump-cov.zig b/tools/dump-cov.zig index 249783b927..2d93a25800 100644 --- a/tools/dump-cov.zig +++ b/tools/dump-cov.zig @@ -16,9 +16,15 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const exe_file_name = args[1]; - const cov_file_name = args[2]; + const args = try std.cli.parse(struct { + named: struct {}, + positional: struct { + exe_file: [:0]const u8, + cov_file: [:0]const u8, + }, + }, arena, .{}); + const exe_file_name = args.positional.exe_file; + const cov_file_name = args.positional.cov_file; const exe_path: Path = .{ .root_dir = std.Build.Cache.Directory.cwd(), diff --git a/tools/fetch_them_macos_headers.zig b/tools/fetch_them_macos_headers.zig index 3c070e849f..b2e4a5172b 100644 --- a/tools/fetch_them_macos_headers.zig +++ b/tools/fetch_them_macos_headers.zig @@ -55,36 +55,24 @@ const Target = struct { const headers_source_prefix: []const u8 = "headers"; -const usage = - \\fetch_them_macos_headers [options] [cc args] - \\ - \\Options: - \\ --sysroot Path to macOS SDK - \\ - \\General Options: - \\-h, --help Print this help and exit -; +const Args = struct { + named: struct { + sysroot: []const u8 = "", + pub const sysroot_help = "Path to macOS SDK"; + }, + positional: struct { + cc_args: []const [:0]const u8 = &.{}, + }, +}; pub fn main() anyerror!void { var arena = std.heap.ArenaAllocator.init(gpa); defer arena.deinit(); const allocator = arena.allocator(); - const args = try std.process.argsAlloc(allocator); + const args = try std.cli.parse(Args, allocator, .{}); - var argv = std.array_list.Managed([]const u8).init(allocator); - var sysroot: ?[]const u8 = null; - - var args_iter = ArgsIterator{ .args = args[1..] }; - while (args_iter.next()) |arg| { - if (mem.eql(u8, arg, "--help") or mem.eql(u8, arg, "-h")) { - return info(usage, .{}); - } else if (mem.eql(u8, arg, "--sysroot")) { - sysroot = args_iter.nextOrFatal(); - } else try argv.append(arg); - } - - const sysroot_path = sysroot orelse blk: { + const sysroot_path = if (args.named.sysroot.len > 0) args.named.sysroot else blk: { const target = try std.zig.system.resolveTargetQuery(.{}); break :blk std.zig.system.darwin.getSdk(allocator, &target) orelse fatal("no SDK found; you can provide one explicitly with '--sysroot' flag", .{}); @@ -121,13 +109,13 @@ pub fn main() anyerror!void { .arch = arch, .os_ver = os_ver, }; - try fetchTarget(allocator, argv.items, sysroot_path, target, version, tmp); + try fetchTarget(allocator, args.positional.cc_args, sysroot_path, target, version, tmp); } } fn fetchTarget( arena: Allocator, - args: []const []const u8, + cc_args: []const []const u8, sysroot: []const u8, target: Target, ver: Version, @@ -165,7 +153,7 @@ fn fetchTarget( "-MF", headers_list_path, }); - try cc_argv.appendSlice(args); + try cc_argv.appendSlice(cc_args); const res = try std.process.Child.run(.{ .allocator = arena, @@ -229,24 +217,6 @@ fn fetchTarget( } } -const ArgsIterator = struct { - args: []const []const u8, - i: usize = 0, - - fn next(it: *@This()) ?[]const u8 { - if (it.i >= it.args.len) { - return null; - } - defer it.i += 1; - return it.args[it.i]; - } - - fn nextOrFatal(it: *@This()) []const u8 { - const arg = it.next() orelse fatal("expected parameter after '{s}'", .{it.args[it.i - 1]}); - return arg; - } -}; - const Version = struct { major: u16, minor: u8, diff --git a/tools/gen_macos_headers_c.zig b/tools/gen_macos_headers_c.zig index f95023adb7..7d04032e41 100644 --- a/tools/gen_macos_headers_c.zig +++ b/tools/gen_macos_headers_c.zig @@ -8,32 +8,18 @@ const Allocator = std.mem.Allocator; var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; const gpa = general_purpose_allocator.allocator(); -const usage = - \\gen_macos_headers_c [dir] - \\ - \\General Options: - \\-h, --help Print this help and exit -; - pub fn main() anyerror!void { var arena_allocator = std.heap.ArenaAllocator.init(gpa); defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - const args = try std.process.argsAlloc(arena); - if (args.len == 1) fatal("no command or option specified", .{}); + const args = try std.cli.parse(struct { + positional: struct { + dir: []const u8, + }, + }, arena, .{}); - var positionals = std.array_list.Managed([]const u8).init(arena); - - for (args[1..]) |arg| { - if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) { - return info(usage, .{}); - } else try positionals.append(arg); - } - - if (positionals.items.len != 1) fatal("expected one positional argument: [dir]", .{}); - - var dir = try std.fs.cwd().openDir(positionals.items[0], .{ .no_follow = true }); + var dir = try std.fs.cwd().openDir(args.positional.dir, .{ .no_follow = true }); defer dir.close(); var paths = std.array_list.Managed([]const u8).init(arena); try findHeaders(arena, dir, "", &paths); diff --git a/tools/gen_outline_atomics.zig b/tools/gen_outline_atomics.zig index 1dade66610..a5d379d477 100644 --- a/tools/gen_outline_atomics.zig +++ b/tools/gen_outline_atomics.zig @@ -15,7 +15,7 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - //const args = try std.process.argsAlloc(arena); + _ = try std.cli.parse(struct {}, arena, .{}); var stdout_buffer: [2000]u8 = undefined; var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer); diff --git a/tools/gen_spirv_spec.zig b/tools/gen_spirv_spec.zig index 702866824c..1f481ae5ed 100644 --- a/tools/gen_spirv_spec.zig +++ b/tools/gen_spirv_spec.zig @@ -58,12 +58,20 @@ const allocator = arena.allocator(); pub fn main() !void { defer arena.deinit(); - const args = try std.process.argsAlloc(allocator); - if (args.len != 3) { - usageAndExit(args[0], 1); - } + const args = try std.cli.parse(struct { + pub const description = + \\Generates Zig bindings for SPIR-V specifications found in the SPIRV-Headers + \\repository. The result, printed to stdout, should be used to update + \\files in src/codegen/spirv. Don't forget to format the output. + ; + positional: struct { + pub const @"path/to/SPIRV-Headers_help" = "should point to a clone of https://github.com/KhronosGroup/SPIRV-Headers/"; + @"path/to/SPIRV-Headers": [:0]const u8, + @"path/to/zig/src/codegen/spirv/extinst.zig.grammar.json": [:0]const u8, + }, + }, allocator, .{}); - const json_path = try std.fs.path.join(allocator, &.{ args[1], "include/spirv/unified1/" }); + const json_path = try std.fs.path.join(allocator, &.{ args.positional.@"path/to/SPIRV-Headers", "include/spirv/unified1/" }); const dir = try std.fs.cwd().openDir(json_path, .{ .iterate = true }); const core_spec = try readRegistry(CoreRegistry, dir, "spirv.core.grammar.json"); @@ -80,7 +88,7 @@ pub fn main() !void { try readExtRegistry(&exts, dir, entry.name); } - try readExtRegistry(&exts, std.fs.cwd(), args[2]); + try readExtRegistry(&exts, std.fs.cwd(), args.positional.@"path/to/zig/src/codegen/spirv/extinst.zig.grammar.json"); var allocating: std.Io.Writer.Allocating = .init(allocator); defer allocating.deinit(); @@ -929,19 +937,3 @@ fn parseHexInt(text: []const u8) !u31 { return error.InvalidHexInt; return try std.fmt.parseInt(u31, text[prefix.len..], 16); } - -fn usageAndExit(arg0: []const u8, code: u8) noreturn { - const stderr = std.debug.lockStderrWriter(&.{}); - stderr.print( - \\Usage: {s} - \\ - \\Generates Zig bindings for SPIR-V specifications found in the SPIRV-Headers - \\repository. The result, printed to stdout, should be used to update - \\files in src/codegen/spirv. Don't forget to format the output. - \\ - \\ should point to a clone of - \\https://github.com/KhronosGroup/SPIRV-Headers/ - \\ - , .{arg0}) catch std.process.exit(1); - std.process.exit(code); -} diff --git a/tools/gen_stubs.zig b/tools/gen_stubs.zig index 1aadda232d..5ad6be25ac 100644 --- a/tools/gen_stubs.zig +++ b/tools/gen_stubs.zig @@ -284,8 +284,12 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const build_all_path = args[1]; + const args = try std.cli.parse(struct { + positional: struct { + build_all_path: [:0]const u8, + }, + }, arena, .{}); + const build_all_path = args.positional.build_all_path; var build_all_dir = try std.fs.cwd().openDir(build_all_path, .{}); diff --git a/tools/generate_JSONTestSuite.zig b/tools/generate_JSONTestSuite.zig index 2c6fee5bdd..c8e9c3e329 100644 --- a/tools/generate_JSONTestSuite.zig +++ b/tools/generate_JSONTestSuite.zig @@ -1,4 +1,6 @@ -// zig run this file inside the test_parsing/ directory of this repo: https://github.com/nst/JSONTestSuite +const Args = struct { + pub const description = "zig run this file inside the test_parsing/ directory of this repo: https://github.com/nst/JSONTestSuite"; +}; const std = @import("std"); @@ -6,6 +8,8 @@ pub fn main() !void { var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; var allocator = gpa.allocator(); + _ = try std.cli.parse(Args, allocator, .{}); + var stdout_buffer: [2000]u8 = undefined; var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer); const output = &stdout_writer.interface; diff --git a/tools/generate_c_size_and_align_checks.zig b/tools/generate_c_size_and_align_checks.zig index 8c278407e4..c833dbdf95 100644 --- a/tools/generate_c_size_and_align_checks.zig +++ b/tools/generate_c_size_and_align_checks.zig @@ -25,21 +25,22 @@ fn cName(ty: std.Target.CType) []const u8 { }; } -var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; - pub fn main() !void { - const gpa = general_purpose_allocator.allocator(); + var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; defer std.debug.assert(general_purpose_allocator.deinit() == .ok); + const gpa = general_purpose_allocator.allocator(); - const args = try std.process.argsAlloc(gpa); - defer std.process.argsFree(gpa, args); + var arena_instance = std.heap.ArenaAllocator.init(gpa); + defer arena_instance.deinit(); + const arena = arena_instance.allocator(); - if (args.len != 2) { - std.debug.print("Usage: {s} [target_triple]\n", .{args[0]}); - std.process.exit(1); - } + const args = try std.cli.parse(struct { + positional: struct { + target_triple: [:0]const u8, + }, + }, arena, .{}); - const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] }); + const query = try std.Target.Query.parse(.{ .arch_os_abi = args.positional.target_triple }); const target = try std.zig.system.resolveTargetQuery(query); var buffer: [2000]u8 = undefined; diff --git a/tools/generate_linux_syscalls.zig b/tools/generate_linux_syscalls.zig index 2705618a7d..18e216d559 100644 --- a/tools/generate_linux_syscalls.zig +++ b/tools/generate_linux_syscalls.zig @@ -11,6 +11,16 @@ //! //! Everything after `name` is ignored for the purposes of this tool. +const Args = struct { + pub const description = + \\Generates the list of Linux syscalls for each supported cpu arch, using the Linux development tree. + \\Prints to stdout Zig code which you can use to replace the file lib/std/os/linux/syscalls.zig. + ; + positional: struct { + @"/path/to/linux": [:0]const u8, + }, +}; + const std = @import("std"); const Io = std.Io; const mem = std.mem; @@ -175,12 +185,8 @@ pub fn main() !void { defer arena.deinit(); const gpa = arena.allocator(); - const args = try std.process.argsAlloc(gpa); - if (args.len < 2 or mem.eql(u8, args[1], "--help")) { - usage(std.debug.lockStderrWriter(&.{}), args[0]) catch std.process.exit(2); - std.process.exit(1); - } - const linux_path = args[1]; + const args = try std.cli.parse(Args, gpa, .{}); + const linux_path = args.positional.@"/path/to/linux"; var stdout_buffer: [2048]u8 = undefined; var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer); @@ -247,14 +253,3 @@ pub fn main() !void { try Io.Writer.flush(stdout); } - -fn usage(w: *std.Io.Writer, arg0: []const u8) std.Io.Writer.Error!void { - try w.print( - \\Usage: {s} /path/to/zig /path/to/linux - \\Alternative Usage: zig run /path/to/git/zig/tools/generate_linux_syscalls.zig -- /path/to/zig /path/to/linux - \\ - \\Generates the list of Linux syscalls for each supported cpu arch, using the Linux development tree. - \\Prints to stdout Zig code which you can use to replace the file lib/std/os/linux/syscalls.zig. - \\ - , .{arg0}); -} diff --git a/tools/incr-check.zig b/tools/incr-check.zig index ed7443046a..074f124df4 100644 --- a/tools/incr-check.zig +++ b/tools/incr-check.zig @@ -2,8 +2,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const Cache = std.Build.Cache; -const usage = "usage: incr-check [--zig-lib-dir lib] [--debug-zcu] [--debug-dwarf] [--debug-link] [--preserve-tmp] [--zig-cc-binary /path/to/zig]"; - pub fn main() !void { const fatal = std.process.fatal; @@ -11,46 +9,29 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - var opt_zig_exe: ?[]const u8 = null; - var opt_input_file_name: ?[]const u8 = null; - var opt_lib_dir: ?[]const u8 = null; - var opt_cc_zig: ?[]const u8 = null; - var debug_zcu = false; - var debug_dwarf = false; - var debug_link = false; - var preserve_tmp = false; + const args = try std.cli.parse(struct { + positional: struct { + @"zig-binary-path": []const u8, + @"input-file": []const u8, + }, + named: struct { + @"zig-lib-dir": []const u8 = "", + @"debug-zcu": bool = false, + @"debug-dwarf": bool = false, + @"debug-link": bool = false, + preserve_tmp: bool = false, + @"zig-cc-binary": []const u8 = "", + }, + }, arena, .{}); - var arg_it = try std.process.argsWithAllocator(arena); - _ = arg_it.skip(); - while (arg_it.next()) |arg| { - if (arg.len > 0 and arg[0] == '-') { - if (std.mem.eql(u8, arg, "--zig-lib-dir")) { - opt_lib_dir = arg_it.next() orelse fatal("expected arg after '--zig-lib-dir'\n{s}", .{usage}); - } else if (std.mem.eql(u8, arg, "--debug-zcu")) { - debug_zcu = true; - } else if (std.mem.eql(u8, arg, "--debug-dwarf")) { - debug_dwarf = true; - } else if (std.mem.eql(u8, arg, "--debug-link")) { - debug_link = true; - } else if (std.mem.eql(u8, arg, "--preserve-tmp")) { - preserve_tmp = true; - } else if (std.mem.eql(u8, arg, "--zig-cc-binary")) { - opt_cc_zig = arg_it.next() orelse fatal("expect arg after '--zig-cc-binary'\n{s}", .{usage}); - } else { - fatal("unknown option '{s}'\n{s}", .{ arg, usage }); - } - continue; - } - if (opt_zig_exe == null) { - opt_zig_exe = arg; - } else if (opt_input_file_name == null) { - opt_input_file_name = arg; - } else { - fatal("unknown argument '{s}'\n{s}", .{ arg, usage }); - } - } - const zig_exe = opt_zig_exe orelse fatal("missing path to zig\n{s}", .{usage}); - const input_file_name = opt_input_file_name orelse fatal("missing input file\n{s}", .{usage}); + const opt_lib_dir: ?[]const u8 = if (args.named.@"zig-lib-dir".len > 0) args.named.@"zig-lib-dir" else null; + const opt_cc_zig: ?[]const u8 = if (args.named.@"zig-cc-binary".len > 0) args.named.@"zig-cc-binary" else null; + const debug_zcu = args.named.@"debug-zcu"; + const debug_dwarf = args.named.@"debug-dwarf"; + const debug_link = args.named.@"debug-link"; + const preserve_tmp = args.named.preserve_tmp; + const zig_exe = args.positional.@"zig-binary-path"; + const input_file_name = args.positional.@"input-file"; const input_file_bytes = try std.fs.cwd().readFileAlloc(input_file_name, arena, .limited(std.math.maxInt(u32))); const case = try Case.parse(arena, input_file_bytes); diff --git a/tools/migrate_langref.zig b/tools/migrate_langref.zig index d880db1c25..77ffd717fb 100644 --- a/tools/migrate_langref.zig +++ b/tools/migrate_langref.zig @@ -13,9 +13,14 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const input_file = args[1]; - const output_file = args[2]; + const args = try std.cli.parse(struct { + positional: struct { + input_file: [:0]const u8, + output_file: [:0]const u8, + }, + }, arena, .{}); + const input_file = args.positional.input_file; + const output_file = args.positional.output_file; var in_file = try fs.cwd().openFile(input_file, .{ .mode = .read_only }); defer in_file.close(); diff --git a/tools/process_headers.zig b/tools/process_headers.zig index eb671193bb..9e8b5e178b 100644 --- a/tools/process_headers.zig +++ b/tools/process_headers.zig @@ -119,52 +119,24 @@ const HashToContents = std.StringHashMap(Contents); const TargetToHash = std.StringArrayHashMap([]const u8); const PathTable = std.StringHashMap(*TargetToHash); -const LibCVendor = enum { - musl, - glibc, - freebsd, - netbsd, -}; - pub fn main() !void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); const allocator = arena.allocator(); - const args = try std.process.argsAlloc(allocator); - var search_paths = std.array_list.Managed([]const u8).init(allocator); - var opt_out_dir: ?[]const u8 = null; - var opt_abi: ?[]const u8 = null; - var arg_i: usize = 1; - while (arg_i < args.len) : (arg_i += 1) { - if (std.mem.eql(u8, args[arg_i], "--help")) - usageAndExit(args[0]); - if (arg_i + 1 >= args.len) { - std.debug.print("expected argument after '{s}'\n", .{args[arg_i]}); - usageAndExit(args[0]); - } + const args = try std.cli.parse(struct { + named: struct { + @"search-path": []const []const u8 = &.{}, + out: []const u8, + abi: enum { musl, glibc, freebsd, netbsd }, - if (std.mem.eql(u8, args[arg_i], "--search-path")) { - try search_paths.append(args[arg_i + 1]); - } else if (std.mem.eql(u8, args[arg_i], "--out")) { - assert(opt_out_dir == null); - opt_out_dir = args[arg_i + 1]; - } else if (std.mem.eql(u8, args[arg_i], "--abi")) { - assert(opt_abi == null); - opt_abi = args[arg_i + 1]; - } else { - std.debug.print("unrecognized argument: {s}\n", .{args[arg_i]}); - usageAndExit(args[0]); - } - - arg_i += 1; - } - - const out_dir = opt_out_dir orelse usageAndExit(args[0]); - const abi_name = opt_abi orelse usageAndExit(args[0]); - const vendor = std.meta.stringToEnum(LibCVendor, abi_name) orelse { - std.debug.print("unrecognized C ABI: {s}\n", .{abi_name}); - usageAndExit(args[0]); - }; + pub const @"search-path_help" = "subdirectories of search paths look like, e.g. x86_64-linux-gnu"; + pub const out_help = "a dir that will be created, and populated with the results"; + }, + }, allocator, .{}); + const search_paths = args.named.@"search-path"; + const out_dir = args.named.out; + const vendor = args.named.abi; + const abi_name = @tagName(vendor); const generic_name = try std.fmt.allocPrint(allocator, "generic-{s}", .{abi_name}); const libc_targets = switch (vendor) { @@ -225,7 +197,7 @@ pub fn main() !void { @tagName(libc_target.abi), }); - search: for (search_paths.items) |search_path| { + search: for (search_paths) |search_path| { const sub_path = switch (vendor) { .glibc, .freebsd, @@ -362,12 +334,3 @@ pub fn main() !void { } } } - -fn usageAndExit(arg0: []const u8) noreturn { - std.debug.print("Usage: {s} [--search-path ] --out --abi \n", .{arg0}); - std.debug.print("--search-path can be used any number of times.\n", .{}); - std.debug.print(" subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{}); - std.debug.print("--out is a dir that will be created, and populated with the results\n", .{}); - std.debug.print("--abi is either glibc, musl, freebsd, or netbsd\n", .{}); - std.process.exit(1); -} diff --git a/tools/update-linux-headers.zig b/tools/update-linux-headers.zig index bf9edf0753..99df00760a 100644 --- a/tools/update-linux-headers.zig +++ b/tools/update-linux-headers.zig @@ -142,33 +142,18 @@ const PathTable = std.StringHashMap(*TargetToHash); pub fn main() !void { var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator); const arena = arena_state.allocator(); - const args = try std.process.argsAlloc(arena); - var search_paths = std.array_list.Managed([]const u8).init(arena); - var opt_out_dir: ?[]const u8 = null; - var arg_i: usize = 1; - while (arg_i < args.len) : (arg_i += 1) { - if (std.mem.eql(u8, args[arg_i], "--help")) - usageAndExit(args[0]); - if (arg_i + 1 >= args.len) { - std.debug.print("expected argument after '{s}'\n", .{args[arg_i]}); - usageAndExit(args[0]); - } + const args = try std.cli.parse(struct { + named: struct { + @"search-path": []const []const u8 = &.{}, + out: []const u8, - if (std.mem.eql(u8, args[arg_i], "--search-path")) { - try search_paths.append(args[arg_i + 1]); - } else if (std.mem.eql(u8, args[arg_i], "--out")) { - assert(opt_out_dir == null); - opt_out_dir = args[arg_i + 1]; - } else { - std.debug.print("unrecognized argument: {s}\n", .{args[arg_i]}); - usageAndExit(args[0]); - } - - arg_i += 1; - } - - const out_dir = opt_out_dir orelse usageAndExit(args[0]); + pub const @"search-path_help" = "subdirectories of search paths look like, e.g. x86_64-linux-gnu"; + pub const out_help = "a dir that will be created, and populated with the results"; + }, + }, arena, .{}); + const search_paths = args.named.@"search-path"; + const out_dir = args.named.out; const generic_name = "any-linux-any"; var path_table = PathTable.init(arena); @@ -182,7 +167,7 @@ pub fn main() !void { const dest_target = DestTarget{ .arch = linux_target.arch, }; - search: for (search_paths.items) |search_path| { + search: for (search_paths) |search_path| { const target_include_dir = try std.fs.path.join(arena, &.{ search_path, linux_target.name, "include", }); @@ -320,11 +305,3 @@ pub fn main() !void { try std.fs.cwd().deleteFile(full_path); } } - -fn usageAndExit(arg0: []const u8) noreturn { - std.debug.print("Usage: {s} [--search-path ] --out --abi \n", .{arg0}); - std.debug.print("--search-path can be used any number of times.\n", .{}); - std.debug.print(" subdirectories of search paths look like, e.g. x86_64-linux-gnu\n", .{}); - std.debug.print("--out is a dir that will be created, and populated with the results\n", .{}); - std.process.exit(1); -} diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index 9b054478a2..e40e55bc74 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -630,29 +630,22 @@ const cpu_targets = struct { pub fn main() anyerror!void { var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); - const allocator = arena.allocator(); - const args = try std.process.argsAlloc(allocator); var stdout_buffer: [4000]u8 = undefined; var stdout_writer = fs.File.stdout().writerStreaming(&stdout_buffer); const stdout = &stdout_writer.interface; - if (args.len <= 1) printUsageAndExit(args[0]); + const args = try std.cli.parse(struct { + pub const description = "Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig."; + positional: struct { + @"/path/to/llvm-tblgen": [:0]const u8, + @"/path/to/git/llvm/llvm-project": [:0]const u8, + }, + }, allocator, .{}); - if (std.mem.eql(u8, args[1], "--help")) { - printUsage(stdout, args[0]) catch std.process.exit(2); - stdout.flush() catch std.process.exit(2); - std.process.exit(0); - } - - if (args.len < 3) printUsageAndExit(args[0]); - - const llvm_tblgen_exe = args[1]; - if (std.mem.startsWith(u8, llvm_tblgen_exe, "-")) printUsageAndExit(args[0]); - - const llvm_src_root = args[2]; - if (std.mem.startsWith(u8, llvm_src_root, "-")) printUsageAndExit(args[0]); + const llvm_tblgen_exe = args.positional.@"/path/to/llvm-tblgen"; + const llvm_src_root = args.positional.@"/path/to/git/llvm/llvm-project"; var llvm_to_zig_cpu_features = std.StringHashMap([]const u8).init(allocator); @@ -959,18 +952,3 @@ fn objectLessThan(context: void, a: *json.ObjectMap, b: *json.ObjectMap) bool { const b_key = b.get("!name").?.string; return std.mem.lessThan(u8, a_key, b_key); } - -fn printUsageAndExit(arg0: []const u8) noreturn { - printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2); - std.process.exit(1); -} - -fn printUsage(w: *std.Io.Writer, arg0: []const u8) std.Io.Writer.Error!void { - try w.print( - \\Usage: {s} /path/to/llvm-tblgen /path/to/git/llvm/llvm-project - \\Alternative Usage: zig run /path/to/git/zig/tools/update_clang_options.zig -- /path/to/llvm-tblgen /path/to/git/llvm/llvm-project - \\ - \\Prints to stdout Zig code which you can use to replace the file src/clang_options_data.zig. - \\ - , .{arg0}); -} diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig index b6e0d6495e..9dfd740801 100644 --- a/tools/update_cpu_features.zig +++ b/tools/update_cpu_features.zig @@ -1567,38 +1567,23 @@ pub fn main() anyerror!void { defer arena_state.deinit(); const arena = arena_state.allocator(); - var args = try std.process.argsWithAllocator(arena); - const args0 = args.next().?; - - const llvm_tblgen_exe = args.next() orelse - usageAndExit(args0, 1); - - if (std.mem.eql(u8, llvm_tblgen_exe, "--help")) { - usageAndExit(args0, 0); - } - if (std.mem.startsWith(u8, llvm_tblgen_exe, "-")) { - usageAndExit(args0, 1); - } - - const llvm_src_root = args.next() orelse - usageAndExit(args0, 1); - - if (std.mem.startsWith(u8, llvm_src_root, "-")) { - usageAndExit(args0, 1); - } - - const zig_src_root = args.next() orelse - usageAndExit(args0, 1); - - if (std.mem.startsWith(u8, zig_src_root, "-")) { - usageAndExit(args0, 1); - } - - var filter: ?[]const u8 = null; - if (args.next()) |arg| filter = arg; - - // there shouldn't be any more argument after the optional filter - if (args.skip()) usageAndExit(args0, 1); + const args = try std.cli.parse(struct { + pub const description = + \\Updates lib/std/target/.zig from llvm/lib/Target//.td . + \\ + \\On a less beefy system, or when debugging, compile with -fsingle-threaded. + ; + positional: struct { + @"/path/to/llvm-tblgen": [:0]const u8, + @"/path/git/llvm-project": [:0]const u8, + @"/path/git/zig": [:0]const u8, + zig_name_filter: []const u8 = "", + }, + }, arena, .{}); + const llvm_tblgen_exe = args.positional.@"/path/to/llvm-tblgen"; + const llvm_src_root = args.positional.@"/path/git/llvm-project"; + const zig_src_root = args.positional.@"/path/git/zig"; + const filter: ?[]const u8 = if (args.positional.zig_name_filter.len > 0) args.positional.zig_name_filter else null; var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{}); defer zig_src_dir.close(); @@ -2104,19 +2089,6 @@ fn processOneTarget(job: Job) void { render_progress.end(); } -fn usageAndExit(arg0: []const u8, code: u8) noreturn { - const stderr = std.debug.lockStderrWriter(&.{}); - stderr.print( - \\Usage: {s} /path/to/llvm-tblgen /path/git/llvm-project /path/git/zig [zig_name filter] - \\ - \\Updates lib/std/target/.zig from llvm/lib/Target//.td . - \\ - \\On a less beefy system, or when debugging, compile with -fsingle-threaded. - \\ - , .{arg0}) catch std.process.exit(1); - std.process.exit(code); -} - fn featureLessThan(_: void, a: Feature, b: Feature) bool { return std.ascii.lessThanIgnoreCase(a.zig_name, b.zig_name); } diff --git a/tools/update_crc_catalog.zig b/tools/update_crc_catalog.zig index a973a1b75a..a25f23a3f2 100644 --- a/tools/update_crc_catalog.zig +++ b/tools/update_crc_catalog.zig @@ -10,11 +10,12 @@ pub fn main() anyerror!void { defer arena_state.deinit(); const arena = arena_state.allocator(); - const args = try std.process.argsAlloc(arena); - if (args.len <= 1) printUsageAndExit(args[0]); - - const zig_src_root = args[1]; - if (mem.startsWith(u8, zig_src_root, "-")) printUsageAndExit(args[0]); + const args = try std.cli.parse(struct { + positional: struct { + @"/path/git/zig": [:0]const u8, + }, + }, arena, .{}); + const zig_src_root = args.positional.@"/path/git/zig"; var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{}); defer zig_src_dir.close(); @@ -188,15 +189,3 @@ pub fn main() anyerror!void { try code_writer.flush(); try test_writer.flush(); } - -fn printUsageAndExit(arg0: []const u8) noreturn { - printUsage(std.debug.lockStderrWriter(&.{}), arg0) catch std.process.exit(2); - std.process.exit(1); -} - -fn printUsage(w: *std.Io.Writer, arg0: []const u8) std.Io.Writer.Error!void { - return w.print( - \\Usage: {s} /path/git/zig - \\ - , .{arg0}); -} diff --git a/tools/update_freebsd_libc.zig b/tools/update_freebsd_libc.zig index 420147e0df..9cb972d632 100644 --- a/tools/update_freebsd_libc.zig +++ b/tools/update_freebsd_libc.zig @@ -16,9 +16,14 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const freebsd_src_path = args[1]; - const zig_src_path = args[2]; + const args = try std.cli.parse(struct { + positional: struct { + freebsd_src_path: [:0]const u8, + zig_src_path: [:0]const u8, + }, + }, arena, .{}); + const freebsd_src_path = args.positional.freebsd_src_path; + const zig_src_path = args.positional.zig_src_path; const dest_dir_path = try std.fmt.allocPrint(arena, "{s}/lib/libc/freebsd", .{zig_src_path}); diff --git a/tools/update_glibc.zig b/tools/update_glibc.zig index 297c5c65b5..315db83a8a 100644 --- a/tools/update_glibc.zig +++ b/tools/update_glibc.zig @@ -41,9 +41,14 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const glibc_src_path = args[1]; - const zig_src_path = args[2]; + const args = try std.cli.parse(struct { + positional: struct { + glibc_src_path: [:0]const u8, + zig_src_path: [:0]const u8, + }, + }, arena, .{}); + const glibc_src_path = args.positional.glibc_src_path; + const zig_src_path = args.positional.zig_src_path; const dest_dir_path = try std.fmt.allocPrint(arena, "{s}/lib/libc/glibc", .{zig_src_path}); diff --git a/tools/update_mingw.zig b/tools/update_mingw.zig index 9c67b27375..dbae3756e6 100644 --- a/tools/update_mingw.zig +++ b/tools/update_mingw.zig @@ -5,9 +5,14 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const zig_src_lib_path = args[1]; - const mingw_src_path = args[2]; + const args = try std.cli.parse(struct { + positional: struct { + zig_src_lib_path: [:0]const u8, + mingw_src_path: [:0]const u8, + }, + }, arena, .{}); + const zig_src_lib_path = args.positional.zig_src_lib_path; + const mingw_src_path = args.positional.mingw_src_path; const dest_mingw_crt_path = try std.fs.path.join(arena, &.{ zig_src_lib_path, "libc", "mingw", diff --git a/tools/update_netbsd_libc.zig b/tools/update_netbsd_libc.zig index 7bfe99b094..1cd04f1a88 100644 --- a/tools/update_netbsd_libc.zig +++ b/tools/update_netbsd_libc.zig @@ -16,9 +16,14 @@ pub fn main() !void { defer arena_instance.deinit(); const arena = arena_instance.allocator(); - const args = try std.process.argsAlloc(arena); - const netbsd_src_path = args[1]; - const zig_src_path = args[2]; + const args = try std.cli.parse(struct { + positional: struct { + netbsd_src_path: [:0]const u8, + zig_src_path: [:0]const u8, + }, + }, arena, .{}); + const netbsd_src_path = args.positional.netbsd_src_path; + const zig_src_path = args.positional.zig_src_path; const dest_dir_path = try std.fmt.allocPrint(arena, "{s}/lib/libc/netbsd", .{zig_src_path});