2024-07-17 06:38:10 -08:00
|
|
|
// SPDX-FileCopyrightText: Yorhel <projects@yorhel.nl>
|
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
|
|
const std = @import("std");
|
|
|
|
|
const main = @import("main.zig");
|
|
|
|
|
const model = @import("model.zig");
|
|
|
|
|
const sink = @import("sink.zig");
|
|
|
|
|
|
|
|
|
|
// Emit the memory tree to the sink in depth-first order from a single thread,
|
|
|
|
|
// suitable for JSON export.
|
|
|
|
|
|
|
|
|
|
fn toStat(e: *model.Entry) sink.Stat {
|
|
|
|
|
const el = e.link();
|
|
|
|
|
return sink.Stat{
|
2024-08-01 04:20:34 -08:00
|
|
|
.etype = e.pack.etype,
|
2024-07-17 06:38:10 -08:00
|
|
|
.blocks = e.pack.blocks,
|
|
|
|
|
.size = e.size,
|
|
|
|
|
.dev =
|
|
|
|
|
if (e.dir()) |d| model.devices.list.items[d.pack.dev]
|
|
|
|
|
else if (el) |l| model.devices.list.items[l.parent.pack.dev]
|
|
|
|
|
else undefined,
|
|
|
|
|
.ino = if (el) |l| l.ino else undefined,
|
2024-07-23 00:51:19 -08:00
|
|
|
.nlink = if (el) |l| l.pack.nlink else 1,
|
2024-07-17 06:38:10 -08:00
|
|
|
.ext = if (e.ext()) |x| x.* else .{},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Ctx = struct {
|
|
|
|
|
sink: *sink.Thread,
|
|
|
|
|
stat: sink.Stat,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn rec(ctx: *Ctx, dir: *sink.Dir, entry: *model.Entry) void {
|
2024-07-28 00:54:55 -08:00
|
|
|
if ((ctx.sink.files_seen.load(.monotonic) & 65) == 0)
|
2024-07-17 06:38:10 -08:00
|
|
|
main.handleEvent(false, false);
|
|
|
|
|
|
|
|
|
|
ctx.stat = toStat(entry);
|
2024-08-01 04:20:34 -08:00
|
|
|
switch (entry.pack.etype) {
|
|
|
|
|
.dir => {
|
|
|
|
|
const d = entry.dir().?;
|
|
|
|
|
var ndir = dir.addDir(ctx.sink, entry.name(), &ctx.stat);
|
|
|
|
|
ctx.sink.setDir(ndir);
|
|
|
|
|
if (d.pack.err) ndir.setReadError(ctx.sink);
|
2024-08-05 23:46:17 -08:00
|
|
|
var it = d.sub.ptr;
|
|
|
|
|
while (it) |e| : (it = e.next.ptr) rec(ctx, ndir, e);
|
2024-08-01 04:20:34 -08:00
|
|
|
ctx.sink.setDir(dir);
|
|
|
|
|
ndir.unref(ctx.sink);
|
|
|
|
|
},
|
|
|
|
|
.reg, .nonreg, .link => dir.addStat(ctx.sink, entry.name(), &ctx.stat),
|
|
|
|
|
else => dir.addSpecial(ctx.sink, entry.name(), entry.pack.etype),
|
2024-07-17 06:38:10 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn run(d: *model.Dir) void {
|
|
|
|
|
const sink_threads = sink.createThreads(1);
|
|
|
|
|
|
|
|
|
|
var ctx = .{
|
|
|
|
|
.sink = &sink_threads[0],
|
|
|
|
|
.stat = toStat(&d.entry),
|
|
|
|
|
};
|
|
|
|
|
var buf = std.ArrayList(u8).init(main.allocator);
|
|
|
|
|
d.fmtPath(true, &buf);
|
|
|
|
|
const root = sink.createRoot(buf.items, &ctx.stat);
|
|
|
|
|
buf.deinit();
|
|
|
|
|
|
2024-08-05 23:46:17 -08:00
|
|
|
var it = d.sub.ptr;
|
|
|
|
|
while (it) |e| : (it = e.next.ptr) rec(&ctx, root, e);
|
2024-07-17 06:38:10 -08:00
|
|
|
|
2024-07-27 08:40:48 -08:00
|
|
|
root.unref(ctx.sink);
|
2024-07-17 06:38:10 -08:00
|
|
|
sink.done();
|
|
|
|
|
}
|