mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-13 01:08:41 -09:00
parent
c83159f076
commit
a2eb84e7d3
2 changed files with 37 additions and 22 deletions
|
|
@ -109,16 +109,11 @@ pub const Entry = extern struct {
|
|||
};
|
||||
}
|
||||
|
||||
// Set the 'err' flag on Dirs and Files, propagating 'suberr' to parents.
|
||||
pub fn setErr(self: *Self, parent: *Dir) void {
|
||||
if (self.dir()) |d| d.pack.err = true
|
||||
else if (self.file()) |f| f.pack.err = true
|
||||
else unreachable;
|
||||
var it: ?*Dir = if (&parent.entry == self) parent.parent else parent;
|
||||
while (it) |p| : (it = p.parent) {
|
||||
if (p.pack.suberr) break;
|
||||
p.pack.suberr = true;
|
||||
}
|
||||
fn hasErr(self: *Self) bool {
|
||||
return
|
||||
if (self.file()) |f| f.pack.err
|
||||
else if (self.dir()) |d| d.pack.err or d.pack.suberr
|
||||
else false;
|
||||
}
|
||||
|
||||
pub fn addStats(self: *Entry, parent: *Dir, nlink: u31) void {
|
||||
|
|
@ -265,6 +260,19 @@ pub const Dir = extern struct {
|
|||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Only updates the suberr of this Dir, assumes child dirs have already
|
||||
// been updated and does not propagate to parents.
|
||||
pub fn updateSubErr(self: *@This()) void {
|
||||
self.pack.suberr = false;
|
||||
var sub = self.sub;
|
||||
while (sub) |e| : (sub = e.next) {
|
||||
if (e.hasErr()) {
|
||||
self.pack.suberr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// File that's been hardlinked (i.e. nlink > 1)
|
||||
|
|
|
|||
31
src/scan.zig
31
src/scan.zig
|
|
@ -176,7 +176,7 @@ const ScanDir = struct {
|
|||
};
|
||||
var f = e.file().?;
|
||||
switch (t) {
|
||||
.err => e.setErr(self.dir),
|
||||
.err => f.pack.err = true,
|
||||
.other_fs => f.pack.other_fs = true,
|
||||
.kernfs => f.pack.kernfs = true,
|
||||
.excluded => f.pack.excluded = true,
|
||||
|
|
@ -231,16 +231,17 @@ const ScanDir = struct {
|
|||
}
|
||||
|
||||
fn final(self: *Self) void {
|
||||
if (self.entries.count() == 0) // optimization for the common case
|
||||
return;
|
||||
var it = &self.dir.sub;
|
||||
while (it.*) |e| {
|
||||
if (self.entries.contains(e)) {
|
||||
e.delStatsRec(self.dir);
|
||||
it.* = e.next;
|
||||
} else
|
||||
it = &e.next;
|
||||
if (self.entries.count() > 0) {
|
||||
var it = &self.dir.sub;
|
||||
while (it.*) |e| {
|
||||
if (self.entries.contains(e)) {
|
||||
e.delStatsRec(self.dir);
|
||||
it.* = e.next;
|
||||
} else
|
||||
it = &e.next;
|
||||
}
|
||||
}
|
||||
self.dir.updateSubErr();
|
||||
}
|
||||
|
||||
fn deinit(self: *Self) void {
|
||||
|
|
@ -261,6 +262,7 @@ const ScanDir = struct {
|
|||
const Context = struct {
|
||||
// When scanning to RAM
|
||||
parents: ?std.ArrayList(ScanDir) = null,
|
||||
refreshing: ?*model.Dir = null,
|
||||
// When scanning to a file
|
||||
wr: ?*Writer = null,
|
||||
|
||||
|
|
@ -300,7 +302,10 @@ const Context = struct {
|
|||
|
||||
fn initMem(dir: ?*model.Dir) *Self {
|
||||
var self = main.allocator.create(Self) catch unreachable;
|
||||
self.* = .{ .parents = std.ArrayList(ScanDir).init(main.allocator) };
|
||||
self.* = .{
|
||||
.parents = std.ArrayList(ScanDir).init(main.allocator),
|
||||
.refreshing = dir,
|
||||
};
|
||||
if (dir) |d| self.parents.?.append(ScanDir.init(d)) catch unreachable;
|
||||
return self;
|
||||
}
|
||||
|
|
@ -311,6 +316,8 @@ const Context = struct {
|
|||
defer counting_hardlinks = false;
|
||||
main.handleEvent(false, true);
|
||||
model.inodes.addAllStats();
|
||||
var p = self.refreshing;
|
||||
while (p) |d| : (p = d.parent) d.updateSubErr();
|
||||
}
|
||||
if (self.wr) |wr| {
|
||||
wr.writer().writeByte(']') catch |e| writeErr(e);
|
||||
|
|
@ -353,7 +360,7 @@ const Context = struct {
|
|||
// Set a flag to indicate that there was an error listing file entries in the current directory.
|
||||
// (Such errors are silently ignored when exporting to a file, as the directory metadata has already been written)
|
||||
fn setDirlistError(self: *Self) void {
|
||||
if (self.parents) |*p| p.items[p.items.len-1].dir.entry.setErr(p.items[p.items.len-1].dir);
|
||||
if (self.parents) |*p| p.items[p.items.len-1].dir.pack.err = true;
|
||||
}
|
||||
|
||||
const Special = enum { err, other_fs, kernfs, excluded };
|
||||
|
|
|
|||
Loading…
Reference in a new issue