tiny.chant.preprocess.system
Defined in preprocess.
API (2)
Actions
Public operations.
Source
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
| Definitions | 3 |
|---|---|
| Public names | 3 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |