Skip to content

Commit

Permalink
Compilation: use mtime for timestamp macro
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsan901998 authored Oct 18, 2024
1 parent 0620577 commit 9020bdf
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/aro/Builtins.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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();

Expand Down
46 changes: 28 additions & 18 deletions src/aro/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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());
Expand Down
7 changes: 4 additions & 3 deletions src/aro/Driver.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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("<command line>", 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();
Expand All @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion src/aro/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion test/fuzz/fuzz_lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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("<STDIN>", buf);

try processSource(&comp, builtin, user_source);
Expand Down
2 changes: 1 addition & 1 deletion test/record_runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ fn singleRun(alloc: std.mem.Allocator, test_dir: []const u8, test_case: TestCase
}

const user_macros = try comp.addSourceFromBuffer("<command line>", 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();
Expand Down
4 changes: 2 additions & 2 deletions test/runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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("<command line>", 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();
Expand Down Expand Up @@ -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("<command line>", 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);
Expand Down

0 comments on commit 9020bdf

Please sign in to comment.