mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-14 09:48:40 -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.
|
fn hasErr(self: *Self) bool {
|
||||||
pub fn setErr(self: *Self, parent: *Dir) void {
|
return
|
||||||
if (self.dir()) |d| d.pack.err = true
|
if (self.file()) |f| f.pack.err
|
||||||
else if (self.file()) |f| f.pack.err = true
|
else if (self.dir()) |d| d.pack.err or d.pack.suberr
|
||||||
else unreachable;
|
else false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn addStats(self: *Entry, parent: *Dir, nlink: u31) void {
|
pub fn addStats(self: *Entry, parent: *Dir, nlink: u31) void {
|
||||||
|
|
@ -265,6 +260,19 @@ pub const Dir = extern struct {
|
||||||
i -= 1;
|
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)
|
// 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().?;
|
var f = e.file().?;
|
||||||
switch (t) {
|
switch (t) {
|
||||||
.err => e.setErr(self.dir),
|
.err => f.pack.err = true,
|
||||||
.other_fs => f.pack.other_fs = true,
|
.other_fs => f.pack.other_fs = true,
|
||||||
.kernfs => f.pack.kernfs = true,
|
.kernfs => f.pack.kernfs = true,
|
||||||
.excluded => f.pack.excluded = true,
|
.excluded => f.pack.excluded = true,
|
||||||
|
|
@ -231,16 +231,17 @@ const ScanDir = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn final(self: *Self) void {
|
fn final(self: *Self) void {
|
||||||
if (self.entries.count() == 0) // optimization for the common case
|
if (self.entries.count() > 0) {
|
||||||
return;
|
var it = &self.dir.sub;
|
||||||
var it = &self.dir.sub;
|
while (it.*) |e| {
|
||||||
while (it.*) |e| {
|
if (self.entries.contains(e)) {
|
||||||
if (self.entries.contains(e)) {
|
e.delStatsRec(self.dir);
|
||||||
e.delStatsRec(self.dir);
|
it.* = e.next;
|
||||||
it.* = e.next;
|
} else
|
||||||
} else
|
it = &e.next;
|
||||||
it = &e.next;
|
}
|
||||||
}
|
}
|
||||||
|
self.dir.updateSubErr();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(self: *Self) void {
|
fn deinit(self: *Self) void {
|
||||||
|
|
@ -261,6 +262,7 @@ const ScanDir = struct {
|
||||||
const Context = struct {
|
const Context = struct {
|
||||||
// When scanning to RAM
|
// When scanning to RAM
|
||||||
parents: ?std.ArrayList(ScanDir) = null,
|
parents: ?std.ArrayList(ScanDir) = null,
|
||||||
|
refreshing: ?*model.Dir = null,
|
||||||
// When scanning to a file
|
// When scanning to a file
|
||||||
wr: ?*Writer = null,
|
wr: ?*Writer = null,
|
||||||
|
|
||||||
|
|
@ -300,7 +302,10 @@ const Context = struct {
|
||||||
|
|
||||||
fn initMem(dir: ?*model.Dir) *Self {
|
fn initMem(dir: ?*model.Dir) *Self {
|
||||||
var self = main.allocator.create(Self) catch unreachable;
|
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;
|
if (dir) |d| self.parents.?.append(ScanDir.init(d)) catch unreachable;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
@ -311,6 +316,8 @@ const Context = struct {
|
||||||
defer counting_hardlinks = false;
|
defer counting_hardlinks = false;
|
||||||
main.handleEvent(false, true);
|
main.handleEvent(false, true);
|
||||||
model.inodes.addAllStats();
|
model.inodes.addAllStats();
|
||||||
|
var p = self.refreshing;
|
||||||
|
while (p) |d| : (p = d.parent) d.updateSubErr();
|
||||||
}
|
}
|
||||||
if (self.wr) |wr| {
|
if (self.wr) |wr| {
|
||||||
wr.writer().writeByte(']') catch |e| writeErr(e);
|
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.
|
// 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)
|
// (Such errors are silently ignored when exporting to a file, as the directory metadata has already been written)
|
||||||
fn setDirlistError(self: *Self) void {
|
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 };
|
const Special = enum { err, other_fs, kernfs, excluded };
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue