diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index aec780af02..fc38a8b2bf 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -74,9 +74,7 @@ pub const Environment = struct { pub const default: @This() = .{ .provided = 0 }; }; - /// Load all of the environment variables using the std.process API. Do not use if using Aro as a shared library on Linux without libc - /// See https://github.com/ziglang/zig/issues/4524 - pub fn loadAll(allocator: std.mem.Allocator) !Environment { + pub fn loadAll(allocator: std.mem.Allocator, environ_map: *const std.process.Environ.Map) !Environment { var env: Environment = .{}; errdefer env.deinit(allocator); @@ -85,11 +83,7 @@ pub const Environment = struct { var env_var_buf: [field.name.len]u8 = undefined; const env_var_name = std.ascii.upperString(&env_var_buf, field.name); - const val: ?[]const u8 = std.process.getEnvVarOwned(allocator, env_var_name) catch |err| switch (err) { - error.OutOfMemory => |e| return e, - error.EnvironmentVariableNotFound => null, - error.InvalidWtf8 => null, - }; + const val: ?[]const u8 = if (environ_map.get(env_var_name)) |v| try allocator.dupe(u8, v) else null; @field(env, field.name) = val; } return env; @@ -193,13 +187,20 @@ pub fn init(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, /// Initialize Compilation with default environment, /// pragma handlers and emulation mode set to target. -pub fn initDefault(gpa: Allocator, arena: Allocator, io: Io, diagnostics: *Diagnostics, cwd: Io.Dir) !Compilation { +pub fn initDefault( + gpa: Allocator, + arena: Allocator, + io: Io, + diagnostics: *Diagnostics, + cwd: Io.Dir, + env_map: *const std.process.Environ.Map, +) !Compilation { var comp: Compilation = .{ .gpa = gpa, .arena = arena, .io = io, .diagnostics = diagnostics, - .environment = try Environment.loadAll(gpa), + .environment = try Environment.loadAll(gpa, env_map), .cwd = cwd, }; errdefer comp.deinit(); diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index 6ffaedc2e7..400a1ef6f6 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -1250,21 +1250,25 @@ fn getOutFileName(d: *Driver, source: Source, buf: *[std.fs.max_name_bytes]u8) ! } fn invokeAssembler(d: *Driver, tc: *Toolchain, input_path: []const u8, output_path: []const u8) !void { + const io = d.comp.io; var assembler_path_buf: [std.fs.max_path_bytes]u8 = undefined; const assembler_path = try tc.getAssemblerPath(&assembler_path_buf); const argv = [_][]const u8{ assembler_path, input_path, "-o", output_path }; - var child = std.process.Child.init(&argv, d.comp.gpa); - // TODO handle better - child.stdin_behavior = .inherit; - child.stdout_behavior = .inherit; - child.stderr_behavior = .inherit; - - const term = child.spawnAndWait() catch |er| { + var child = std.process.spawn(io, .{ + .argv = &argv, + // TODO handle better + .stdin = .inherit, + .stdout = .inherit, + .stderr = .inherit, + }) catch |er| { return d.fatal("unable to spawn linker: {s}", .{errorDescription(er)}); }; + const term = child.wait(io) catch |er| { + return d.fatal("unable to wait linker: {s}", .{errorDescription(er)}); + }; switch (term) { - .Exited => |code| if (code != 0) { + .exited => |code| if (code != 0) { const e = d.fatal("assembler exited with an error code", .{}); return e; }, @@ -1490,6 +1494,7 @@ fn dumpLinkerArgs(w: *std.Io.Writer, items: []const []const u8) !void { /// **MAY call `exit` if `fast_exit` is set.** pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) Compilation.Error!void { const gpa = d.comp.gpa; + const io = d.comp.io; var argv: std.ArrayList([]const u8) = .empty; defer argv.deinit(gpa); @@ -1506,17 +1511,20 @@ pub fn invokeLinker(d: *Driver, tc: *Toolchain, comptime fast_exit: bool) Compil return d.fatal("unable to dump linker args: {s}", .{errorDescription(stdout.err.?)}); }; } - var child = std.process.Child.init(argv.items, d.comp.gpa); - // TODO handle better - child.stdin_behavior = .inherit; - child.stdout_behavior = .inherit; - child.stderr_behavior = .inherit; - - const term = child.spawnAndWait() catch |er| { + var child = std.process.spawn(io, .{ + .argv = argv.items, + // TODO handle better + .stdin = .inherit, + .stdout = .inherit, + .stderr = .inherit, + }) catch |er| { return d.fatal("unable to spawn linker: {s}", .{errorDescription(er)}); }; + const term = child.wait(io) catch |er| { + return d.fatal("unable to wait linker: {s}", .{errorDescription(er)}); + }; switch (term) { - .Exited => |code| if (code != 0) { + .exited => |code| if (code != 0) { const e = d.fatal("linker exited with an error code", .{}); if (fast_exit) d.exitWithCleanup(code); return e; diff --git a/lib/compiler/resinator/compile.zig b/lib/compiler/resinator/compile.zig index 4f75fca18a..76d6a14636 100644 --- a/lib/compiler/resinator/compile.zig +++ b/lib/compiler/resinator/compile.zig @@ -80,7 +80,7 @@ pub const Dependencies = struct { } }; -pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void { +pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions, env_map: *const std.process.Environ.Map) !void { var lexer = lex.Lexer.init(source, .{ .default_code_page = options.default_code_page, .source_mappings = options.source_mappings, @@ -148,8 +148,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) }); } if (!options.ignore_include_env_var) { - const INCLUDE = std.process.getEnvVarOwned(allocator, "INCLUDE") catch ""; - defer allocator.free(INCLUDE); + const INCLUDE = env_map.get("INCLUDE") orelse ""; // The only precedence here is llvm-rc which also uses the platform-specific // delimiter. There's no precedence set by `rc.exe` since it's Windows-only. diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index ec5b6fcbc2..58f539274c 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -24,6 +24,9 @@ pub fn main(init: std.process.Init.Minimal) !void { defer std.debug.assert(debug_allocator.deinit() == .ok); const gpa = debug_allocator.allocator(); + var env_map = try init.environ.createMap(gpa); + defer env_map.deinit(); + var threaded: std.Io.Threaded = .init(gpa, .{ .environ = init.environ, .argv0 = .init(init.args), @@ -148,8 +151,8 @@ pub fn main(init: std.process.Init.Minimal) !void { defer argv.deinit(aro_arena); try argv.append(aro_arena, "arocc"); // dummy command name - const resolved_include_paths = try include_paths.get(&error_handler); - try preprocess.appendAroArgs(aro_arena, &argv, options, resolved_include_paths); + const resolved_include_paths = try include_paths.get(&error_handler, &env_map); + try preprocess.appendAroArgs(aro_arena, &argv, options, resolved_include_paths, &env_map); try argv.append(aro_arena, switch (options.input_source) { .stdio => "-", .filename => |filename| filename, @@ -283,7 +286,7 @@ pub fn main(init: std.process.Init.Minimal) !void { .dependencies = maybe_dependencies, .ignore_include_env_var = options.ignore_include_env_var, .extra_include_paths = options.extra_include_paths.items, - .system_include_paths = try include_paths.get(&error_handler), + .system_include_paths = try include_paths.get(&error_handler, &env_map), .default_language_id = options.default_language_id, .default_code_page = default_code_page, .disjoint_code_page = has_disjoint_code_page, @@ -292,7 +295,7 @@ pub fn main(init: std.process.Init.Minimal) !void { .max_string_literal_codepoints = options.max_string_literal_codepoints, .silent_duplicate_control_ids = options.silent_duplicate_control_ids, .warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page, - }) catch |err| switch (err) { + }, &env_map) catch |err| switch (err) { error.ParseError, error.CompileError => { try error_handler.emitDiagnostics(gpa, Io.Dir.cwd(), final_input, &diagnostics, mapping_results.mappings); // Delete the output file on error diff --git a/lib/compiler/resinator/preprocess.zig b/lib/compiler/resinator/preprocess.zig index a67721a7e1..39e01f2f41 100644 --- a/lib/compiler/resinator/preprocess.zig +++ b/lib/compiler/resinator/preprocess.zig @@ -86,7 +86,7 @@ fn hasAnyErrors(comp: *aro.Compilation) bool { /// `arena` is used for temporary -D argument strings and the INCLUDE environment variable. /// The arena should be kept alive at least as long as `argv`. -pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options: cli.Options, system_include_paths: []const []const u8) !void { +pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options: cli.Options, system_include_paths: []const []const u8, env_map: *const std.process.Environ.Map) !void { try argv.appendSlice(arena, &.{ "-E", "--comments", @@ -109,7 +109,7 @@ pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options } if (!options.ignore_include_env_var) { - const INCLUDE = std.process.getEnvVarOwned(arena, "INCLUDE") catch ""; + const INCLUDE = env_map.get("INCLUDE") orelse ""; // The only precedence here is llvm-rc which also uses the platform-specific // delimiter. There's no precedence set by `rc.exe` since it's Windows-only. diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index 0c7f8c10a2..d85c89a627 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -13,6 +13,7 @@ pub fn main(init: std.process.Init) u8 { const gpa = init.gpa; const arena = init.arena.allocator(); const io = init.io; + const env_map = init.env_map; const args = init.minimal.args.toSlice(arena) catch { std.debug.print("ran out of memory allocating arguments\n", .{}); @@ -25,8 +26,8 @@ pub fn main(init: std.process.Init) u8 { zig_integration = true; } - const NO_COLOR = std.zig.EnvVar.NO_COLOR.isSet(init.env_map); - const CLICOLOR_FORCE = std.zig.EnvVar.CLICOLOR_FORCE.isSet(init.env_map); + const NO_COLOR = std.zig.EnvVar.NO_COLOR.isSet(env_map); + const CLICOLOR_FORCE = std.zig.EnvVar.CLICOLOR_FORCE.isSet(env_map); var stderr_buf: [1024]u8 = undefined; var stderr = Io.File.stderr().writer(io, &stderr_buf); @@ -41,7 +42,7 @@ pub fn main(init: std.process.Init) u8 { }; defer diagnostics.deinit(); - var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, Io.Dir.cwd()) catch |err| switch (err) { + var comp = aro.Compilation.initDefault(gpa, arena, io, &diagnostics, .cwd(), env_map) catch |err| switch (err) { error.OutOfMemory => { std.debug.print("ran out of memory initializing C compilation\n", .{}); if (fast_exit) process.exit(1); @@ -114,43 +115,41 @@ pub const usage = \\ ; -fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8, zig_integration: bool) !void { +fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: []const [:0]const u8, zig_integration: bool) !void { const gpa = d.comp.gpa; const io = d.comp.io; - const aro_args = args: { - var i: usize = 0; - for (args) |arg| { - args[i] = arg; - if (mem.eql(u8, arg, "--help")) { - var stdout_buf: [512]u8 = undefined; - var stdout = Io.File.stdout().writer(io, &stdout_buf); - try stdout.interface.print(usage, .{args[0]}); - try stdout.interface.flush(); - return; - } else if (mem.eql(u8, arg, "--version")) { - var stdout_buf: [512]u8 = undefined; - var stdout = Io.File.stdout().writer(io, &stdout_buf); - // TODO add version - try stdout.interface.writeAll("0.0.0-dev\n"); - try stdout.interface.flush(); - return; - } else if (mem.eql(u8, arg, "--zig-integration")) { - if (i != 1 or !zig_integration) - return d.fatal("--zig-integration must be the first argument", .{}); - } else { - i += 1; - } + var aro_args: std.ArrayList([:0]const u8) = .empty; + defer aro_args.deinit(gpa); + + for (args, 0..) |arg, i| { + if (mem.eql(u8, arg, "--help")) { + var stdout_buf: [512]u8 = undefined; + var stdout = Io.File.stdout().writer(io, &stdout_buf); + try stdout.interface.print(usage, .{args[0]}); + try stdout.interface.flush(); + return; + } else if (mem.eql(u8, arg, "--version")) { + var stdout_buf: [512]u8 = undefined; + var stdout = Io.File.stdout().writer(io, &stdout_buf); + // TODO add version + try stdout.interface.writeAll("0.0.0-dev\n"); + try stdout.interface.flush(); + return; + } else if (mem.eql(u8, arg, "--zig-integration")) { + if (i != 1 or !zig_integration) + return d.fatal("--zig-integration must be the first argument", .{}); + } else { + try aro_args.append(gpa, arg); } - break :args args[0..i]; - }; + } const user_macros = macros: { var macro_buf: std.ArrayList(u8) = .empty; defer macro_buf.deinit(gpa); var discard_buf: [256]u8 = undefined; var discarding: std.Io.Writer.Discarding = .init(&discard_buf); - assert(!try d.parseArgs(&discarding.writer, ¯o_buf, aro_args)); + assert(!try d.parseArgs(&discarding.writer, ¯o_buf, aro_args.items)); if (macro_buf.items.len > std.math.maxInt(u32)) { return d.fatal("user provided macro source exceeded max size", .{}); } diff --git a/test/standalone/child_process/main.zig b/test/standalone/child_process/main.zig index c2ae038f5a..ef933c0abd 100644 --- a/test/standalone/child_process/main.zig +++ b/test/standalone/child_process/main.zig @@ -9,7 +9,7 @@ pub fn main(init: std.process.Init.Minimal) !void { }; const gpa = gpa_state.allocator(); - var it = try init.iterateAllocator(gpa); + var it = try init.args.iterateAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name const child_path, const needs_free = child_path: { @@ -28,11 +28,13 @@ pub fn main(init: std.process.Init.Minimal) !void { defer threaded.deinit(); const io = threaded.io(); - var child = std.process.Child.init(&.{ child_path, "hello arg" }, gpa); - child.stdin_behavior = .pipe; - child.stdout_behavior = .pipe; - child.stderr_behavior = .inherit; - try child.spawn(io); + var child = try std.process.spawn(.{ + .argv = &.{ child_path, "hello arg" }, + .stdin = .pipe, + .stdout = .pipe, + .stderr = .inherit, + }); + const child_stdin = child.stdin.?; try child_stdin.writeStreamingAll(io, "hello from stdin"); // verified in child child_stdin.close(io); @@ -47,7 +49,7 @@ pub fn main(init: std.process.Init.Minimal) !void { } switch (try child.wait(io)) { - .Exited => |code| { + .exited => |code| { const child_ok_code = 42; // set by child if no test errors if (code != child_ok_code) { testError(io, "child exit code: {d}; want {d}", .{ code, child_ok_code }); @@ -60,7 +62,7 @@ pub fn main(init: std.process.Init.Minimal) !void { // Check that FileNotFound is consistent across platforms when trying to spawn an executable that doesn't exist const missing_child_path = try std.mem.concat(gpa, u8, &.{ child_path, "_intentionally_missing" }); defer gpa.free(missing_child_path); - try std.testing.expectError(error.FileNotFound, std.process.Child.run(gpa, io, .{ .argv = &.{missing_child_path} })); + try std.testing.expectError(error.FileNotFound, std.process.run(gpa, io, .{ .argv = &.{missing_child_path} })); } var parent_test_error = false; diff --git a/test/standalone/cmakedefine/check.zig b/test/standalone/cmakedefine/check.zig index c2f89ad112..8db602f39d 100644 --- a/test/standalone/cmakedefine/check.zig +++ b/test/standalone/cmakedefine/check.zig @@ -1,16 +1,12 @@ -pub fn main() !void { - var arena_state: std.heap.ArenaAllocator = .init(std.heap.page_allocator); - defer arena_state.deinit(); - const arena = arena_state.allocator(); - - const args = try std.process.argsAlloc(arena); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); if (args.len != 3) return error.BadUsage; const actual_path = args[1]; const expected_path = args[2]; - const io = std.Io.Threaded.global_single_threaded.ioBasic(); - const actual = try std.Io.Dir.cwd().readFileAlloc(io, actual_path, arena, .limited(1024 * 1024)); const expected = try std.Io.Dir.cwd().readFileAlloc(io, expected_path, arena, .limited(1024 * 1024)); diff --git a/test/standalone/empty_env/main.zig b/test/standalone/empty_env/main.zig index 1dc435d9fa..7a47dd6d3e 100644 --- a/test/standalone/empty_env/main.zig +++ b/test/standalone/empty_env/main.zig @@ -1,8 +1,5 @@ const std = @import("std"); -pub fn main() !void { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - defer _ = gpa.deinit(); - const env_map = std.process.getEnvMap(gpa.allocator()) catch @panic("unable to get env map"); - try std.testing.expect(env_map.count() == 0); +pub fn main(init: std.process.Init) !void { + try std.testing.expect(init.env_map.count() == 0); } diff --git a/test/standalone/entry_point/check_differ.zig b/test/standalone/entry_point/check_differ.zig index 29b333632f..be761d46ed 100644 --- a/test/standalone/entry_point/check_differ.zig +++ b/test/standalone/entry_point/check_differ.zig @@ -1,13 +1,12 @@ -pub fn main() !void { - var arena_state: std.heap.ArenaAllocator = .init(std.heap.page_allocator); - defer arena_state.deinit(); - const arena = arena_state.allocator(); +const std = @import("std"); + +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); - const args = try std.process.argsAlloc(arena); if (args.len != 3) return error.BadUsage; // usage: 'check_differ ' - const io = std.Io.Threaded.global_single_threaded.ioBasic(); - const contents_1 = try std.Io.Dir.cwd().readFileAlloc(io, args[1], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty const contents_2 = try std.Io.Dir.cwd().readFileAlloc(io, args[2], arena, .limited(1024 * 1024 * 64)); // 64 MiB ought to be plenty @@ -16,4 +15,3 @@ pub fn main() !void { } // success, files differ } -const std = @import("std"); diff --git a/test/standalone/env_vars/main.zig b/test/standalone/env_vars/main.zig index 9069f93f42..112c2a8312 100644 --- a/test/standalone/env_vars/main.zig +++ b/test/standalone/env_vars/main.zig @@ -7,145 +7,126 @@ pub fn main(init: std.process.Init) !void { const allocator = init.gpa; const arena = init.arena.allocator(); + const environ = init.minimal.environ; - // hasNonEmptyEnvVar + // containsUnempty { - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "FOO")); - try std.testing.expect(!(try std.process.hasNonEmptyEnvVar(allocator, "FOO="))); - try std.testing.expect(!(try std.process.hasNonEmptyEnvVar(allocator, "FO"))); - try std.testing.expect(!(try std.process.hasNonEmptyEnvVar(allocator, "FOOO"))); + try std.testing.expect(try environ.containsUnempty(allocator, "FOO")); + try std.testing.expect(!(try environ.containsUnempty(allocator, "FOO="))); + try std.testing.expect(!(try environ.containsUnempty(allocator, "FO"))); + try std.testing.expect(!(try environ.containsUnempty(allocator, "FOOO"))); if (builtin.os.tag == .windows) { - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "foo")); + try std.testing.expect(try environ.containsUnempty(allocator, "foo")); } - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "EQUALS")); - try std.testing.expect(!(try std.process.hasNonEmptyEnvVar(allocator, "EQUALS=ABC"))); - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "КИРиллИЦА")); + try std.testing.expect(try environ.containsUnempty(allocator, "EQUALS")); + try std.testing.expect(!(try environ.containsUnempty(allocator, "EQUALS=ABC"))); + try std.testing.expect(try environ.containsUnempty(allocator, "КИРиллИЦА")); if (builtin.os.tag == .windows) { - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "кирИЛЛица")); + try std.testing.expect(try environ.containsUnempty(allocator, "кирИЛЛица")); } - try std.testing.expect(!(try std.process.hasNonEmptyEnvVar(allocator, "NO_VALUE"))); - try std.testing.expect(!(try std.process.hasNonEmptyEnvVar(allocator, "NOT_SET"))); + try std.testing.expect(!(try environ.containsUnempty(allocator, "NO_VALUE"))); + try std.testing.expect(!(try environ.containsUnempty(allocator, "NOT_SET"))); if (builtin.os.tag == .windows) { - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "=HIDDEN")); - try std.testing.expect(try std.process.hasNonEmptyEnvVar(allocator, "INVALID_UTF16_\xed\xa0\x80")); + try std.testing.expect(try environ.containsUnempty(allocator, "=HIDDEN")); + try std.testing.expect(try environ.containsUnempty(allocator, "INVALID_UTF16_\xed\xa0\x80")); } } - // hasNonEmptyEnvVarContstant + // containsUnemptyConstant { - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("FOO")); - try std.testing.expect(!std.process.hasNonEmptyEnvVarConstant("FOO=")); - try std.testing.expect(!std.process.hasNonEmptyEnvVarConstant("FO")); - try std.testing.expect(!std.process.hasNonEmptyEnvVarConstant("FOOO")); + try std.testing.expect(environ.containsUnemptyConstant("FOO")); + try std.testing.expect(!environ.containsUnemptyConstant("FOO=")); + try std.testing.expect(!environ.containsUnemptyConstant("FO")); + try std.testing.expect(!environ.containsUnemptyConstant("FOOO")); if (builtin.os.tag == .windows) { - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("foo")); + try std.testing.expect(environ.containsUnemptyConstant("foo")); } - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("EQUALS")); - try std.testing.expect(!std.process.hasNonEmptyEnvVarConstant("EQUALS=ABC")); - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("КИРиллИЦА")); + try std.testing.expect(environ.containsUnemptyConstant("EQUALS")); + try std.testing.expect(!environ.containsUnemptyConstant("EQUALS=ABC")); + try std.testing.expect(environ.containsUnemptyConstant("КИРиллИЦА")); if (builtin.os.tag == .windows) { - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("кирИЛЛица")); + try std.testing.expect(environ.containsUnemptyConstant("кирИЛЛица")); } - try std.testing.expect(!(std.process.hasNonEmptyEnvVarConstant("NO_VALUE"))); - try std.testing.expect(!(std.process.hasNonEmptyEnvVarConstant("NOT_SET"))); + try std.testing.expect(!(environ.containsUnemptyConstant("NO_VALUE"))); + try std.testing.expect(!(environ.containsUnemptyConstant("NOT_SET"))); if (builtin.os.tag == .windows) { - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("=HIDDEN")); - try std.testing.expect(std.process.hasNonEmptyEnvVarConstant("INVALID_UTF16_\xed\xa0\x80")); + try std.testing.expect(environ.containsUnemptyConstant("=HIDDEN")); + try std.testing.expect(environ.containsUnemptyConstant("INVALID_UTF16_\xed\xa0\x80")); } } - // hasEnvVar + // contains { - try std.testing.expect(try std.process.hasEnvVar(allocator, "FOO")); - try std.testing.expect(!(try std.process.hasEnvVar(allocator, "FOO="))); - try std.testing.expect(!(try std.process.hasEnvVar(allocator, "FO"))); - try std.testing.expect(!(try std.process.hasEnvVar(allocator, "FOOO"))); + try std.testing.expect(try environ.contains(allocator, "FOO")); + try std.testing.expect(!(try environ.contains(allocator, "FOO="))); + try std.testing.expect(!(try environ.contains(allocator, "FO"))); + try std.testing.expect(!(try environ.contains(allocator, "FOOO"))); if (builtin.os.tag == .windows) { - try std.testing.expect(try std.process.hasEnvVar(allocator, "foo")); + try std.testing.expect(try environ.contains(allocator, "foo")); } - try std.testing.expect(try std.process.hasEnvVar(allocator, "EQUALS")); - try std.testing.expect(!(try std.process.hasEnvVar(allocator, "EQUALS=ABC"))); - try std.testing.expect(try std.process.hasEnvVar(allocator, "КИРиллИЦА")); + try std.testing.expect(try environ.contains(allocator, "EQUALS")); + try std.testing.expect(!(try environ.contains(allocator, "EQUALS=ABC"))); + try std.testing.expect(try environ.contains(allocator, "КИРиллИЦА")); if (builtin.os.tag == .windows) { - try std.testing.expect(try std.process.hasEnvVar(allocator, "кирИЛЛица")); + try std.testing.expect(try environ.contains(allocator, "кирИЛЛица")); } - try std.testing.expect(try std.process.hasEnvVar(allocator, "NO_VALUE")); - try std.testing.expect(!(try std.process.hasEnvVar(allocator, "NOT_SET"))); + try std.testing.expect(try environ.contains(allocator, "NO_VALUE")); + try std.testing.expect(!(try environ.contains(allocator, "NOT_SET"))); if (builtin.os.tag == .windows) { - try std.testing.expect(try std.process.hasEnvVar(allocator, "=HIDDEN")); - try std.testing.expect(try std.process.hasEnvVar(allocator, "INVALID_UTF16_\xed\xa0\x80")); + try std.testing.expect(try environ.contains(allocator, "=HIDDEN")); + try std.testing.expect(try environ.contains(allocator, "INVALID_UTF16_\xed\xa0\x80")); } } - // hasEnvVarConstant + // containsConstant { - try std.testing.expect(std.process.hasEnvVarConstant("FOO")); - try std.testing.expect(!std.process.hasEnvVarConstant("FOO=")); - try std.testing.expect(!std.process.hasEnvVarConstant("FO")); - try std.testing.expect(!std.process.hasEnvVarConstant("FOOO")); + try std.testing.expect(environ.containsConstant("FOO")); + try std.testing.expect(!environ.containsConstant("FOO=")); + try std.testing.expect(!environ.containsConstant("FO")); + try std.testing.expect(!environ.containsConstant("FOOO")); if (builtin.os.tag == .windows) { - try std.testing.expect(std.process.hasEnvVarConstant("foo")); + try std.testing.expect(environ.containsConstant("foo")); } - try std.testing.expect(std.process.hasEnvVarConstant("EQUALS")); - try std.testing.expect(!std.process.hasEnvVarConstant("EQUALS=ABC")); - try std.testing.expect(std.process.hasEnvVarConstant("КИРиллИЦА")); + try std.testing.expect(environ.containsConstant("EQUALS")); + try std.testing.expect(!environ.containsConstant("EQUALS=ABC")); + try std.testing.expect(environ.containsConstant("КИРиллИЦА")); if (builtin.os.tag == .windows) { - try std.testing.expect(std.process.hasEnvVarConstant("кирИЛЛица")); + try std.testing.expect(environ.containsConstant("кирИЛЛица")); } - try std.testing.expect(std.process.hasEnvVarConstant("NO_VALUE")); - try std.testing.expect(!(std.process.hasEnvVarConstant("NOT_SET"))); + try std.testing.expect(environ.containsConstant("NO_VALUE")); + try std.testing.expect(!(environ.containsConstant("NOT_SET"))); if (builtin.os.tag == .windows) { - try std.testing.expect(std.process.hasEnvVarConstant("=HIDDEN")); - try std.testing.expect(std.process.hasEnvVarConstant("INVALID_UTF16_\xed\xa0\x80")); + try std.testing.expect(environ.containsConstant("=HIDDEN")); + try std.testing.expect(environ.containsConstant("INVALID_UTF16_\xed\xa0\x80")); } } - // getEnvVarOwned + // getAlloc { - try std.testing.expectEqualSlices(u8, "123", try std.process.getEnvVarOwned(arena, "FOO")); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.getEnvVarOwned(arena, "FOO=")); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.getEnvVarOwned(arena, "FO")); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.getEnvVarOwned(arena, "FOOO")); + try std.testing.expectEqualSlices(u8, "123", try environ.getAlloc(arena, "FOO")); + try std.testing.expectError(error.EnvironmentVariableNotFound, environ.getAlloc(arena, "FOO=")); + try std.testing.expectError(error.EnvironmentVariableNotFound, environ.getAlloc(arena, "FO")); + try std.testing.expectError(error.EnvironmentVariableNotFound, environ.getAlloc(arena, "FOOO")); if (builtin.os.tag == .windows) { - try std.testing.expectEqualSlices(u8, "123", try std.process.getEnvVarOwned(arena, "foo")); + try std.testing.expectEqualSlices(u8, "123", try environ.getAlloc(arena, "foo")); } - try std.testing.expectEqualSlices(u8, "ABC=123", try std.process.getEnvVarOwned(arena, "EQUALS")); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.getEnvVarOwned(arena, "EQUALS=ABC")); - try std.testing.expectEqualSlices(u8, "non-ascii አማርኛ \u{10FFFF}", try std.process.getEnvVarOwned(arena, "КИРиллИЦА")); + try std.testing.expectEqualSlices(u8, "ABC=123", try environ.getAlloc(arena, "EQUALS")); + try std.testing.expectError(error.EnvironmentVariableNotFound, environ.getAlloc(arena, "EQUALS=ABC")); + try std.testing.expectEqualSlices(u8, "non-ascii አማርኛ \u{10FFFF}", try environ.getAlloc(arena, "КИРиллИЦА")); if (builtin.os.tag == .windows) { - try std.testing.expectEqualSlices(u8, "non-ascii አማርኛ \u{10FFFF}", try std.process.getEnvVarOwned(arena, "кирИЛЛица")); + try std.testing.expectEqualSlices(u8, "non-ascii አማርኛ \u{10FFFF}", try environ.getAlloc(arena, "кирИЛЛица")); } - try std.testing.expectEqualSlices(u8, "", try std.process.getEnvVarOwned(arena, "NO_VALUE")); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.getEnvVarOwned(arena, "NOT_SET")); + try std.testing.expectEqualSlices(u8, "", try environ.getAlloc(arena, "NO_VALUE")); + try std.testing.expectError(error.EnvironmentVariableNotFound, environ.getAlloc(arena, "NOT_SET")); if (builtin.os.tag == .windows) { - try std.testing.expectEqualSlices(u8, "hi", try std.process.getEnvVarOwned(arena, "=HIDDEN")); - try std.testing.expectEqualSlices(u8, "\xed\xa0\x80", try std.process.getEnvVarOwned(arena, "INVALID_UTF16_\xed\xa0\x80")); + try std.testing.expectEqualSlices(u8, "hi", try environ.getAlloc(arena, "=HIDDEN")); + try std.testing.expectEqualSlices(u8, "\xed\xa0\x80", try environ.getAlloc(arena, "INVALID_UTF16_\xed\xa0\x80")); } } - // parseEnvVarInt + // Environ.Map { - try std.testing.expectEqual(123, try std.process.parseEnvVarInt("FOO", u32, 10)); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.parseEnvVarInt("FO", u32, 10)); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.parseEnvVarInt("FOOO", u32, 10)); - try std.testing.expectEqual(0x123, try std.process.parseEnvVarInt("FOO", u32, 16)); - if (builtin.os.tag == .windows) { - try std.testing.expectEqual(123, try std.process.parseEnvVarInt("foo", u32, 10)); - } - try std.testing.expectError(error.InvalidCharacter, std.process.parseEnvVarInt("EQUALS", u32, 10)); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.parseEnvVarInt("EQUALS=ABC", u32, 10)); - try std.testing.expectError(error.InvalidCharacter, std.process.parseEnvVarInt("КИРиллИЦА", u32, 10)); - try std.testing.expectError(error.InvalidCharacter, std.process.parseEnvVarInt("NO_VALUE", u32, 10)); - try std.testing.expectError(error.EnvironmentVariableNotFound, std.process.parseEnvVarInt("NOT_SET", u32, 10)); - if (builtin.os.tag == .windows) { - try std.testing.expectError(error.InvalidCharacter, std.process.parseEnvVarInt("=HIDDEN", u32, 10)); - try std.testing.expectError(error.InvalidCharacter, std.process.parseEnvVarInt("INVALID_UTF16_\xed\xa0\x80", u32, 10)); - } - } - - // EnvMap - { - var env_map = try std.process.getEnvMap(allocator); + var env_map = try environ.createMap(allocator); defer env_map.deinit(); try std.testing.expectEqualSlices(u8, "123", env_map.get("FOO").?); diff --git a/test/standalone/posix/getenv.zig b/test/standalone/posix/getenv.zig index 8b28d09ae7..ea4f9c4877 100644 --- a/test/standalone/posix/getenv.zig +++ b/test/standalone/posix/getenv.zig @@ -1,9 +1,9 @@ -// test getting environment variables +//! test getting environment variables const std = @import("std"); const builtin = @import("builtin"); -pub fn main() !void { +pub fn main(init: std.process.Init.Minimal) !void { if (builtin.target.os.tag == .windows) { return; // Windows env strings are WTF-16, so not supported by Zig's std.posix.getenv() } @@ -12,21 +12,22 @@ pub fn main() !void { return; // std.posix.getenv is not supported on WASI due to the need of allocation } - // Test some unset env vars: + const environ = init.environ; - try std.testing.expectEqual(std.posix.getenv(""), null); - try std.testing.expectEqual(std.posix.getenv("BOGUSDOESNOTEXISTENVVAR"), null); - try std.testing.expectEqual(std.posix.getenvZ("BOGUSDOESNOTEXISTENVVAR"), null); + // Test some unset env vars: + try std.testing.expectEqual(environ.getPosix(""), null); + try std.testing.expectEqual(environ.getPosix("BOGUSDOESNOTEXISTENVVAR"), null); + try std.testing.expectEqual(environ.getPosix("BOGUSDOESNOTEXISTENVVAR"), null); if (builtin.link_libc) { // Test if USER matches what C library sees const expected = std.mem.span(std.c.getenv("USER") orelse ""); - const actual = std.posix.getenv("USER") orelse ""; + const actual = environ.getPosix("USER") orelse ""; try std.testing.expectEqualStrings(expected, actual); } // env vars set by our build.zig run step: - try std.testing.expectEqualStrings("", std.posix.getenv("ZIG_TEST_POSIX_EMPTY") orelse "invalid"); - try std.testing.expectEqualStrings("test=variable", std.posix.getenv("ZIG_TEST_POSIX_1EQ") orelse "invalid"); - try std.testing.expectEqualStrings("=test=variable=", std.posix.getenv("ZIG_TEST_POSIX_3EQ") orelse "invalid"); + try std.testing.expectEqualStrings("", environ.getPosix("ZIG_TEST_POSIX_EMPTY") orelse "invalid"); + try std.testing.expectEqualStrings("test=variable", environ.getPosix("ZIG_TEST_POSIX_1EQ") orelse "invalid"); + try std.testing.expectEqualStrings("=test=variable=", environ.getPosix("ZIG_TEST_POSIX_3EQ") orelse "invalid"); } diff --git a/test/standalone/run_output_caching/main.zig b/test/standalone/run_output_caching/main.zig index d7838cab99..8a9855f5ec 100644 --- a/test/standalone/run_output_caching/main.zig +++ b/test/standalone/run_output_caching/main.zig @@ -2,7 +2,7 @@ const std = @import("std"); pub fn main(init: std.process.Init) !void { const io = init.io; - var args = try init.minimal.argsAllocator(init.arena.allocator()); + var args = try init.minimal.args.iterateAllocator(init.arena.allocator()); _ = args.skip(); const filename = args.next().?; const file = try std.Io.Dir.cwd().createFile(io, filename, .{}); diff --git a/test/standalone/run_output_paths/create_file.zig b/test/standalone/run_output_paths/create_file.zig index 5281e6675a..8490c1c5e9 100644 --- a/test/standalone/run_output_paths/create_file.zig +++ b/test/standalone/run_output_paths/create_file.zig @@ -2,7 +2,7 @@ const std = @import("std"); pub fn main(init: std.process.Init) !void { const io = init.io; - var args = try init.args.iterateAllocator(init.arena.allocator()); + var args = try init.minimal.args.iterateAllocator(init.arena.allocator()); _ = args.skip(); const dir_name = args.next().?; const dir = try std.Io.Dir.cwd().openDir(io, if (std.mem.startsWith(u8, dir_name, "--dir=")) diff --git a/test/standalone/self_exe_symlink/create-symlink.zig b/test/standalone/self_exe_symlink/create-symlink.zig index cf6a1c81dd..3de4f8a69d 100644 --- a/test/standalone/self_exe_symlink/create-symlink.zig +++ b/test/standalone/self_exe_symlink/create-symlink.zig @@ -3,14 +3,16 @@ const std = @import("std"); pub fn main(init: std.process.Init) !void { const io = init.io; const gpa = init.gpa; - var it = try init.args.iterateAllocator(gpa); + var it = try init.minimal.args.iterateAllocator(gpa); defer it.deinit(); _ = it.next() orelse unreachable; // skip binary name const exe_path = it.next() orelse unreachable; const symlink_path = it.next() orelse unreachable; + const cwd = std.process.getCwdAlloc(init.arena.allocator()); + // If `exe_path` is relative to our cwd, we need to convert it to be relative to the dirname of `symlink_path`. - const exe_rel_path = try std.fs.path.relative(gpa, std.fs.path.dirname(symlink_path) orelse ".", exe_path); + const exe_rel_path = try std.fs.path.relative(gpa, cwd, init.env_map, std.fs.path.dirname(symlink_path) orelse ".", exe_path); defer gpa.free(exe_rel_path); try std.Io.Dir.cwd().symLink(io, exe_rel_path, symlink_path, .{}); diff --git a/test/standalone/self_exe_symlink/main.zig b/test/standalone/self_exe_symlink/main.zig index fa2c3380b5..0b1704b18a 100644 --- a/test/standalone/self_exe_symlink/main.zig +++ b/test/standalone/self_exe_symlink/main.zig @@ -1,13 +1,8 @@ const std = @import("std"); -pub fn main() !void { - var debug_allocator: std.heap.DebugAllocator(.{}) = .init; - defer if (debug_allocator.deinit() == .leak) @panic("found memory leaks"); - const gpa = debug_allocator.allocator(); - - var threaded: std.Io.Threaded = .init(gpa, .{}); - defer threaded.deinit(); - const io = threaded.io(); +pub fn main(init: std.process.Init) !void { + const gpa = init.gpa; + const io = init.io; const self_path = try std.process.executablePathAlloc(io, gpa); defer gpa.free(self_path); diff --git a/test/standalone/simple/cat/main.zig b/test/standalone/simple/cat/main.zig index adab3aead8..bc894d3881 100644 --- a/test/standalone/simple/cat/main.zig +++ b/test/standalone/simple/cat/main.zig @@ -7,7 +7,7 @@ const fatal = std.process.fatal; pub fn main(init: std.process.Init) !void { const arena = init.arena.allocator(); const io = init.io; - const args = try init.args.toSlice(arena); + const args = try init.minimal.args.toSlice(arena); const exe = args[0]; var catted_anything = false; diff --git a/test/standalone/simple/guess_number/main.zig b/test/standalone/simple/guess_number/main.zig index b98d109f21..e7b30867ec 100644 --- a/test/standalone/simple/guess_number/main.zig +++ b/test/standalone/simple/guess_number/main.zig @@ -1,22 +1,11 @@ -const builtin = @import("builtin"); const std = @import("std"); -// See https://github.com/ziglang/zig/issues/24510 -// for the plan to simplify this code. -pub fn main() !void { - var debug_allocator: std.heap.DebugAllocator(.{}) = .init; - defer _ = debug_allocator.deinit(); - const gpa = debug_allocator.allocator(); - - var threaded: std.Io.Threaded = .init(gpa, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - var stdout_writer = std.Io.File.stdout().writerStreaming(io, &.{}); +pub fn main(init: std.process.Init) !void { + var stdout_writer = std.Io.File.stdout().writerStreaming(init.io, &.{}); const out = &stdout_writer.interface; var line_buffer: [20]u8 = undefined; - var stdin_reader: std.Io.File.Reader = .init(.stdin(), io, &line_buffer); + var stdin_reader: std.Io.File.Reader = .init(.stdin(), init.io, &line_buffer); const in = &stdin_reader.interface; try out.writeAll("Welcome to the Guess Number Game in Zig.\n"); diff --git a/test/standalone/windows_bat_args/fuzz.zig b/test/standalone/windows_bat_args/fuzz.zig index 123c0be314..0f29f40398 100644 --- a/test/standalone/windows_bat_args/fuzz.zig +++ b/test/standalone/windows_bat_args/fuzz.zig @@ -93,7 +93,7 @@ fn testExecBat(gpa: Allocator, io: Io, bat: []const u8, args: []const []const u8 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat"); - const result = try std.process.Child.run(gpa, io, .{ + const result = try std.process.run(gpa, io, .{ .env_map = env, .argv = argv, }); diff --git a/test/standalone/windows_bat_args/test.zig b/test/standalone/windows_bat_args/test.zig index 38ecb5e2f8..c184192599 100644 --- a/test/standalone/windows_bat_args/test.zig +++ b/test/standalone/windows_bat_args/test.zig @@ -140,7 +140,7 @@ fn testExecBat(gpa: Allocator, io: Io, bat: []const u8, args: []const []const u8 const can_have_trailing_empty_args = std.mem.eql(u8, bat, "args3.bat"); - const result = try std.process.Child.run(gpa, io, .{ + const result = try std.process.run(gpa, io, .{ .env_map = env, .argv = argv, }); diff --git a/test/standalone/windows_paths/test.zig b/test/standalone/windows_paths/test.zig index 1fbdca2115..b874dea3e9 100644 --- a/test/standalone/windows_paths/test.zig +++ b/test/standalone/windows_paths/test.zig @@ -98,7 +98,7 @@ fn checkRelative( cwd: ?[]const u8, env_map: ?*const std.process.Environ.Map, ) !void { - const result = try std.process.Child.run(allocator, io, .{ + const result = try std.process.run(allocator, io, .{ .argv = argv, .cwd = cwd, .env_map = env_map, diff --git a/test/standalone/windows_spawn/main.zig b/test/standalone/windows_spawn/main.zig index 32db164a5a..b1fba1bed6 100644 --- a/test/standalone/windows_spawn/main.zig +++ b/test/standalone/windows_spawn/main.zig @@ -207,7 +207,7 @@ fn testExec(gpa: Allocator, io: Io, command: []const u8, expected_stdout: []cons } fn testExecWithCwd(gpa: Allocator, io: Io, command: []const u8, cwd: ?[]const u8, expected_stdout: []const u8) !void { - const result = try std.process.Child.run(gpa, io, .{ + const result = try std.process.run(gpa, io, .{ .argv = &[_][]const u8{command}, .cwd = cwd, }); diff --git a/tools/doctest.zig b/tools/doctest.zig index 44d5954f7e..377de25e93 100644 --- a/tools/doctest.zig +++ b/tools/doctest.zig @@ -193,14 +193,14 @@ fn printOutput( try shell_out.print("\n", .{}); if (expected_outcome == .build_fail) { - const result = try process.Child.run(arena, io, .{ + const result = try process.run(arena, io, .{ .argv = build_args.items, .cwd = tmp_dir_path, .env_map = &env_map, .max_output_bytes = max_doc_file_size, }); switch (result.term) { - .Exited => |exit_code| { + .exited => |exit_code| { if (exit_code == 0) { print("{s}\nThe following command incorrectly succeeded:\n", .{result.stderr}); dumpArgs(build_args.items); @@ -249,21 +249,21 @@ fn printOutput( var exited_with_signal = false; const result = if (expected_outcome == .fail) blk: { - const result = try process.Child.run(arena, io, .{ + const result = try process.run(arena, io, .{ .argv = run_args, .env_map = &env_map, .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { - .Exited => |exit_code| { + .exited => |exit_code| { if (exit_code == 0) { print("{s}\nThe following command incorrectly succeeded:\n", .{result.stderr}); dumpArgs(run_args); fatal("example incorrectly compiled", .{}); } }, - .Signal => exited_with_signal = true, + .signal => exited_with_signal = true, else => {}, } break :blk result; @@ -368,14 +368,14 @@ fn printOutput( try test_args.append("-lc"); try shell_out.print("-lc ", .{}); } - const result = try process.Child.run(arena, io, .{ + const result = try process.run(arena, io, .{ .argv = test_args.items, .env_map = &env_map, .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { - .Exited => |exit_code| { + .exited => |exit_code| { if (exit_code == 0) { print("{s}\nThe following command incorrectly succeeded:\n", .{result.stderr}); dumpArgs(test_args.items); @@ -424,14 +424,14 @@ fn printOutput( }, } - const result = try process.Child.run(arena, io, .{ + const result = try process.run(arena, io, .{ .argv = test_args.items, .env_map = &env_map, .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { - .Exited => |exit_code| { + .exited => |exit_code| { if (exit_code == 0) { print("{s}\nThe following command incorrectly succeeded:\n", .{result.stderr}); dumpArgs(test_args.items); @@ -500,14 +500,14 @@ fn printOutput( } if (maybe_error_match) |error_match| { - const result = try process.Child.run(arena, io, .{ + const result = try process.run(arena, io, .{ .argv = build_args.items, .env_map = &env_map, .cwd = tmp_dir_path, .max_output_bytes = max_doc_file_size, }); switch (result.term) { - .Exited => |exit_code| { + .exited => |exit_code| { if (exit_code == 0) { print("{s}\nThe following command incorrectly succeeded:\n", .{result.stderr}); dumpArgs(build_args.items); @@ -1123,15 +1123,15 @@ fn run( env_map: *process.Environ.Map, cwd: []const u8, args: []const []const u8, -) !process.Child.RunResult { - const result = try process.Child.run(allocator, io, .{ +) !process.RunResult { + const result = try process.run(allocator, io, .{ .argv = args, .env_map = env_map, .cwd = cwd, .max_output_bytes = max_doc_file_size, }); switch (result.term) { - .Exited => |exit_code| { + .exited => |exit_code| { if (exit_code != 0) { std.debug.print("{s}\nThe following command exited with code {}:\n", .{ result.stderr, exit_code }); dumpArgs(args); diff --git a/tools/dump-cov.zig b/tools/dump-cov.zig index b264f8d032..4a54d9f519 100644 --- a/tools/dump-cov.zig +++ b/tools/dump-cov.zig @@ -10,9 +10,9 @@ const SeenPcsHeader = std.Build.abi.fuzz.SeenPcsHeader; pub fn main(init: std.process.Init) !void { const gpa = init.gpa; - const arena = init.arena; + const arena = init.arena.allocator(); const io = init.io; - const args = try init.args.toSlice(arena); + const args = try init.minimal.args.toSlice(arena); const target_query_str = switch (args.len) { 3 => "native", diff --git a/tools/fetch_them_macos_headers.zig b/tools/fetch_them_macos_headers.zig index d52ac9173a..c0d41b85ae 100644 --- a/tools/fetch_them_macos_headers.zig +++ b/tools/fetch_them_macos_headers.zig @@ -68,7 +68,7 @@ const usage = pub fn main(init: std.process.Init) !void { const allocator = init.arena; - const args = try init.args.toSlice(allocator); + const args = try init.minimal.args.toSlice(allocator); var argv = std.array_list.Managed([]const u8).init(allocator); var sysroot: ?[]const u8 = null; @@ -161,7 +161,7 @@ fn fetchTarget( }); try cc_argv.appendSlice(args); - const res = try std.process.Child.run(arena, io, .{ .argv = cc_argv.items }); + const res = try std.process.run(arena, io, .{ .argv = cc_argv.items }); if (res.stderr.len != 0) { std.log.err("{s}", .{res.stderr}); diff --git a/tools/gen_macos_headers_c.zig b/tools/gen_macos_headers_c.zig index 960b480b15..393e17f321 100644 --- a/tools/gen_macos_headers_c.zig +++ b/tools/gen_macos_headers_c.zig @@ -16,8 +16,8 @@ const usage = pub fn main(init: std.process.Init) !void { const arena = init.arena; const io = init.io; + const args = try init.minimal.args.toSlice(arena); - const args = try init.args.toSlice(arena); if (args.len == 1) fatal("no command or option specified", .{}); var positionals = std.array_list.Managed([]const u8).init(arena); diff --git a/tools/gen_outline_atomics.zig b/tools/gen_outline_atomics.zig index 3a33c333d5..bd36484e1e 100644 --- a/tools/gen_outline_atomics.zig +++ b/tools/gen_outline_atomics.zig @@ -12,7 +12,7 @@ const AtomicOp = enum { }; pub fn main(init: std.process.Init) !void { - const arena = init.arena; + const arena = init.arena.allocator(); const io = init.io; //const args = try std.process.argsAlloc(arena); diff --git a/tools/gen_spirv_spec.zig b/tools/gen_spirv_spec.zig index e96c98b6c0..f53b10cbb1 100644 --- a/tools/gen_spirv_spec.zig +++ b/tools/gen_spirv_spec.zig @@ -1,6 +1,7 @@ const std = @import("std"); const Io = std.Io; const Allocator = std.mem.Allocator; +const assert = std.debug.assert; const g = @import("spirv/grammar.zig"); const CoreRegistry = g.CoreRegistry; @@ -54,28 +55,22 @@ const set_names = std.StaticStringMap(struct { []const u8, []const u8 }).initCom .{ "zig", .{ "zig", "Zig" } }, }); -var arena = std.heap.ArenaAllocator.init(std.heap.smp_allocator); -const allocator = arena.allocator(); - -pub fn main() !void { - defer arena.deinit(); - - const args = try std.process.argsAlloc(allocator); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const args = try init.minimal.args.toSlice(arena); if (args.len != 3) { usageAndExit(args[0], 1); } - var threaded: std.Io.Threaded = .init(allocator, .{}); - defer threaded.deinit(); - const io = threaded.io(); + const io = init.io; - const json_path = try Io.Dir.path.join(allocator, &.{ args[1], "include/spirv/unified1/" }); + const json_path = try Io.Dir.path.join(arena, &.{ args[1], "include/spirv/unified1/" }); const dir = try Io.Dir.cwd().openDir(io, json_path, .{ .iterate = true }); - const core_spec = try readRegistry(io, CoreRegistry, dir, "spirv.core.grammar.json"); + const core_spec = try readRegistry(io, arena, CoreRegistry, dir, "spirv.core.grammar.json"); std.mem.sortUnstable(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt); - var exts = std.array_list.Managed(Extension).init(allocator); + var exts = std.array_list.Managed(Extension).init(arena); var it = dir.iterate(); while (try it.next(io)) |entry| { @@ -83,48 +78,48 @@ pub fn main() !void { continue; } - try readExtRegistry(io, &exts, dir, entry.name); + try readExtRegistry(io, arena, &exts, dir, entry.name); } - try readExtRegistry(io, &exts, Io.Dir.cwd(), args[2]); + try readExtRegistry(io, arena, &exts, Io.Dir.cwd(), args[2]); - var allocating: std.Io.Writer.Allocating = .init(allocator); + var allocating: std.Io.Writer.Allocating = .init(arena); defer allocating.deinit(); - try render(&allocating.writer, core_spec, exts.items); + try render(arena, &allocating.writer, core_spec, exts.items); try allocating.writer.writeByte(0); const output = allocating.written()[0 .. allocating.written().len - 1 :0]; - var tree = try std.zig.Ast.parse(allocator, output, .zig); + var tree = try std.zig.Ast.parse(arena, output, .zig); if (tree.errors.len != 0) { - try std.zig.printAstErrorsToStderr(allocator, io, tree, "", .auto); + try std.zig.printAstErrorsToStderr(arena, io, tree, "", .auto); return; } - var zir = try std.zig.AstGen.generate(allocator, tree); + var zir = try std.zig.AstGen.generate(arena, tree); if (zir.hasCompileErrors()) { var wip_errors: std.zig.ErrorBundle.Wip = undefined; - try wip_errors.init(allocator); + try wip_errors.init(arena); defer wip_errors.deinit(); try wip_errors.addZirErrorMessages(zir, tree, output, ""); var error_bundle = try wip_errors.toOwnedBundle(""); - defer error_bundle.deinit(allocator); + defer error_bundle.deinit(arena); try error_bundle.renderToStderr(io, .{}, .auto); } - const formatted_output = try tree.renderAlloc(allocator); + const formatted_output = try tree.renderAlloc(arena); try Io.File.stdout().writeStreamingAll(io, formatted_output); } -fn readExtRegistry(io: Io, exts: *std.array_list.Managed(Extension), dir: Io.Dir, sub_path: []const u8) !void { +fn readExtRegistry(io: Io, arena: Allocator, exts: *std.array_list.Managed(Extension), dir: Io.Dir, sub_path: []const u8) !void { const filename = Io.Dir.path.basename(sub_path); if (!std.mem.startsWith(u8, filename, "extinst.")) { return; } - std.debug.assert(std.mem.endsWith(u8, filename, ".grammar.json")); + assert(std.mem.endsWith(u8, filename, ".grammar.json")); const name = filename["extinst.".len .. filename.len - ".grammar.json".len]; - const spec = try readRegistry(io, ExtensionRegistry, dir, sub_path); + const spec = try readRegistry(io, arena, ExtensionRegistry, dir, sub_path); const set_name = set_names.get(name) orelse { std.log.info("ignored instruction set '{s}'", .{name}); @@ -140,16 +135,16 @@ fn readExtRegistry(io: Io, exts: *std.array_list.Managed(Extension), dir: Io.Dir }); } -fn readRegistry(io: Io, comptime RegistryType: type, dir: Io.Dir, path: []const u8) !RegistryType { - const spec = try dir.readFileAlloc(io, path, allocator, .unlimited); +fn readRegistry(io: Io, arena: Allocator, comptime RegistryType: type, dir: Io.Dir, path: []const u8) !RegistryType { + const spec = try dir.readFileAlloc(io, path, arena, .unlimited); // Required for json parsing. // TODO: ALI @setEvalBranchQuota(10000); - var scanner = std.json.Scanner.initCompleteInput(allocator, spec); + var scanner = std.json.Scanner.initCompleteInput(arena, spec); var diagnostics = std.json.Diagnostics{}; scanner.enableDiagnostics(&diagnostics); - const parsed = std.json.parseFromTokenSource(RegistryType, allocator, &scanner, .{}) catch |err| { + const parsed = std.json.parseFromTokenSource(RegistryType, arena, &scanner, .{}) catch |err| { std.debug.print("{s}:{}:{}:\n", .{ path, diagnostics.getLine(), diagnostics.getColumn() }); return err; }; @@ -158,8 +153,8 @@ fn readRegistry(io: Io, comptime RegistryType: type, dir: Io.Dir, path: []const /// Returns a set with types that require an extra struct for the `Instruction` interface /// to the spir-v spec, or whether the original type can be used. -fn extendedStructs(kinds: []const OperandKind) !ExtendedStructSet { - var map = ExtendedStructSet.init(allocator); +fn extendedStructs(arena: Allocator, kinds: []const OperandKind) !ExtendedStructSet { + var map = ExtendedStructSet.init(arena); try map.ensureTotalCapacity(@as(u32, @intCast(kinds.len))); for (kinds) |kind| { @@ -194,6 +189,7 @@ fn tagPriorityScore(tag: []const u8) usize { } fn render( + arena: Allocator, writer: *std.Io.Writer, registry: CoreRegistry, extensions: []const Extension, @@ -299,7 +295,7 @@ fn render( ); // Merge the operand kinds from all extensions together. - var all_operand_kinds = OperandKindMap.init(allocator); + var all_operand_kinds = OperandKindMap.init(arena); for (registry.operand_kinds) |kind| { try all_operand_kinds.putNoClobber(.{ "core", kind.kind }, kind); } @@ -312,22 +308,22 @@ fn render( try all_operand_kinds.ensureUnusedCapacity(ext.spec.operand_kinds.len); for (ext.spec.operand_kinds) |kind| { var new_kind = kind; - new_kind.kind = try std.mem.join(allocator, ".", &.{ ext.name, kind.kind }); + new_kind.kind = try std.mem.join(arena, ".", &.{ ext.name, kind.kind }); try all_operand_kinds.putNoClobber(.{ ext.name, kind.kind }, new_kind); } } - const extended_structs = try extendedStructs(all_operand_kinds.values()); + const extended_structs = try extendedStructs(arena, all_operand_kinds.values()); // Note: extensions don't seem to have class. - try renderClass(writer, registry.instructions); + try renderClass(arena, writer, registry.instructions); try renderOperandKind(writer, all_operand_kinds.values()); - try renderOpcodes(writer, "Opcode", true, registry.instructions, extended_structs); + try renderOpcodes(arena, writer, "Opcode", true, registry.instructions, extended_structs); for (extensions) |ext| { - try renderOpcodes(writer, ext.opcode_name, false, ext.spec.instructions, extended_structs); + try renderOpcodes(arena, writer, ext.opcode_name, false, ext.spec.instructions, extended_structs); } - try renderOperandKinds(writer, all_operand_kinds.values(), extended_structs); + try renderOperandKinds(arena, writer, all_operand_kinds.values(), extended_structs); try renderInstructionSet(writer, registry, extensions, all_operand_kinds); } @@ -414,8 +410,8 @@ fn renderInstructionsCase( ); } -fn renderClass(writer: *std.Io.Writer, instructions: []const Instruction) !void { - var class_map = std.StringArrayHashMap(void).init(allocator); +fn renderClass(arena: Allocator, writer: *std.Io.Writer, instructions: []const Instruction) !void { + var class_map = std.StringArrayHashMap(void).init(arena); for (instructions) |inst| { if (std.mem.eql(u8, inst.class.?, "@exclude")) continue; @@ -535,16 +531,17 @@ fn renderEnumerant(writer: *std.Io.Writer, enumerant: Enumerant) !void { } fn renderOpcodes( + arena: Allocator, writer: *std.Io.Writer, opcode_type_name: []const u8, want_operands: bool, instructions: []const Instruction, extended_structs: ExtendedStructSet, ) !void { - var inst_map = std.AutoArrayHashMap(u32, usize).init(allocator); + var inst_map = std.AutoArrayHashMap(u32, usize).init(arena); try inst_map.ensureTotalCapacity(instructions.len); - var aliases = std.array_list.Managed(struct { inst: usize, alias: usize }).init(allocator); + var aliases = std.array_list.Managed(struct { inst: usize, alias: usize }).init(arena); try aliases.ensureTotalCapacity(instructions.len); for (instructions, 0..) |inst, i| { @@ -634,30 +631,32 @@ fn renderOpcodes( } fn renderOperandKinds( + arena: Allocator, writer: *std.Io.Writer, kinds: []const OperandKind, extended_structs: ExtendedStructSet, ) !void { for (kinds) |kind| { switch (kind.category) { - .ValueEnum => try renderValueEnum(writer, kind, extended_structs), - .BitEnum => try renderBitEnum(writer, kind, extended_structs), + .ValueEnum => try renderValueEnum(arena, writer, kind, extended_structs), + .BitEnum => try renderBitEnum(arena, writer, kind, extended_structs), else => {}, } } } fn renderValueEnum( + arena: Allocator, writer: *std.Io.Writer, enumeration: OperandKind, extended_structs: ExtendedStructSet, ) !void { const enumerants = enumeration.enumerants orelse return error.InvalidRegistry; - var enum_map = std.AutoArrayHashMap(u32, usize).init(allocator); + var enum_map = std.AutoArrayHashMap(u32, usize).init(arena); try enum_map.ensureTotalCapacity(enumerants.len); - var aliases = std.array_list.Managed(struct { enumerant: usize, alias: usize }).init(allocator); + var aliases = std.array_list.Managed(struct { enumerant: usize, alias: usize }).init(arena); try aliases.ensureTotalCapacity(enumerants.len); for (enumerants, 0..) |enumerant, i| { @@ -726,6 +725,7 @@ fn renderValueEnum( } fn renderBitEnum( + arena: Allocator, writer: *std.Io.Writer, enumeration: OperandKind, extended_structs: ExtendedStructSet, @@ -735,7 +735,7 @@ fn renderBitEnum( var flags_by_bitpos = [_]?usize{null} ** 32; const enumerants = enumeration.enumerants orelse return error.InvalidRegistry; - var aliases = std.array_list.Managed(struct { flag: usize, alias: u5 }).init(allocator); + var aliases = std.array_list.Managed(struct { flag: usize, alias: u5 }).init(arena); try aliases.ensureTotalCapacity(enumerants.len); for (enumerants, 0..) |enumerant, i| { @@ -749,7 +749,7 @@ fn renderBitEnum( continue; } - std.debug.assert(@popCount(value) == 1); + assert(@popCount(value) == 1); const bitpos = std.math.log2_int(u32, value); if (flags_by_bitpos[bitpos]) |*existing| { diff --git a/tools/gen_stubs.zig b/tools/gen_stubs.zig index 51e83e1a08..bad27fd201 100644 --- a/tools/gen_stubs.zig +++ b/tools/gen_stubs.zig @@ -281,16 +281,10 @@ const Parse = struct { arch: Arch, }; -pub fn main() !void { - var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_instance.deinit(); - const arena = arena_instance.allocator(); - - var threaded: std.Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const args = try std.process.argsAlloc(arena); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); const build_all_path = args[1]; var build_all_dir = try Io.Dir.cwd().openDir(io, build_all_path, .{}); diff --git a/tools/generate_c_size_and_align_checks.zig b/tools/generate_c_size_and_align_checks.zig index 48c35f07d9..6041a550da 100644 --- a/tools/generate_c_size_and_align_checks.zig +++ b/tools/generate_c_size_and_align_checks.zig @@ -29,7 +29,7 @@ fn cName(ty: std.Target.CType) []const u8 { var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init; pub fn main(init: std.process.Init) !void { - const args = try init.args.toSlice(init.arena); + const args = try init.minimal.args.toSlice(init.arena.allocator()); const io = init.io; if (args.len != 2) { diff --git a/tools/generate_linux_syscalls.zig b/tools/generate_linux_syscalls.zig index c9740a7f70..e124a2c84d 100644 --- a/tools/generate_linux_syscalls.zig +++ b/tools/generate_linux_syscalls.zig @@ -174,7 +174,7 @@ pub fn main(init: std.process.Init) !void { const gpa = init.gpa; const io = init.io; - const args = try std.process.argsAlloc(gpa); + const args = try init.minimal.args.toSlice(init.arena.allocator()); if (args.len < 2 or mem.eql(u8, args[1], "--help")) { const stderr = std.debug.lockStderr(&.{}); const w = &stderr.file_writer.interface; diff --git a/tools/incr-check.zig b/tools/incr-check.zig index d9664be710..16f37b1bd0 100644 --- a/tools/incr-check.zig +++ b/tools/incr-check.zig @@ -171,14 +171,6 @@ pub fn main(init: std.process.Init) !void { const zig_prog_node = target_prog_node.start("zig build-exe", 0); defer zig_prog_node.end(); - var child = std.process.Child.init(child_args.items, arena); - child.stdin_behavior = .Pipe; - child.stdout_behavior = .Pipe; - child.stderr_behavior = .Pipe; - child.progress_node = zig_prog_node; - child.cwd_dir = tmp_dir; - child.cwd = tmp_dir_path; - var cc_child_args: std.ArrayList([]const u8) = .empty; if (target.backend == .cbe) { const resolved_cc_zig_exe = if (opt_cc_zig) |cc_zig_exe| @@ -201,6 +193,17 @@ pub fn main(init: std.process.Init) !void { try cc_child_args.append(arena, "-o"); } + var child = std.process.spawn(io, .{ + .argv = child_args.items, + .stdin = .pipe, + .stdout = .pipe, + .stderr = .pipe, + .progress_node = zig_prog_node, + .cwd_dir = tmp_dir, + .cwd = tmp_dir_path, + }); + defer child.kill(io); + var eval: Eval = .{ .arena = arena, .io = io, @@ -219,11 +222,6 @@ pub fn main(init: std.process.Init) !void { .enable_darling = enable_darling, }; - try child.spawn(io); - errdefer { - _ = child.kill(io) catch {}; - } - var poller = Io.poll(arena, Eval.StreamEnum, .{ .stdout = child.stdout.?, .stderr = child.stderr.?, @@ -528,7 +526,7 @@ const Eval = struct { const run_prog_node = prog_node.start("run generated executable", 0); defer run_prog_node.end(); - const result = std.process.Child.run(eval.arena, io, .{ + const result = std.process.run(eval.arena, io, .{ .argv = argv, .cwd_dir = eval.tmp_dir, .cwd = eval.tmp_dir_path, @@ -556,7 +554,7 @@ const Eval = struct { } switch (result.term) { - .Exited => |code| switch (update.outcome) { + .exited => |code| switch (update.outcome) { .unknown, .compile_errors => unreachable, .stdout => |expected_stdout| { if (code != 0) { @@ -564,9 +562,12 @@ const Eval = struct { } try std.testing.expectEqualStrings(expected_stdout, result.stdout); }, - .exit_code => |expected_code| try std.testing.expectEqual(expected_code, result.term.Exited), + .exit_code => |expected_code| try std.testing.expectEqual(expected_code, code), }, - .Signal, .Stopped, .Unknown => { + .signal => |sig| { + eval.fatal("generated executable '{s}' terminated with signal {t}", .{ binary_path, sig }); + }, + .stopped, .unknown => { eval.fatal("generated executable '{s}' terminated unexpectedly", .{binary_path}); }, } @@ -614,7 +615,7 @@ const Eval = struct { try eval.cc_child_args.appendSlice(eval.arena, &.{ out_path, c_path }); defer eval.cc_child_args.items.len -= 2; - const result = std.process.Child.run(eval.arena, eval.io, .{ + const result = std.process.run(eval.arena, eval.io, .{ .argv = eval.cc_child_args.items, .cwd_dir = eval.tmp_dir, .cwd = eval.tmp_dir_path, @@ -623,13 +624,13 @@ const Eval = struct { eval.fatal("failed to spawn zig cc for '{s}': {t}", .{ c_path, err }); }; switch (result.term) { - .Exited => |code| if (code != 0) { + .exited => |code| if (code != 0) { if (result.stderr.len != 0) { std.log.err("zig cc stderr:\n{s}", .{result.stderr}); } eval.fatal("zig cc for '{s}' failed with code {d}", .{ c_path, code }); }, - .Signal, .Stopped, .Unknown => { + .signal, .stopped, .unknown => { if (result.stderr.len != 0) { std.log.err("zig cc stderr:\n{s}", .{result.stderr}); } @@ -909,8 +910,9 @@ fn waitChild(child: *std.process.Child, eval: *Eval) void { requestExit(child, eval); const term = child.wait(io) catch |err| eval.fatal("child process failed: {t}", .{err}); switch (term) { - .Exited => |code| if (code != 0) eval.fatal("compiler failed with code {d}", .{code}), - .Signal, .Stopped, .Unknown => eval.fatal("compiler terminated unexpectedly", .{}), + .exited => |code| if (code != 0) eval.fatal("compiler failed with code {d}", .{code}), + .signal => |sig| eval.fatal("compiler terminated with signal {t}", .{sig}), + .stopped, .unknown => eval.fatal("compiler terminated unexpectedly", .{}), } } diff --git a/tools/migrate_langref.zig b/tools/migrate_langref.zig index 24ddd5941d..581d1294ff 100644 --- a/tools/migrate_langref.zig +++ b/tools/migrate_langref.zig @@ -11,21 +11,14 @@ const fatal = std.process.fatal; const max_doc_file_size = 10 * 1024 * 1024; -pub fn main() !void { - var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_instance.deinit(); - const arena = arena_instance.allocator(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); - const gpa = arena; - - const args = try std.process.argsAlloc(arena); const input_file = args[1]; const output_file = args[2]; - var threaded: std.Io.Threaded = .init(gpa, .{}); - defer threaded.deinit(); - const io = threaded.io(); - var in_file = try Dir.cwd().openFile(io, input_file, .{ .mode = .read_only }); defer in_file.close(io); diff --git a/tools/update-linux-headers.zig b/tools/update-linux-headers.zig index 5091b18dbe..26cf1fd143 100644 --- a/tools/update-linux-headers.zig +++ b/tools/update-linux-headers.zig @@ -141,15 +141,13 @@ const HashToContents = std.StringHashMap(Contents); const TargetToHash = std.ArrayHashMap(DestTarget, []const u8, DestTarget.HashContext, true); 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(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); + const env_map = init.env_map; + const cwd = try std.process.getCwdAlloc(arena); - var threaded: Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - 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; @@ -211,7 +209,7 @@ pub fn main() !void { switch (entry.kind) { .directory => try dir_stack.append(full_path), .file => { - const rel_path = try Dir.path.relative(arena, target_include_dir, full_path); + const rel_path = try Dir.path.relative(arena, cwd, env_map, target_include_dir, full_path); const max_size = 2 * 1024 * 1024 * 1024; const raw_bytes = try Dir.cwd().readFileAlloc(io, full_path, arena, .limited(max_size)); const trimmed = std.mem.trim(u8, raw_bytes, " \r\n\t"); diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index 3c7762bab6..b52267a3fb 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -627,16 +627,10 @@ const cpu_targets = struct { pub const xtensa = std.Target.xtensa; }; -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 threaded: std.Io.Threaded = .init(allocator, .{}); - defer threaded.deinit(); - const io = threaded.io(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const args = try init.minimal.args.toSlice(arena); + const io = init.io; var stdout_buffer: [4000]u8 = undefined; var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); @@ -658,7 +652,7 @@ pub fn main() anyerror!void { const llvm_src_root = args[2]; if (std.mem.startsWith(u8, llvm_src_root, "-")) printUsageAndExit(args[0]); - var llvm_to_zig_cpu_features = std.StringHashMap([]const u8).init(allocator); + var llvm_to_zig_cpu_features = std.StringHashMap([]const u8).init(arena); inline for (@typeInfo(cpu_targets).@"struct".decls) |decl| { const Feature = @field(cpu_targets, decl.name).Feature; @@ -675,12 +669,12 @@ pub fn main() anyerror!void { const child_args = [_][]const u8{ llvm_tblgen_exe, "--dump-json", - try std.fmt.allocPrint(allocator, "{s}/clang/include/clang/Driver/Options.td", .{llvm_src_root}), - try std.fmt.allocPrint(allocator, "-I={s}/llvm/include", .{llvm_src_root}), - try std.fmt.allocPrint(allocator, "-I={s}/clang/include/clang/Driver", .{llvm_src_root}), + try std.fmt.allocPrint(arena, "{s}/clang/include/clang/Driver/Options.td", .{llvm_src_root}), + try std.fmt.allocPrint(arena, "-I={s}/llvm/include", .{llvm_src_root}), + try std.fmt.allocPrint(arena, "-I={s}/clang/include/clang/Driver", .{llvm_src_root}), }; - const child_result = try std.process.Child.run(allocator, io, .{ + const child_result = try std.process.run(arena, io, .{ .argv = &child_args, .max_output_bytes = 100 * 1024 * 1024, }); @@ -688,7 +682,7 @@ pub fn main() anyerror!void { std.debug.print("{s}\n", .{child_result.stderr}); const json_text = switch (child_result.term) { - .Exited => |code| if (code == 0) child_result.stdout else { + .exited => |code| if (code == 0) child_result.stdout else { std.debug.print("llvm-tblgen exited with code {d}\n", .{code}); std.process.exit(1); }, @@ -698,11 +692,11 @@ pub fn main() anyerror!void { }, }; - const parsed = try json.parseFromSlice(json.Value, allocator, json_text, .{}); + const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{}); defer parsed.deinit(); const root_map = &parsed.value.object; - var all_objects = std.array_list.Managed(*json.ObjectMap).init(allocator); + var all_objects = std.array_list.Managed(*json.ObjectMap).init(arena); { var it = root_map.iterator(); it_map: while (it.next()) |kv| { diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig index 6def3db6ba..3041ee6acc 100644 --- a/tools/update_cpu_features.zig +++ b/tools/update_cpu_features.zig @@ -1884,7 +1884,7 @@ const targets = [_]ArchTarget{ }; pub fn main(init: std.process.Init) !void { - const arena = init.arena_allocator.allocator(); + const arena = init.arena.allocator(); const io = init.io; var args = try init.minimal.args.iterateAllocator(arena); @@ -1985,7 +1985,7 @@ fn processOneTarget(io: Io, job: Job) void { }), }; - const child_result = try std.process.Child.run(arena, io, .{ + const child_result = try std.process.run(arena, io, .{ .argv = &child_args, .max_output_bytes = 500 * 1024 * 1024, }); @@ -1995,7 +1995,7 @@ fn processOneTarget(io: Io, job: Job) void { } const json_text = switch (child_result.term) { - .Exited => |code| if (code == 0) child_result.stdout else { + .exited => |code| if (code == 0) child_result.stdout else { std.debug.print("llvm-tblgen exited with code {d}\n", .{code}); std.process.exit(1); }, diff --git a/tools/update_crc_catalog.zig b/tools/update_crc_catalog.zig index 29856aacf8..57eedf375b 100644 --- a/tools/update_crc_catalog.zig +++ b/tools/update_crc_catalog.zig @@ -6,16 +6,14 @@ const ascii = std.ascii; const catalog_txt = @embedFile("crc/catalog.txt"); -pub fn main() anyerror!void { - var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_state.deinit(); - const arena = arena_state.allocator(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); + return @"i like cheese"(arena, io, args); +} - var threaded: Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const args = try std.process.argsAlloc(arena); +fn @"i like cheese"(arena: std.mem.Allocator, io: Io, args: []const []const u8) !void { if (args.len <= 1) printUsageAndExit(args[0]); const zig_src_root = args[1]; diff --git a/tools/update_freebsd_libc.zig b/tools/update_freebsd_libc.zig index d50364351f..c2b251da0f 100644 --- a/tools/update_freebsd_libc.zig +++ b/tools/update_freebsd_libc.zig @@ -12,16 +12,11 @@ const exempt_files = [_][]const u8{ "abilists", }; -pub fn main() !void { - var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_instance.deinit(); - const arena = arena_instance.allocator(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); - var threaded: Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const args = try std.process.argsAlloc(arena); const freebsd_src_path = args[1]; const zig_src_path = args[2]; diff --git a/tools/update_glibc.zig b/tools/update_glibc.zig index 296d677d45..29df298bf6 100644 --- a/tools/update_glibc.zig +++ b/tools/update_glibc.zig @@ -38,16 +38,11 @@ const exempt_extensions = [_][]const u8{ "-2.33.c", }; -pub fn main() !void { - var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_instance.deinit(); - const arena = arena_instance.allocator(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); - var threaded: Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const args = try std.process.argsAlloc(arena); const glibc_src_path = args[1]; const zig_src_path = args[2]; diff --git a/tools/update_mingw.zig b/tools/update_mingw.zig index 678c3dbdca..ad3237d1ff 100644 --- a/tools/update_mingw.zig +++ b/tools/update_mingw.zig @@ -2,16 +2,11 @@ const std = @import("std"); const Io = std.Io; const Dir = std.Io.Dir; -pub fn main() !void { - var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_instance.deinit(); - const arena = arena_instance.allocator(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); - var threaded: Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const args = try std.process.argsAlloc(arena); const zig_src_lib_path = args[1]; const mingw_src_path = args[2]; diff --git a/tools/update_netbsd_libc.zig b/tools/update_netbsd_libc.zig index a5eeca35c7..7a466c3246 100644 --- a/tools/update_netbsd_libc.zig +++ b/tools/update_netbsd_libc.zig @@ -12,16 +12,11 @@ const exempt_files = [_][]const u8{ "abilists", }; -pub fn main() !void { - var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena_instance.deinit(); - const arena = arena_instance.allocator(); +pub fn main(init: std.process.Init) !void { + const arena = init.arena.allocator(); + const io = init.io; + const args = try init.minimal.args.toSlice(arena); - var threaded: Io.Threaded = .init(arena, .{}); - defer threaded.deinit(); - const io = threaded.io(); - - const args = try std.process.argsAlloc(arena); const netbsd_src_path = args[1]; const zig_src_path = args[2];