summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2021-07-19 15:28:11 +0200
committerYorhel <git@yorhel.nl>2021-12-21 10:34:44 +0100
commit6a68cd9b896cd1975d22d4a58b5c3b845e4d01f6 (patch)
tree06cebf9d253392e809d9c30a55f3bb9859d41280
parent14b90444c97078d2d47e0c16d4e724c93357be54 (diff)
Fixes and updates for Zig 0.9.0
-rw-r--r--README.md2
-rw-r--r--src/browser.zig42
-rw-r--r--src/delete.zig8
-rw-r--r--src/main.zig28
-rw-r--r--src/model.zig51
-rw-r--r--src/scan.zig46
-rw-r--r--src/ui.zig38
-rw-r--r--src/util.zig10
8 files changed, 107 insertions, 118 deletions
diff --git a/README.md b/README.md
index a7fb43e..5edb94b 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ C version (1.x).
## Requirements
-- Zig 0.8 or 0.8.1
+- Zig 0.9.0
- Some sort of POSIX-like OS
- ncurses libraries and header files
diff --git a/src/browser.zig b/src/browser.zig
index de1ffa7..2f3c1c0 100644
--- a/src/browser.zig
+++ b/src/browser.zig
@@ -8,7 +8,7 @@ const scan = @import("scan.zig");
const delete = @import("delete.zig");
const ui = @import("ui.zig");
const c = @cImport(@cInclude("time.h"));
-usingnamespace @import("util.zig");
+const util = @import("util.zig");
// Currently opened directory.
pub var dir_parent: *model.Dir = undefined;
@@ -188,9 +188,9 @@ const Row = struct {
width += 2 + width;
defer self.col += width;
const item = self.item orelse return;
- const siz = if (main.config.show_blocks) blocksToSize(item.blocks) else item.size;
- var shr = if (item.dir()) |d| (if (main.config.show_blocks) blocksToSize(d.shared_blocks) else d.shared_size) else 0;
- if (main.config.show_shared == .unique) shr = saturateSub(siz, shr);
+ const siz = if (main.config.show_blocks) util.blocksToSize(item.blocks) else item.size;
+ var shr = if (item.dir()) |d| (if (main.config.show_blocks) util.blocksToSize(d.shared_blocks) else d.shared_size) else 0;
+ if (main.config.show_shared == .unique) shr = siz -| shr;
ui.move(self.row, self.col);
ui.addsize(self.bg, siz);
@@ -231,7 +231,7 @@ const Row = struct {
var siz: u64 = 0;
self.bg.fg(.graph);
while (i < bar_size) : (i += 1) {
- siz = saturateAdd(siz, perblock);
+ siz = siz +| perblock;
ui.addch(if (siz <= num) '#' else ' ');
}
}
@@ -284,7 +284,7 @@ const Row = struct {
if (self.item) |i| {
self.bg.fg(if (i.etype == .dir) .dir else .default);
ui.addch(if (i.isDirectory()) '/' else ' ');
- ui.addstr(ui.shorten(ui.toUtf8(i.name()), saturateSub(ui.cols, self.col + 1)));
+ ui.addstr(ui.shorten(ui.toUtf8(i.name()), ui.cols -| self.col +| 1));
} else {
self.bg.fg(.dir);
ui.addstr("/..");
@@ -383,7 +383,7 @@ const info = struct {
}
fn drawLinks(box: ui.Box, row: *u32, rows: u32, cols: u32) void {
- const numrows = saturateSub(rows, 4);
+ const numrows = rows -| 4;
if (links_idx < links_top) links_top = links_idx;
if (links_idx >= links_top + numrows) links_top = links_idx - numrows + 1;
@@ -396,7 +396,7 @@ const info = struct {
ui.addch(if (&e.entry == entry) '*' else ' ');
const path = e.path(false);
defer main.allocator.free(path);
- ui.addstr(ui.shorten(ui.toUtf8(path), saturateSub(cols, 5)));
+ ui.addstr(ui.shorten(ui.toUtf8(path), cols -| 5));
row.* += 1;
}
ui.style(.default);
@@ -420,7 +420,7 @@ const info = struct {
if (shared > 0) {
ui.style(.default);
drawSizeRow(box, row, " > shared: ", shared);
- drawSizeRow(box, row, " > unique: ", saturateSub(size, shared));
+ drawSizeRow(box, row, " > unique: ", size -| shared);
}
}
@@ -466,8 +466,8 @@ const info = struct {
}
// Disk usage & Apparent size
- drawSize(box, row, " Disk usage: ", blocksToSize(e.blocks), if (e.dir()) |d| blocksToSize(d.shared_blocks) else 0);
- drawSize(box, row, "Apparent size: ", e.size, if (e.dir()) |d| d.shared_size else 0);
+ drawSize(box, row, " Disk usage: ", util.blocksToSize(e.blocks), if (e.dir()) |d| util.blocksToSize(d.shared_blocks) else 0);
+ drawSize(box, row, "Apparent size: ", e.size, if (e.dir()) |d| d.shared_size else 0);
// Number of items
if (e.dir()) |d| {
@@ -552,7 +552,7 @@ const info = struct {
set(null, .info);
}
}
- if (keyInputSelection(ch, &cursor_idx, dir_items.items.len, saturateSub(ui.rows, 3))) {
+ if (keyInputSelection(ch, &cursor_idx, dir_items.items.len, ui.rows -| 3)) {
set(dir_items.items[cursor_idx], .info);
return true;
}
@@ -725,10 +725,10 @@ pub fn draw() void {
ui.style(.hd);
ui.addstr(" for help");
if (main.config.imported) {
- ui.move(0, saturateSub(ui.cols, 10));
+ ui.move(0, ui.cols -| 10);
ui.addstr("[imported]");
} else if (!main.config.can_delete.?) {
- ui.move(0, saturateSub(ui.cols, 10));
+ ui.move(0, ui.cols -| 10);
ui.addstr("[readonly]");
}
@@ -741,13 +741,13 @@ pub fn draw() void {
var pathbuf = std.ArrayList(u8).init(main.allocator);
dir_parent.fmtPath(true, &pathbuf);
- ui.addstr(ui.shorten(ui.toUtf8(arrayListBufZ(&pathbuf)), saturateSub(ui.cols, 5)));
+ ui.addstr(ui.shorten(ui.toUtf8(util.arrayListBufZ(&pathbuf)), ui.cols -| 5));
pathbuf.deinit();
ui.style(.default);
ui.addch(' ');
- const numrows = saturateSub(ui.rows, 3);
+ const numrows = ui.rows -| 3;
if (cursor_idx < current_view.top) current_view.top = cursor_idx;
if (cursor_idx >= current_view.top + numrows) current_view.top = cursor_idx - numrows + 1;
@@ -770,7 +770,7 @@ pub fn draw() void {
ui.move(ui.rows-1, 1);
ui.style(if (main.config.show_blocks) .bold_hd else .hd);
ui.addstr("Total disk usage: ");
- ui.addsize(.hd, blocksToSize(dir_parent.entry.blocks));
+ ui.addsize(.hd, util.blocksToSize(dir_parent.entry.blocks));
ui.style(if (main.config.show_blocks) .hd else .bold_hd);
ui.addstr(" Apparent size: ");
ui.addsize(.hd, dir_parent.entry.size);
@@ -810,9 +810,9 @@ fn keyInputSelection(ch: i32, idx: *usize, len: usize, page: u32) bool {
if (idx.* > 0) idx.* -= 1;
},
ui.c.KEY_HOME => idx.* = 0,
- ui.c.KEY_END, ui.c.KEY_LL => idx.* = saturateSub(len, 1),
- ui.c.KEY_PPAGE => idx.* = saturateSub(idx.*, page),
- ui.c.KEY_NPAGE => idx.* = std.math.min(saturateSub(len, 1), idx.* + page),
+ ui.c.KEY_END, ui.c.KEY_LL => idx.* = len -| 1,
+ ui.c.KEY_PPAGE => idx.* = idx.* -| page,
+ ui.c.KEY_NPAGE => idx.* = std.math.min(len -| 1, idx.* + page),
else => return false,
}
return true;
@@ -930,6 +930,6 @@ pub fn keyInput(ch: i32) void {
.unique => .off,
},
- else => _ = keyInputSelection(ch, &cursor_idx, dir_items.items.len, saturateSub(ui.rows, 3)),
+ else => _ = keyInputSelection(ch, &cursor_idx, dir_items.items.len, ui.rows -| 3),
}
}
diff --git a/src/delete.zig b/src/delete.zig
index b9e6851..663035f 100644
--- a/src/delete.zig
+++ b/src/delete.zig
@@ -6,7 +6,7 @@ const main = @import("main.zig");
const model = @import("model.zig");
const ui = @import("ui.zig");
const browser = @import("browser.zig");
-usingnamespace @import("util.zig");
+const util = @import("util.zig");
var parent: *model.Dir = undefined;
var entry: *model.Entry = undefined;
@@ -89,7 +89,7 @@ pub fn delete() ?*model.Entry {
path.append('/') catch unreachable;
path.appendSlice(entry.name()) catch unreachable;
- _ = deleteItem(std.fs.cwd(), arrayListBufZ(&path), it);
+ _ = deleteItem(std.fs.cwd(), util.arrayListBufZ(&path), it);
model.inodes.addAllStats();
return if (it.* == e) e else next_sel;
}
@@ -132,7 +132,7 @@ fn drawProgress() void {
const box = ui.Box.create(6, 60, "Deleting...");
box.move(2, 2);
- ui.addstr(ui.shorten(ui.toUtf8(arrayListBufZ(&path)), 56));
+ ui.addstr(ui.shorten(ui.toUtf8(util.arrayListBufZ(&path)), 56));
box.move(4, 41);
ui.addstr("Press ");
ui.style(.key);
@@ -151,7 +151,7 @@ fn drawErr() void {
const box = ui.Box.create(6, 60, "Error");
box.move(1, 2);
ui.addstr("Error deleting ");
- ui.addstr(ui.shorten(ui.toUtf8(arrayListBufZ(&path)), 41));
+ ui.addstr(ui.shorten(ui.toUtf8(util.arrayListBufZ(&path)), 41));
box.move(2, 4);
ui.addstr(ui.errorString(error_code));
diff --git a/src/main.zig b/src/main.zig
index e7b7786..d98a4fc 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -16,27 +16,25 @@ const c = @cImport(@cInclude("locale.h"));
// This allocator never returns an error, it either succeeds or causes ncdu to quit.
// (Which means you'll find a lot of "catch unreachable" sprinkled through the code,
// they look scarier than they are)
-fn wrapAlloc(alloc: *std.mem.Allocator, len: usize, alignment: u29, len_align: u29, return_address: usize) error{OutOfMemory}![]u8 {
+fn wrapAlloc(_: *anyopaque, len: usize, alignment: u29, len_align: u29, return_address: usize) error{OutOfMemory}![]u8 {
while (true) {
- if (std.heap.c_allocator.allocFn(alloc, len, alignment, len_align, return_address)) |r|
+ if (std.heap.c_allocator.vtable.alloc(undefined, len, alignment, len_align, return_address)) |r|
return r
else |_| {}
ui.oom();
}
}
-fn wrapResize(alloc: *std.mem.Allocator, buf: []u8, buf_align: u29, new_len: usize, len_align: u29, return_address: usize) std.mem.Allocator.Error!usize {
- // AFAIK, all uses of resizeFn to grow an allocation will fall back to allocFn on failure.
- return std.heap.c_allocator.resizeFn(alloc, buf, buf_align, new_len, len_align, return_address);
-}
-
-var allocator_state = std.mem.Allocator{
- .allocFn = wrapAlloc,
- .resizeFn = wrapResize,
+pub const allocator = std.mem.Allocator{
+ .ptr = undefined,
+ .vtable = &.{
+ .alloc = wrapAlloc,
+ // AFAIK, all uses of resize() to grow an allocation will fall back to alloc() on failure.
+ .resize = std.heap.c_allocator.vtable.resize,
+ .free = std.heap.c_allocator.vtable.free,
+ },
};
-pub const allocator = &allocator_state;
-//var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
-//pub const allocator = &general_purpose_allocator.allocator;
+
pub const config = struct {
pub const SortCol = enum { name, blocks, size, items, mtime };
@@ -388,7 +386,7 @@ pub fn main() void {
_ = c.setlocale(c.LC_ALL, "");
if (c.localeconv()) |locale| {
if (locale.*.thousands_sep) |sep| {
- const span = std.mem.spanZ(sep);
+ const span = std.mem.sliceTo(sep, 0);
if (span.len > 0)
config.thousands_sep = span;
}
@@ -444,7 +442,7 @@ pub fn main() void {
}
}
- if (std.builtin.os.tag != .linux and config.exclude_kernfs)
+ if (@import("builtin").os.tag != .linux and config.exclude_kernfs)
ui.die("The --exclude-kernfs tag is currently only supported on Linux.\n", .{});
const out_tty = std.io.getStdOut().isTty();
diff --git a/src/model.zig b/src/model.zig
index 5d611ba..1839b7e 100644
--- a/src/model.zig
+++ b/src/model.zig
@@ -4,7 +4,7 @@
const std = @import("std");
const main = @import("main.zig");
const ui = @import("ui.zig");
-usingnamespace @import("util.zig");
+const util = @import("util.zig");
// While an arena allocator is optimimal for almost all scenarios in which ncdu
// is used, it doesn't allow for re-using deleted nodes after doing a delete or
@@ -12,9 +12,10 @@ usingnamespace @import("util.zig");
// will leak memory, but I'd say that's worth the efficiency gains.
// TODO: Can still implement a simple bucketed free list on top of this arena
// allocator to reuse nodes, if necessary.
-var allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+var allocator_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+const allocator = allocator_state.allocator();
-pub const EType = packed enum(u2) { dir, link, file };
+pub const EType = enum(u2) { dir, link, file };
// Type for the Entry.blocks field. Smaller than a u64 to make room for flags.
pub const Blocks = u60;
@@ -66,15 +67,15 @@ pub const Entry = packed struct {
fn nameOffset(etype: EType) usize {
return switch (etype) {
- .dir => @byteOffsetOf(Dir, "name"),
- .link => @byteOffsetOf(Link, "name"),
- .file => @byteOffsetOf(File, "name"),
+ .dir => @offsetOf(Dir, "name"),
+ .link => @offsetOf(Link, "name"),
+ .file => @offsetOf(File, "name"),
};
}
pub fn name(self: *const Self) [:0]const u8 {
const ptr = @ptrCast([*:0]const u8, self) + nameOffset(self.etype);
- return ptr[0..std.mem.lenZ(ptr) :0];
+ return std.mem.sliceTo(ptr, 0);
}
pub fn ext(self: *Self) ?*Ext {
@@ -87,7 +88,7 @@ pub const Entry = packed struct {
const size = nameOffset(etype) + ename.len + 1 + extsize;
var ptr = blk: {
while (true) {
- if (allocator.allocator.allocWithOptions(u8, size, std.math.max(@alignOf(Ext), @alignOf(Entry)), null)) |p|
+ if (allocator.allocWithOptions(u8, size, std.math.max(@alignOf(Ext), @alignOf(Entry)), null)) |p|
break :blk p
else |_| {}
ui.oom();
@@ -124,7 +125,7 @@ pub const Entry = packed struct {
var d = inodes.map.getOrPut(l) catch unreachable;
if (!d.found_existing) {
d.value_ptr.* = .{ .counted = false, .nlink = nlink };
- inodes.total_blocks = saturateAdd(inodes.total_blocks, self.blocks);
+ inodes.total_blocks +|= self.blocks;
l.next = l;
} else {
inodes.setStats(.{ .key_ptr = d.key_ptr, .value_ptr = d.value_ptr }, false);
@@ -142,10 +143,10 @@ pub const Entry = packed struct {
if (self.ext()) |e|
if (p.entry.ext()) |pe|
if (e.mtime > pe.mtime) { pe.mtime = e.mtime; };
- p.items = saturateAdd(p.items, 1);
+ p.items +|= 1;
if (self.etype != .link) {
- p.entry.size = saturateAdd(p.entry.size, self.size);
- p.entry.blocks = saturateAdd(p.entry.blocks, self.blocks);
+ p.entry.size +|= self.size;
+ p.entry.blocks +|= self.blocks;
}
}
}
@@ -174,7 +175,7 @@ pub const Entry = packed struct {
if (l.next == l) {
_ = inodes.map.remove(l);
_ = inodes.uncounted.remove(l);
- inodes.total_blocks = saturateSub(inodes.total_blocks, self.blocks);
+ inodes.total_blocks -|= self.blocks;
} else {
if (d.key_ptr.* == l)
d.key_ptr.* = l.next;
@@ -193,10 +194,10 @@ pub const Entry = packed struct {
var it: ?*Dir = parent;
while(it) |p| : (it = p.parent) {
- p.items = saturateSub(p.items, 1);
+ p.items -|= 1;
if (self.etype != .link) {
- p.entry.size = saturateSub(p.entry.size, self.size);
- p.entry.blocks = saturateSub(p.entry.blocks, self.blocks);
+ p.entry.size -|= self.size;
+ p.entry.blocks -|= self.blocks;
}
}
}
@@ -234,7 +235,7 @@ pub const Dir = packed struct {
err: bool,
suberr: bool,
- // Only used to find the @byteOffsetOff, the name is written at this point as a 0-terminated string.
+ // Only used to find the @offsetOff, the name is written at this point as a 0-terminated string.
// (Old C habits die hard)
name: u8,
@@ -418,20 +419,20 @@ pub const inodes = struct {
var dir_iter = dirs.iterator();
if (add) {
while (dir_iter.next()) |de| {
- de.key_ptr.*.entry.blocks = saturateAdd(de.key_ptr.*.entry.blocks, entry.key_ptr.*.entry.blocks);
- de.key_ptr.*.entry.size = saturateAdd(de.key_ptr.*.entry.size, entry.key_ptr.*.entry.size);
+ de.key_ptr.*.entry.blocks +|= entry.key_ptr.*.entry.blocks;
+ de.key_ptr.*.entry.size +|= entry.key_ptr.*.entry.size;
if (de.value_ptr.* < nlink) {
- de.key_ptr.*.shared_blocks = saturateAdd(de.key_ptr.*.shared_blocks, entry.key_ptr.*.entry.blocks);
- de.key_ptr.*.shared_size = saturateAdd(de.key_ptr.*.shared_size, entry.key_ptr.*.entry.size);
+ de.key_ptr.*.shared_blocks +|= entry.key_ptr.*.entry.blocks;
+ de.key_ptr.*.shared_size +|= entry.key_ptr.*.entry.size;
}
}
} else {
while (dir_iter.next()) |de| {
- de.key_ptr.*.entry.blocks = saturateSub(de.key_ptr.*.entry.blocks, entry.key_ptr.*.entry.blocks);
- de.key_ptr.*.entry.size = saturateSub(de.key_ptr.*.entry.size, entry.key_ptr.*.entry.size);
+ de.key_ptr.*.entry.blocks -|= entry.key_ptr.*.entry.blocks;
+ de.key_ptr.*.entry.size -|= entry.key_ptr.*.entry.size;
if (de.value_ptr.* < nlink) {
- de.key_ptr.*.shared_blocks = saturateSub(de.key_ptr.*.shared_blocks, entry.key_ptr.*.entry.blocks);
- de.key_ptr.*.shared_size = saturateSub(de.key_ptr.*.shared_size, entry.key_ptr.*.entry.size);
+ de.key_ptr.*.shared_blocks -|= entry.key_ptr.*.entry.blocks;
+ de.key_ptr.*.shared_size -|= entry.key_ptr.*.entry.size;
}
}
}
diff --git a/src/scan.zig b/src/scan.zig
index ed92a35..01b01a0 100644
--- a/src/scan.zig
+++ b/src/scan.zig
@@ -5,7 +5,7 @@ const std = @import("std");
const main = @import("main.zig");
const model = @import("model.zig");
const ui = @import("ui.zig");
-usingnamespace @import("util.zig");
+const util = @import("util.zig");
const c_statfs = @cImport(@cInclude("sys/vfs.h"));
const c_fnmatch = @cImport(@cInclude("fnmatch.h"));
@@ -24,25 +24,25 @@ const Stat = struct {
ext: model.Ext = .{},
fn clamp(comptime T: type, comptime field: anytype, x: anytype) std.meta.fieldInfo(T, field).field_type {
- return castClamp(std.meta.fieldInfo(T, field).field_type, x);
+ return util.castClamp(std.meta.fieldInfo(T, field).field_type, x);
}
fn truncate(comptime T: type, comptime field: anytype, x: anytype) std.meta.fieldInfo(T, field).field_type {
- return castTruncate(std.meta.fieldInfo(T, field).field_type, x);
+ return util.castTruncate(std.meta.fieldInfo(T, field).field_type, x);
}
fn read(parent: std.fs.Dir, name: [:0]const u8, follow: bool) !Stat {
- const stat = try std.os.fstatatZ(parent.fd, name, if (follow) 0 else std.os.AT_SYMLINK_NOFOLLOW);
+ const stat = try std.os.fstatatZ(parent.fd, name, if (follow) 0 else std.os.AT.SYMLINK_NOFOLLOW);
return Stat{
.blocks = clamp(Stat, .blocks, stat.blocks),
.size = clamp(Stat, .size, stat.size),
.dev = truncate(Stat, .dev, stat.dev),
.ino = truncate(Stat, .ino, stat.ino),
.nlink = clamp(Stat, .nlink, stat.nlink),
- .hlinkc = stat.nlink > 1 and !std.os.system.S_ISDIR(stat.mode),
- .dir = std.os.system.S_ISDIR(stat.mode),
- .reg = std.os.system.S_ISREG(stat.mode),
- .symlink = std.os.system.S_ISLNK(stat.mode),
+ .hlinkc = stat.nlink > 1 and !std.os.system.S.ISDIR(stat.mode),
+ .dir = std.os.system.S.ISDIR(stat.mode),
+ .reg = std.os.system.S.ISREG(stat.mode),
+ .symlink = std.os.system.S.ISLNK(stat.mode),
.ext = .{
.mtime = clamp(model.Ext, .mtime, stat.mtime().tv_sec),
.uid = truncate(model.Ext, .uid, stat.uid),
@@ -141,7 +141,7 @@ const ScanDir = struct {
var count: Map.Size = 0;
var it = dir.sub;
while (it) |e| : (it = e.next) count += 1;
- self.entries.ensureCapacity(count) catch unreachable;
+ self.entries.ensureUnusedCapacity(count) catch unreachable;
it = dir.sub;
while (it) |e| : (it = e.next)
@@ -345,7 +345,7 @@ const Context = struct {
}
fn pathZ(self: *Self) [:0]const u8 {
- return arrayListBufZ(&self.path);
+ return util.arrayListBufZ(&self.path);
}
// Set a flag to indicate that there was an error listing file entries in the current directory.
@@ -396,7 +396,7 @@ const Context = struct {
try w.writeAll("{\"name\":");
try writeJsonString(w, self.name);
if (self.stat.size > 0) try w.print(",\"asize\":{d}", .{ self.stat.size });
- if (self.stat.blocks > 0) try w.print(",\"dsize\":{d}", .{ blocksToSize(self.stat.blocks) });
+ if (self.stat.blocks > 0) try w.print(",\"dsize\":{d}", .{ util.blocksToSize(self.stat.blocks) });
if (self.stat.dir and self.stat.dev != dir_dev) try w.print(",\"dev\":{d}", .{ self.stat.dev });
if (self.stat.hlinkc) try w.print(",\"ino\":{d},\"hlnkc\":true,\"nlink\":{d}", .{ self.stat.ino, self.stat.nlink });
if (!self.stat.dir and !self.stat.reg) try w.writeAll(",\"notreg\":true");
@@ -508,7 +508,7 @@ fn scanDir(ctx: *Context, dir: std.fs.Dir, dir_dev: u64) void {
} else null;
defer if (edir != null) edir.?.close();
- if (std.builtin.os.tag == .linux and main.config.exclude_kernfs and ctx.stat.dir and isKernfs(edir.?, ctx.stat.dev)) {
+ if (@import("builtin").os.tag == .linux and main.config.exclude_kernfs and ctx.stat.dir and isKernfs(edir.?, ctx.stat.dev)) {
ctx.addSpecial(.kernfs);
continue;
}
@@ -980,18 +980,18 @@ var animation_pos: u32 = 0;
var need_confirm_quit = false;
fn drawError(err: anyerror) void {
- const width = saturateSub(ui.cols, 5);
+ const width = ui.cols -| 5;
const box = ui.Box.create(7, width, "Scan error");
box.move(2, 2);
ui.addstr("Path: ");
- ui.addstr(ui.shorten(ui.toUtf8(active_context.last_error.?), saturateSub(width, 10)));
+ ui.addstr(ui.shorten(ui.toUtf8(active_context.last_error.?), width -| 10));
box.move(3, 2);
ui.addstr("Error: ");
- ui.addstr(ui.shorten(ui.errorString(err), saturateSub(width, 6)));
+ ui.addstr(ui.shorten(ui.errorString(err), width -| 6));
- box.move(5, saturateSub(width, 27));
+ box.move(5, width -| 27);
ui.addstr("Press any key to continue");
}
@@ -999,7 +999,7 @@ fn drawBox() void {
ui.init();
const ctx = active_context;
if (ctx.fatal_error) |err| return drawError(err);
- const width = saturateSub(ui.cols, 5);
+ const width = ui.cols -| 5;
const box = ui.Box.create(10, width, "Scanning...");
box.move(2, 2);
ui.addstr("Total items: ");
@@ -1009,12 +1009,12 @@ fn drawBox() void {
box.move(2, 30);
ui.addstr("size: ");
// TODO: Should display the size of the dir-to-be-refreshed on refreshing, not the root.
- ui.addsize(.default, blocksToSize(saturateAdd(model.root.entry.blocks, model.inodes.total_blocks)));
+ ui.addsize(.default, util.blocksToSize(model.root.entry.blocks +| model.inodes.total_blocks));
}
box.move(3, 2);
ui.addstr("Current item: ");
- ui.addstr(ui.shorten(ui.toUtf8(ctx.pathZ()), saturateSub(width, 18)));
+ ui.addstr(ui.shorten(ui.toUtf8(ctx.pathZ()), width -| 18));
if (ctx.last_error) |path| {
box.move(5, 2);
@@ -1022,20 +1022,20 @@ fn drawBox() void {
ui.addstr("Warning: ");
ui.style(.default);
ui.addstr("error scanning ");
- ui.addstr(ui.shorten(ui.toUtf8(path), saturateSub(width, 28)));
+ ui.addstr(ui.shorten(ui.toUtf8(path), width -| 28));
box.move(6, 3);
ui.addstr("some directory sizes may not be correct.");
}
if (need_confirm_quit) {
- box.move(8, saturateSub(width, 20));
+ box.move(8, width -| 20);
ui.addstr("Press ");
ui.style(.key);
ui.addch('y');
ui.style(.default);
ui.addstr(" to confirm");
} else {
- box.move(8, saturateSub(width, 18));
+ box.move(8, width -| 18);
ui.addstr("Press ");
ui.style(.key);
ui.addch('q');
@@ -1074,7 +1074,7 @@ pub fn draw() void {
.{ ui.shorten(active_context.pathZ(), 63), active_context.items_seen }
) catch return;
} else {
- const r = ui.FmtSize.fmt(blocksToSize(model.root.entry.blocks));
+ const r = ui.FmtSize.fmt(util.blocksToSize(model.root.entry.blocks));
line = std.fmt.bufPrint(&buf, "\x1b7\x1b[J{s: <51} {d:>9} files / {s}{s}\x1b8",
.{ ui.shorten(active_context.pathZ(), 51), active_context.items_seen, r.num(), r.unit }
) catch return;
diff --git a/src/ui.zig b/src/ui.zig
index 08fbdea..c2cfb5c 100644
--- a/src/ui.zig
+++ b/src/ui.zig
@@ -5,7 +5,7 @@
const std = @import("std");
const main = @import("main.zig");
-usingnamespace @import("util.zig");
+const util = @import("util.zig");
pub const c = @cImport({
@cInclude("stdio.h");
@@ -73,7 +73,7 @@ pub fn errorString(e: anyerror) [:0]const u8 {
error.ReadOnlyFilesystem => "Read-only filesystem",
error.SymlinkLoop => "Symlink loop",
error.SystemFdQuotaExceeded => "System file descriptor limit exceeded",
- else => @bitCast([:0]const u8, @errorName(e)), // XXX: The bitCast can be removed after a Zig >0.8 release.
+ else => @errorName(e),
};
}
@@ -113,7 +113,7 @@ pub fn toUtf8(in: [:0]const u8) [:0]const u8 {
to_utf8_buf.writer().print("\\x{X:0>2}", .{in[i]}) catch unreachable;
i += 1;
}
- return arrayListBufZ(&to_utf8_buf);
+ return util.arrayListBufZ(&to_utf8_buf);
}
var shorten_buf = std.ArrayList(u8).init(main.allocator);
@@ -163,7 +163,7 @@ pub fn shorten(in: [:0]const u8, max_width: u32) [:0] const u8 {
break;
}
}
- return arrayListBufZ(&shorten_buf);
+ return util.arrayListBufZ(&shorten_buf);
}
fn shortenTest(in: [:0]const u8, max_width: u32, out: [:0]const u8) !void {
@@ -348,7 +348,7 @@ pub fn init() void {
clearScr();
if (main.config.nc_tty) {
var tty = c.fopen("/dev/tty", "r+");
- if (tty == null) die("Error opening /dev/tty: {s}.\n", .{ c.strerror(std.c.getErrno(-1)) });
+ if (tty == null) die("Error opening /dev/tty: {s}.\n", .{ c.strerror(@enumToInt(std.c.getErrno(-1))) });
var term = c.newterm(null, tty, tty);
if (term == null) die("Error initializing ncurses.\n", .{});
_ = c.set_term(term);
@@ -439,7 +439,7 @@ pub const FmtSize = struct {
}
pub fn num(self: *const @This()) [:0]const u8 {
- return std.mem.spanZ(&self.buf);
+ return std.mem.sliceTo(&self.buf, 0);
}
};
@@ -478,14 +478,14 @@ pub fn addnum(bg: Bg, v: u64) void {
// Print a file mode, takes 10 columns
pub fn addmode(mode: u32) void {
- addch(switch (mode & std.os.S_IFMT) {
- std.os.S_IFDIR => 'd',
- std.os.S_IFREG => '-',
- std.os.S_IFLNK => 'l',
- std.os.S_IFIFO => 'p',
- std.os.S_IFSOCK => 's',
- std.os.S_IFCHR => 'c',
- std.os.S_IFBLK => 'b',
+ addch(switch (mode & std.os.S.IFMT) {
+ std.os.S.IFDIR => 'd',
+ std.os.S.IFREG => '-',
+ std.os.S.IFLNK => 'l',
+ std.os.S.IFIFO => 'p',
+ std.os.S.IFSOCK => 's',
+ std.os.S.IFCHR => 'c',
+ std.os.S.IFBLK => 'b',
else => '?'
});
addch(if (mode & 0o400 > 0) 'r' else '-');
@@ -496,12 +496,12 @@ pub fn addmode(mode: u32) void {
addch(if (mode & 0o2000 > 0) 's' else if (mode & 0o010 > 0) @as(u7, 'x') else '-');
addch(if (mode & 0o004 > 0) 'r' else '-');
addch(if (mode & 0o002 > 0) 'w' else '-');
- addch(if (mode & 0o1000 > 0) (if (std.os.S_ISDIR(mode)) @as(u7, 't') else 'T') else if (mode & 0o001 > 0) @as(u7, 'x') else '-');
+ addch(if (mode & 0o1000 > 0) (if (std.os.S.ISDIR(mode)) @as(u7, 't') else 'T') else if (mode & 0o001 > 0) @as(u7, 'x') else '-');
}
// Print a timestamp, takes 25 columns
pub fn addts(bg: Bg, ts: u64) void {
- const t = castClamp(c.time_t, ts);
+ const t = util.castClamp(c.time_t, ts);
var buf: [32:0]u8 = undefined;
const len = c.strftime(&buf, buf.len, "%Y-%m-%d %H:%M:%S %z", c.localtime(&t));
if (len > 0) {
@@ -526,8 +526,8 @@ pub const Box = struct {
pub fn create(height: u32, width: u32, title: [:0]const u8) Self {
const s = Self{
- .start_row = saturateSub(rows>>1, height>>1),
- .start_col = saturateSub(cols>>1, width>>1),
+ .start_row = (rows>>1) -| (height>>1),
+ .start_col = (cols>>1) -| (width>>1),
};
style(.default);
if (width < 6 or height < 3) return s;
@@ -597,5 +597,5 @@ pub fn getch(block: bool) i32 {
return ch;
}
die("Error reading keyboard input, assuming TTY has been lost.\n(Potentially nonsensical error message: {s})\n",
- .{ c.strerror(std.c.getErrno(-1)) });
+ .{ c.strerror(@enumToInt(std.c.getErrno(-1))) });
}
diff --git a/src/util.zig b/src/util.zig
index 4c5c8a9..e6191af 100644
--- a/src/util.zig
+++ b/src/util.zig
@@ -3,16 +3,6 @@
const std = @import("std");
-pub fn saturateAdd(a: anytype, b: @TypeOf(a)) @TypeOf(a) {
- std.debug.assert(@typeInfo(@TypeOf(a)).Int.signedness == .unsigned);
- return std.math.add(@TypeOf(a), a, b) catch std.math.maxInt(@TypeOf(a));
-}
-
-pub fn saturateSub(a: anytype, b: @TypeOf(a)) @TypeOf(a) {
- std.debug.assert(@typeInfo(@TypeOf(a)).Int.signedness == .unsigned);
- return std.math.sub(@TypeOf(a), a, b) catch std.math.minInt(@TypeOf(a));
-}
-
// Cast any integer type to the target type, clamping the value to the supported maximum if necessary.
pub fn castClamp(comptime T: type, x: anytype) T {
// (adapted from std.math.cast)