From 9020bdfbf14173cf4f33792a12575ddc5ffcf8db Mon Sep 17 00:00:00 2001 From: danielsan901998 <54245680+danielsan901998@users.noreply.github.com> Date: Fri, 18 Oct 2024 22:13:29 +0200 Subject: [PATCH] Compilation: use mtime for timestamp macro --- src/aro/Builtins.zig | 4 ++-- src/aro/Compilation.zig | 46 +++++++++++++++++++++++++---------------- src/aro/Driver.zig | 7 ++++--- src/aro/Parser.zig | 2 +- test/fuzz/fuzz_lib.zig | 2 +- test/record_runner.zig | 2 +- test/runner.zig | 4 ++-- 7 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/aro/Builtins.zig b/src/aro/Builtins.zig index eb67a2f3..7490f7bf 100644 --- a/src/aro/Builtins.zig +++ b/src/aro/Builtins.zig @@ -352,7 +352,7 @@ test Iterator { test "All builtins" { var comp = Compilation.init(std.testing.allocator, std.fs.cwd()); defer comp.deinit(); - _ = try comp.generateBuiltinMacros(.include_system_defines); + _ = try comp.generateBuiltinMacros(.include_system_defines, null); var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); @@ -375,7 +375,7 @@ test "Allocation failures" { fn testOne(allocator: std.mem.Allocator) !void { var comp = Compilation.init(allocator, std.fs.cwd()); defer comp.deinit(); - _ = try comp.generateBuiltinMacros(.include_system_defines); + _ = try comp.generateBuiltinMacros(.include_system_defines, null); var arena = std.heap.ArenaAllocator.init(comp.gpa); defer arena.deinit(); diff --git a/src/aro/Compilation.zig b/src/aro/Compilation.zig index d2d36d35..ba5e6baa 100644 --- a/src/aro/Compilation.zig +++ b/src/aro/Compilation.zig @@ -180,29 +180,23 @@ pub fn deinit(comp: *Compilation) void { comp.environment.deinit(comp.gpa); } -pub fn getSourceEpoch(self: *const Compilation, max: i64) !?i64 { +pub fn getSourceEpoch(self: *const Compilation, max: i64) !?u47 { const provided = self.environment.source_date_epoch orelse return null; const parsed = std.fmt.parseInt(i64, provided, 10) catch return error.InvalidEpoch; if (parsed < 0 or parsed > max) return error.InvalidEpoch; - return parsed; + return @intCast(std.math.clamp(parsed, 0, max_timestamp)); } /// Dec 31 9999 23:59:59 const max_timestamp = 253402300799; -fn getTimestamp(comp: *Compilation) !u47 { - const provided: ?i64 = comp.getSourceEpoch(max_timestamp) catch blk: { - try comp.addDiagnostic(.{ - .tag = .invalid_source_epoch, - .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 }, - }, &.{}); - break :blk null; +fn generateDateAndTime(w: anytype, opt_timestamp: ?u47) !void { + const timestamp = opt_timestamp orelse { + try w.print("#define __DATE__ \"??? ?? ????\"\n", .{}); + try w.print("#define __TIME__ \"??:??:??\"\n", .{}); + try w.print("#define __TIMESTAMP__ \"??? ??? ?? ??:??:?? ????\"\n", .{}); + return; }; - const timestamp = provided orelse std.time.timestamp(); - return @intCast(std.math.clamp(timestamp, 0, max_timestamp)); -} - -fn generateDateAndTime(w: anytype, timestamp: u47) !void { const epoch_seconds = EpochSeconds{ .secs = timestamp }; const epoch_day = epoch_seconds.getEpochDay(); const day_seconds = epoch_seconds.getDaySeconds(); @@ -550,8 +544,15 @@ fn generateSystemDefines(comp: *Compilation, w: anytype) !void { } } +/// Generate builtin macros trying to use mtime as timestamp +pub fn generateBuiltinMacrosFromPath(comp: *Compilation, system_defines_mode: SystemDefinesMode, path: []const u8) !Source { + const stat = comp.cwd.statFile(path) catch return try generateBuiltinMacros(comp, system_defines_mode, null); + const timestamp: i64 = @intCast(@divTrunc(stat.mtime, std.time.ns_per_s)); + return try generateBuiltinMacros(comp, system_defines_mode, @intCast(std.math.clamp(timestamp, 0, max_timestamp))); +} + /// Generate builtin macros that will be available to each source file. -pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) !Source { +pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode, timestamp: ?u47) !Source { try comp.generateBuiltinTypes(); var buf = std.ArrayList(u8).init(comp.gpa); @@ -587,9 +588,18 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi try buf.append('\n'); } - // timestamps - const timestamp = try comp.getTimestamp(); - try generateDateAndTime(buf.writer(), timestamp); + const provided: ?u47 = comp.getSourceEpoch(max_timestamp) catch blk: { + try comp.addDiagnostic(.{ + .tag = .invalid_source_epoch, + .loc = .{ .id = .unused, .byte_offset = 0, .line = 0 }, + }, &.{}); + break :blk null; + }; + if (provided) |epoch| { + try generateDateAndTime(buf.writer(), epoch); + } else { + try generateDateAndTime(buf.writer(), timestamp); + } if (system_defines_mode == .include_system_defines) { try comp.generateSystemDefines(buf.writer()); diff --git a/src/aro/Driver.zig b/src/aro/Driver.zig index d135b2ef..e79bf191 100644 --- a/src/aro/Driver.zig +++ b/src/aro/Driver.zig @@ -689,10 +689,10 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_ error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}), }; - const builtin = try d.comp.generateBuiltinMacros(d.system_defines); const user_macros = try d.comp.addSourceFromBuffer("", macro_buf.items); if (fast_exit and d.inputs.items.len == 1) { + const builtin = try d.comp.generateBuiltinMacrosFromPath(d.system_defines, d.inputs.items[0].path); d.processSource(tc, d.inputs.items[0], builtin, user_macros, fast_exit) catch |e| switch (e) { error.FatalError => { d.renderErrors(); @@ -704,6 +704,7 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_ } for (d.inputs.items) |source| { + const builtin = try d.comp.generateBuiltinMacrosFromPath(d.system_defines, source.path); d.processSource(tc, source, builtin, user_macros, fast_exit) catch |e| switch (e) { error.FatalError => { d.renderErrors(); @@ -760,7 +761,7 @@ fn processSource( } const file = if (d.output_name) |some| - std.fs.cwd().createFile(some, .{}) catch |er| + d.comp.cwd.createFile(some, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ some, errorDescription(er) }) else std.io.getStdOut(); @@ -863,7 +864,7 @@ fn processSource( break :blk std.fmt.bufPrint(&name_buf, fmt_template, fmt_args) catch return d.fatal("Filename too long for filesystem: " ++ fmt_template, fmt_args); }; - const out_file = std.fs.cwd().createFile(out_file_name, .{}) catch |er| + const out_file = d.comp.cwd.createFile(out_file_name, .{}) catch |er| return d.fatal("unable to create output file '{s}': {s}", .{ out_file_name, errorDescription(er) }); defer out_file.close(); diff --git a/src/aro/Parser.zig b/src/aro/Parser.zig index 95e56c92..785bfa08 100644 --- a/src/aro/Parser.zig +++ b/src/aro/Parser.zig @@ -8972,7 +8972,7 @@ test "Node locations" { \\ ); - const builtin_macros = try comp.generateBuiltinMacros(.no_system_defines); + const builtin_macros = try comp.generateBuiltinMacros(.no_system_defines, null); var pp = Preprocessor.init(&comp); defer pp.deinit(); diff --git a/test/fuzz/fuzz_lib.zig b/test/fuzz/fuzz_lib.zig index 9bcb9135..33c4cc06 100644 --- a/test/fuzz/fuzz_lib.zig +++ b/test/fuzz/fuzz_lib.zig @@ -33,7 +33,7 @@ fn compileSlice(buf: []const u8) !void { try comp.addDefaultPragmaHandlers(); try comp.addSystemIncludeDir(aro_dir); - const builtin = try comp.generateBuiltinMacros(.include_system_defines); + const builtin = try comp.generateBuiltinMacrosFromPath(.include_system_defines, user_source.path); const user_source = try comp.addSourceFromBuffer("", buf); try processSource(&comp, builtin, user_source); diff --git a/test/record_runner.zig b/test/record_runner.zig index 9a1abe3d..60f05cc2 100644 --- a/test/record_runner.zig +++ b/test/record_runner.zig @@ -261,7 +261,7 @@ fn singleRun(alloc: std.mem.Allocator, test_dir: []const u8, test_case: TestCase } const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); - const builtin_macros = try comp.generateBuiltinMacros(.include_system_defines); + const builtin_macros = try comp.generateBuiltinMacrosFromPath(.include_system_defines, file.path); var pp = aro.Preprocessor.init(&comp); defer pp.deinit(); diff --git a/test/runner.zig b/test/runner.zig index 9b084bce..fb697739 100644 --- a/test/runner.zig +++ b/test/runner.zig @@ -76,7 +76,7 @@ fn testOne(allocator: std.mem.Allocator, path: []const u8, test_dir: []const u8) _, _, const system_defines, _ = try addCommandLineArgs(&comp, file, macro_buf.writer()); const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); - const builtin_macros = try comp.generateBuiltinMacros(system_defines); + const builtin_macros = try comp.generateBuiltinMacrosFromPath(system_defines, path); var pp = aro.Preprocessor.init(&comp); defer pp.deinit(); @@ -223,7 +223,7 @@ pub fn main() !void { const only_preprocess, const linemarkers, const system_defines, const dump_mode = try addCommandLineArgs(&comp, file, macro_buf.writer()); const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); - const builtin_macros = try comp.generateBuiltinMacros(system_defines); + const builtin_macros = try comp.generateBuiltinMacrosFromPath(system_defines, file.path); comp.diagnostics.errors = 0; var pp = aro.Preprocessor.init(&comp);