DoxigAlpha

allocPrintCmd2

Function parameters

Parameters

#
opt_cwd:?[]const u8
opt_env:?*const std.process.EnvMap
argv:[]const []const u8

Type definitions in this namespace

Types

#

Functions in this namespace

Functions

#
make
If the Step's `make` function reports `error.MakeFailed`, it indicates they
dump
For debugging purposes, prints identifying information about this Step.
evalZigProcess
Assumes that argv contains `--listen=-` and that the process being spawned
installFile
Wrapper around `std.fs.Dir.updateFile` that handles verbose and error output.
installDir
Wrapper around `std.fs.Dir.makePathStatus` that handles verbose and error output.
cacheHit
Prefer `cacheHitAndWatch` unless you already added watch inputs
cacheHitAndWatch
Clears previous watch inputs, if any, and then populates watch inputs from
writeManifest
Prefer `writeManifestAndWatch` unless you already added watch inputs
writeManifestAndWatch
Clears previous watch inputs, if any, and then populates watch inputs from
singleUnchangingWatchInput
For steps that have a single input that never changes when re-running `make`.
addWatchInput
Places a *file* dependency on the path.
addDirectoryWatchInput
Any changes inside the directory will trigger invalidation.
addDirectoryWatchInputFromPath
Any changes inside the directory will trigger invalidation.
reset
Implementation detail of file watching and forced rebuilds.
recursiveReset
Implementation detail of file watching.

Source

Implementation

#
pub fn allocPrintCmd2(
    arena: Allocator,
    opt_cwd: ?[]const u8,
    opt_env: ?*const std.process.EnvMap,
    argv: []const []const u8,
) Allocator.Error![]u8 {
    const shell = struct {
        fn escape(writer: *std.Io.Writer, string: []const u8, is_argv0: bool) !void {
            for (string) |c| {
                if (switch (c) {
                    else => true,
                    '%', '+'...':', '@'...'Z', '_', 'a'...'z' => false,
                    '=' => is_argv0,
                }) break;
            } else return writer.writeAll(string);

            try writer.writeByte('"');
            for (string) |c| {
                if (switch (c) {
                    std.ascii.control_code.nul => break,
                    '!', '"', '$', '\\', '`' => true,
                    else => !std.ascii.isPrint(c),
                }) try writer.writeByte('\\');
                switch (c) {
                    std.ascii.control_code.nul => unreachable,
                    std.ascii.control_code.bel => try writer.writeByte('a'),
                    std.ascii.control_code.bs => try writer.writeByte('b'),
                    std.ascii.control_code.ht => try writer.writeByte('t'),
                    std.ascii.control_code.lf => try writer.writeByte('n'),
                    std.ascii.control_code.vt => try writer.writeByte('v'),
                    std.ascii.control_code.ff => try writer.writeByte('f'),
                    std.ascii.control_code.cr => try writer.writeByte('r'),
                    std.ascii.control_code.esc => try writer.writeByte('E'),
                    ' '...'~' => try writer.writeByte(c),
                    else => try writer.print("{o:0>3}", .{c}),
                }
            }
            try writer.writeByte('"');
        }
    };

    var aw: std.Io.Writer.Allocating = .init(arena);
    const writer = &aw.writer;
    if (opt_cwd) |cwd| writer.print("cd {s} && ", .{cwd}) catch return error.OutOfMemory;
    if (opt_env) |env| {
        const process_env_map = std.process.getEnvMap(arena) catch std.process.EnvMap.init(arena);
        var it = env.iterator();
        while (it.next()) |entry| {
            const key = entry.key_ptr.*;
            const value = entry.value_ptr.*;
            if (process_env_map.get(key)) |process_value| {
                if (std.mem.eql(u8, value, process_value)) continue;
            }
            writer.print("{s}=", .{key}) catch return error.OutOfMemory;
            shell.escape(writer, value, false) catch return error.OutOfMemory;
            writer.writeByte(' ') catch return error.OutOfMemory;
        }
    }
    shell.escape(writer, argv[0], true) catch return error.OutOfMemory;
    for (argv[1..]) |arg| {
        writer.writeByte(' ') catch return error.OutOfMemory;
        shell.escape(writer, arg, false) catch return error.OutOfMemory;
    }
    return aw.toOwnedSlice();
}