diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-29 13:50:33 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:16 -0300 |
| commit | cb2beaf76c07e74c76297082b9d43be3122bd55a (patch) | |
| tree | f4e1e433554c67715b33808d0728f0881a6c95cf /src | |
| parent | ca362e190825862d5c0a1451d163d3c00be68314 (diff) | |
| download | pardes-cb2beaf76c07e74c76297082b9d43be3122bd55a.tar.gz pardes-cb2beaf76c07e74c76297082b9d43be3122bd55a.zip | |
Two Dumps in one second get names of their own
A dump is named by the second it was written in, so a second Dump within it overwrote the first. A clash now takes -2, -3 and on.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'src')
| -rw-r--r-- | src/dump.zig | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/src/dump.zig b/src/dump.zig index 45a5e0eb..fca88a2d 100644 --- a/src/dump.zig +++ b/src/dump.zig @@ -47,11 +47,40 @@ pub fn outPath(buf: *[1024:0]u8, dir_setting: []const u8) ?[:0]const u8 { const yd = es.getEpochDay().calculateYearDay(); const md = yd.calculateMonthDay(); const ds = es.getDaySeconds(); - return std.fmt.bufPrintSentinel(buf, "{s}/pardes-{d:0>4}{d:0>2}{d:0>2}-{d:0>2}{d:0>2}{d:0>2}.zon", .{ - dir, yd.year, md.month.numeric(), - @as(u8, md.day_index) + 1, ds.getHoursIntoDay(), ds.getMinutesIntoHour(), - ds.getSecondsIntoMinute(), - }, 0) catch null; + var stamp: [32]u8 = undefined; + const base = std.fmt.bufPrint(&stamp, "pardes-{d:0>4}{d:0>2}{d:0>2}-{d:0>2}{d:0>2}{d:0>2}", .{ + yd.year, md.month.numeric(), @as(u8, md.day_index) + 1, + ds.getHoursIntoDay(), ds.getMinutesIntoHour(), ds.getSecondsIntoMinute(), + }) catch return null; + return uniqueIn(buf, dir, base); +} + +/// `<dir>/<base>.zon`, or `<base>-2.zon` and on when two dumps land in one +/// second: a dump never overwrites another. +fn uniqueIn(buf: *[1024:0]u8, dir: []const u8, base: []const u8) ?[:0]const u8 { + var n: usize = 1; + while (n < 1000) : (n += 1) { + const path = (if (n == 1) + std.fmt.bufPrintSentinel(buf, "{s}/{s}.zon", .{ dir, base }, 0) + else + std.fmt.bufPrintSentinel(buf, "{s}/{s}-{d}.zon", .{ dir, base, n }, 0)) catch return null; + if (comptime !pardes.hosted) return path; + if (std.c.access(path.ptr, std.c.F_OK) != 0) return path; + } + return null; +} + +test "two dumps in one second get names of their own" { + var tmp = std.testing.tmpDir(.{}); + defer tmp.cleanup(); + var dir_buf: [900]u8 = undefined; + const dir = dir_buf[0..try tmp.dir.realPath(std.testing.io, &dir_buf)]; + var buf: [1024:0]u8 = undefined; + const first = try std.testing.allocator.dupe(u8, uniqueIn(&buf, dir, "pardes-x").?); + defer std.testing.allocator.free(first); + try std.testing.expect(std.mem.endsWith(u8, first, "/pardes-x.zon")); + try tmp.dir.writeFile(std.testing.io, .{ .sub_path = "pardes-x.zon", .data = "" }); + try std.testing.expect(std.mem.endsWith(u8, uniqueIn(&buf, dir, "pardes-x").?, "/pardes-x-2.zon")); } /// The host's environment; a freestanding core (web, the board) has none /// and no libc to ask, so only a DumpDir with no `~/` names a directory there. |
