Skip to content

Commit

Permalink
Compilation: implement SOURCE_DATE_EPOCH env var to change compilatio…
Browse files Browse the repository at this point in the history
…n time
  • Loading branch information
ehaas committed Aug 3, 2023
1 parent db10f53 commit 48e5a4a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
24 changes: 19 additions & 5 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,23 @@ pub fn intern(comp: *Compilation, str: []const u8) !StringInterner.StringId {
return comp.string_interner.intern(comp.gpa, str);
}

fn generateDateAndTime(w: anytype) !void {
// TODO take timezone into account here once it is supported in Zig std
const timestamp = std.math.clamp(std.time.timestamp(), 0, std.math.maxInt(i64));
const epoch_seconds = EpochSeconds{ .secs = @intCast(timestamp) };
/// Dec 31 9999 23:59:59
const max_timestamp = 253402300799;

fn getTimestamp(comp: *Compilation) !u47 {
const provided: ?i64 = comp.environment.getSourceEpoch(max_timestamp) catch blk: {
try comp.diag.add(.{
.tag = .invalid_source_epoch,
.loc = .{ .id = .unused, .byte_offset = 0, .line = 0 },
}, &.{});
break :blk null;
};
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();
const year_day = epoch_day.calculateYearDay();
Expand Down Expand Up @@ -333,7 +346,8 @@ pub fn generateBuiltinMacros(comp: *Compilation) !Source {
);

// timestamps
try generateDateAndTime(w);
const timestamp = try comp.getTimestamp();
try generateDateAndTime(w, timestamp);

// types
if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n");
Expand Down
4 changes: 4 additions & 0 deletions src/Diagnostics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2347,6 +2347,10 @@ const messages = struct {
const kind = .@"error";
const extra = .str;
};
pub const invalid_source_epoch = struct {
const msg = "environment variable SOURCE_DATE_EPOCH must expand to a non-negative integer less than or equal to 253402300799";
const kind = .@"error";
};
};

list: std.ArrayListUnmanaged(Message) = .{},
Expand Down
7 changes: 7 additions & 0 deletions src/Environment.zig
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ pub fn get(self: *const Environment, name: Name) ?[]const u8 {
return self.variables[@intFromEnum(name)];
}

pub fn getSourceEpoch(self: *const Environment, max: i64) !?i64 {
const provided = self.get(.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;
}

test Environment {
var env1 = Environment.init(.{
.SOURCE_DATE_EPOCH = "123",
Expand Down

0 comments on commit 48e5a4a

Please sign in to comment.