Skip to documentation
SLOP

tiny.chant.preprocess.system

Reference tiny.chant preprocess system

Defined in preprocess.

API (2)

Actions

Public operations.

No direct callersNo direct callspreprocesssystem
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallspreprocessruntest sourcelib.chant.src.preprocess.systemtest: preprocess failure carries the ...private sourcelib.chant.src.preprocess.systemfailureTextprivate sourcelib.chant.src.preprocess.systemrecordFailurepreprocess.systemrun
Static calls · unresolved targets: 2 · external targets: 4.
Called byCallsNo direct callspreprocessrunpreprocess.systemwriteTemporary
Static calls · unresolved targets: 0 · external targets: 2.

Source: lib/chant/src/preprocess/root.zig:5

zig
pub const system = @import("system.zig");

Source: lib/chant/src/preprocess/system.zig

zig
const std = @import("std");const sys = @import("sys");const types = @import("types.zig");const Error = types.Error;const Options = types.Options;const Prepared = types.Prepared;pub fn run(    arena: std.mem.Allocator,    environ: std.process.Environ,    source_path: []const u8,    source_dir: []const u8,    from_temporary: bool,    options: Options,    diagnostic: ?*types.Diagnostic,) Error![]const u8 {    var argv = std.ArrayListUnmanaged([]const u8).empty;    defer argv.deinit(arena);    try argv.appendSlice(arena, &.{ "cc", "-std=c2x", "-E", "-nostdinc" });    if (from_temporary) {        try argv.append(arena, "-iquote");        try argv.append(arena, source_dir);    }    for (options.include_dirs) |dir| {        try argv.append(arena, "-I");        try argv.append(arena, dir);    }    for (options.defines) |define| {        try argv.append(arena, "-D");        try argv.append(arena, define);    }    try argv.append(arena, source_path);    var io_state = std.Io.Threaded.init(arena, .{ .environ = environ });    defer io_state.deinit();    const result = sys.process.run(arena, io_state.io(), .{        .argv = argv.items,        .stdout_limit = .limited(16 * 1024 * 1024),        .stderr_limit = .limited(256 * 1024),    }) catch |err| switch (err) {        error.FileNotFound => return error.PreprocessorUnavailable,        error.OutOfMemory => return error.OutOfMemory,        else => {            recordFailure(diagnostic, source_path, @errorName(err));            return error.PreprocessFailed;        },    };    switch (result.term) {        .exited => |code| if (code != 0) {            recordFailure(diagnostic, source_path, failureText(result.stderr, result.stdout));            return error.PreprocessFailed;        },        else => {            recordFailure(diagnostic, source_path, failureText(result.stderr, result.stdout));            return error.PreprocessFailed;        },    }    return result.stdout;}const failure_text_limit = 512;fn recordFailure(diagnostic: ?*types.Diagnostic, source_path: []const u8, message: []const u8) void {    const out = diagnostic orelse return;    out.* = .{ .message = message, .file = source_path };}fn failureText(stderr: []const u8, stdout: []const u8) []const u8 {    const text = if (std.mem.trim(u8, stderr, " \t\r\n").len != 0) stderr else stdout;    const trimmed = std.mem.trim(u8, text, " \t\r\n");    return trimmed[0..@min(trimmed.len, failure_text_limit)];}pub fn writeTemporary(arena: std.mem.Allocator, source: []const u8) Error!Prepared {    const path = try std.fmt.allocPrint(arena, "/tmp/chant-preprocess-{d}.c", .{sys.time.nanoTimestamp()});    sys.fs.writeFile(path, source) catch return error.PreprocessFailed;    return .{ .path = path, .temporary = true };}test "preprocess failure carries the compiler stderr" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const arena = arena_state.allocator();    const source_path = "/tmp/chant-preprocess-diagnostic.c";    sys.fs.writeFile(source_path,        \\#include <chant-no-such-header.h>        \\int x;        \\    ) catch return;    var diagnostic: types.Diagnostic = .{};    const failed = run(arena, sys.env.current(), source_path, "/tmp", false, .{}, &diagnostic);    if (failed) |_| {        return error.TestUnexpectedResult;    } else |err| switch (err) {        error.PreprocessorUnavailable => return,        error.PreprocessFailed => {            try std.testing.expect(diagnostic.message.len != 0);            try std.testing.expect(std.mem.indexOf(u8, diagnostic.message, "chant-no-such-header.h") != null);            try std.testing.expectEqualStrings(source_path, diagnostic.file);        },        else => return err,    }}test "failure text prefers stderr and bounds the excerpt" {    try std.testing.expectEqualStrings("fatal error", failureText("  fatal error\n", "ignored"));    try std.testing.expectEqualStrings("stdout text", failureText("   \n", "stdout text\n"));    const long = @as([((failure_text_limit + 64)) * ("e").len]u8, @bitCast(@as([(failure_text_limit + 64)][("e").len]u8, @splat(("e")[0..("e").len].*))));    try std.testing.expectEqual(failure_text_limit, failureText(&long, "").len);}

Audit

Definitions3
Public names3
Members0
Version26.7.0
Revisiondaab053ee433