Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation: use mtime for timestamp macro #791

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading