chore(build): fix build with zig 0.11

Test Plan:
```sh
# install zig 0.11
$ make
```
This commit is contained in:
Max 👨🏽‍💻 Coplan 2023-07-13 18:42:16 -07:00
parent e6cfacfa06
commit 3398a4faf5
8 changed files with 75 additions and 89 deletions

View file

@ -9,7 +9,7 @@ ZIG ?= zig
PREFIX ?= /usr/local PREFIX ?= /usr/local
BINDIR ?= ${PREFIX}/bin BINDIR ?= ${PREFIX}/bin
MANDIR ?= ${PREFIX}/share/man/man1 MANDIR ?= ${PREFIX}/share/man/man1
ZIG_FLAGS ?= -Drelease-fast ZIG_FLAGS ?= -Doptimize=ReleaseFast
NCDU_VERSION=$(shell grep 'program_version = "' src/main.zig | sed -e 's/^.*"\(.\+\)".*$$/\1/') NCDU_VERSION=$(shell grep 'program_version = "' src/main.zig | sed -e 's/^.*"\(.\+\)".*$$/\1/')
@ -76,7 +76,7 @@ static-%.tar.gz:
CPPFLAGS=-D_GNU_SOURCE && make && make install.libs CPPFLAGS=-D_GNU_SOURCE && make && make install.libs
@# zig-build - cleaner approach but doesn't work, results in a dynamically linked binary. @# zig-build - cleaner approach but doesn't work, results in a dynamically linked binary.
@#cd static-$* && PKG_CONFIG_LIBDIR="`pwd`/inst/pkg" zig build -Dtarget=$* @#cd static-$* && PKG_CONFIG_LIBDIR="`pwd`/inst/pkg" zig build -Dtarget=$*
@# --build-file ../build.zig --search-prefix inst/ --cache-dir zig -Drelease-fast=true @# --build-file ../build.zig --search-prefix inst/ --cache-dir zig -Doptimize=ReleaseFast
@# Alternative approach, bypassing zig-build @# Alternative approach, bypassing zig-build
cd static-$* && zig build-exe -target $*\ cd static-$* && zig build-exe -target $*\
-Iinst/include -Iinst/include/ncursesw -lc inst/lib/libncursesw.a\ -Iinst/include -Iinst/include/ncursesw -lc inst/lib/libncursesw.a\

View file

@ -5,11 +5,9 @@ const std = @import("std");
pub fn build(b: *std.build.Builder) void { pub fn build(b: *std.build.Builder) void {
const target = b.standardTargetOptions(.{}); const target = b.standardTargetOptions(.{});
const mode = b.standardReleaseOptions(); const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable("ncdu", "src/main.zig"); const exe = b.addExecutable(.{ .name = "ncdu", .root_source_file = .{ .path = "src/main.zig" }, .target = target, .optimize = optimize });
exe.setTarget(target);
exe.setBuildMode(mode);
// https://github.com/ziglang/zig/blob/b52be973dfb7d1408218b8e75800a2da3dc69108/build.zig#L551-L554 // https://github.com/ziglang/zig/blob/b52be973dfb7d1408218b8e75800a2da3dc69108/build.zig#L551-L554
if (exe.target.isDarwin()) { if (exe.target.isDarwin()) {
// useful for package maintainers // useful for package maintainers
@ -18,9 +16,9 @@ pub fn build(b: *std.build.Builder) void {
exe.addCSourceFile("src/ncurses_refs.c", &[_][]const u8{}); exe.addCSourceFile("src/ncurses_refs.c", &[_][]const u8{});
exe.linkLibC(); exe.linkLibC();
exe.linkSystemLibrary("ncursesw"); exe.linkSystemLibrary("ncursesw");
exe.install(); b.installArtifact(exe);
const run_cmd = exe.run(); const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep()); run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| { if (b.args) |args| {
run_cmd.addArgs(args); run_cmd.addArgs(args);
@ -29,7 +27,7 @@ pub fn build(b: *std.build.Builder) void {
const run_step = b.step("run", "Run the app"); const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step); run_step.dependOn(&run_cmd.step);
const tst = b.addTest("src/main.zig"); const tst = b.addTest(.{ .root_source_file = .{ .path = "src/main.zig" } });
tst.linkLibC(); tst.linkLibC();
tst.linkSystemLibrary("ncursesw"); tst.linkSystemLibrary("ncursesw");
tst.addCSourceFile("src/ncurses_refs.c", &[_][]const u8{}); tst.addCSourceFile("src/ncurses_refs.c", &[_][]const u8{});

View file

@ -42,17 +42,15 @@ const View = struct {
// Update cursor_hash and save the current view to the hash table. // Update cursor_hash and save the current view to the hash table.
fn save(self: *@This()) void { fn save(self: *@This()) void {
self.cursor_hash = if (dir_items.items.len == 0) 0 self.cursor_hash = if (dir_items.items.len == 0) 0 else hashEntry(dir_items.items[cursor_idx]);
else hashEntry(dir_items.items[cursor_idx]); opened_dir_views.put(@intFromPtr(dir_parent), self.*) catch {};
opened_dir_views.put(@ptrToInt(dir_parent), self.*) catch {};
} }
// Should be called after dir_parent or dir_items has changed, will load the last saved view and find the proper cursor_idx. // Should be called after dir_parent or dir_items has changed, will load the last saved view and find the proper cursor_idx.
fn load(self: *@This(), sel: ?*const model.Entry) void { fn load(self: *@This(), sel: ?*const model.Entry) void {
if (opened_dir_views.get(@ptrToInt(dir_parent))) |v| self.* = v if (opened_dir_views.get(@intFromPtr(dir_parent))) |v| self.* = v else self.* = @This(){};
else self.* = @This(){};
cursor_idx = 0; cursor_idx = 0;
for (dir_items.items) |e, i| { for (dir_items.items, 0..) |e, i| {
if (if (sel != null) e == sel else self.cursor_hash == hashEntry(e)) { if (if (sel != null) e == sel else self.cursor_hash == hashEntry(e)) {
cursor_idx = i; cursor_idx = i;
break; break;
@ -117,7 +115,7 @@ fn sortDir(next_sel: ?*const model.Entry) void {
// No need to sort the first item if that's the parent dir reference, // No need to sort the first item if that's the parent dir reference,
// excluding that allows sortLt() to ignore null values. // excluding that allows sortLt() to ignore null values.
const lst = dir_items.items[(if (dir_items.items.len > 0 and dir_items.items[0] == null) @as(usize, 1) else 0)..]; const lst = dir_items.items[(if (dir_items.items.len > 0 and dir_items.items[0] == null) @as(usize, 1) else 0)..];
std.sort.sort(?*model.Entry, lst, @as(void, undefined), sortLt); std.sort.block(?*model.Entry, lst, @as(void, undefined), sortLt);
current_view.load(next_sel); current_view.load(next_sel);
} }
@ -203,11 +201,8 @@ const Row = struct {
fn graph(self: *Self) void { fn graph(self: *Self) void {
if ((!main.config.show_graph and !main.config.show_percent) or self.col + 20 > ui.cols) return; if ((!main.config.show_graph and !main.config.show_percent) or self.col + 20 > ui.cols) return;
const bar_size = std.math.max(ui.cols/7, 10); const bar_size = @max(ui.cols / 7, 10);
defer self.col += 3 defer self.col += 3 + (if (main.config.show_graph) bar_size else 0) + (if (main.config.show_percent) @as(u32, 6) else 0) + (if (main.config.show_graph and main.config.show_percent) @as(u32, 1) else 0);
+ (if (main.config.show_graph) bar_size else 0)
+ (if (main.config.show_percent) @as(u32, 6) else 0)
+ (if (main.config.show_graph and main.config.show_percent) @as(u32, 1) else 0);
const item = self.item orelse return; const item = self.item orelse return;
ui.move(self.row, self.col); ui.move(self.row, self.col);
@ -215,10 +210,8 @@ const Row = struct {
ui.addch('['); ui.addch('[');
if (main.config.show_percent) { if (main.config.show_percent) {
self.bg.fg(.num); self.bg.fg(.num);
ui.addprint("{d:>5.1}", .{ 100 * ui.addprint("{d:>5.1}", .{100 *
if (main.config.show_blocks) @intToFloat(f32, item.pack.blocks) / @intToFloat(f32, std.math.max(1, dir_parent.entry.pack.blocks)) if (main.config.show_blocks) @as(f32, @floatFromInt(item.pack.blocks)) / @as(f32, @floatFromInt(@max(1, dir_parent.entry.pack.blocks))) else @as(f32, @floatFromInt(item.size)) / @as(f32, @floatFromInt(@max(1, dir_parent.entry.size)))});
else @intToFloat(f32, item.size) / @intToFloat(f32, std.math.max(1, dir_parent.entry.size))
});
self.bg.fg(.default); self.bg.fg(.default);
ui.addch('%'); ui.addch('%');
} }
@ -234,7 +227,7 @@ const Row = struct {
var i: u32 = 0; var i: u32 = 0;
self.bg.fg(.graph); self.bg.fg(.graph);
while (i < bar_size) : (i += 1) { while (i < bar_size) : (i += 1) {
const frac = std.math.min(@as(usize, 8), (num *| 8) / perblock); const frac = @min(@as(usize, 8), (num *| 8) / perblock);
ui.addstr(switch (main.config.graph_style) { ui.addstr(switch (main.config.graph_style) {
.hash => ([_][:0]const u8{ " ", " ", " ", " ", " ", " ", " ", " ", "#" })[frac], .hash => ([_][:0]const u8{ " ", " ", " ", " ", " ", " ", " ", " ", "#" })[frac],
.half => ([_][:0]const u8{ " ", " ", " ", " ", "", "", "", "", "" })[frac], .half => ([_][:0]const u8{ " ", " ", " ", " ", "", "", "", "", "" })[frac],
@ -261,11 +254,11 @@ const Row = struct {
} else if (n < 100_000) } else if (n < 100_000)
ui.addnum(self.bg, n) ui.addnum(self.bg, n)
else if (n < 1000_000) { else if (n < 1000_000) {
ui.addprint("{d:>5.1}", .{ @intToFloat(f32, n) / 1000 }); ui.addprint("{d:>5.1}", .{@as(f32, @floatFromInt(n)) / 1000});
self.bg.fg(.default); self.bg.fg(.default);
ui.addch('k'); ui.addch('k');
} else if (n < 1000_000_000) { } else if (n < 1000_000_000) {
ui.addprint("{d:>5.1}", .{ @intToFloat(f32, n) / 1000_000 }); ui.addprint("{d:>5.1}", .{@as(f32, @floatFromInt(n)) / 1000_000});
self.bg.fg(.default); self.bg.fg(.default);
ui.addch('M'); ui.addch('M');
} else { } else {
@ -384,8 +377,10 @@ const info = struct {
// TODO: Zig's sort() implementation is type-generic and not very // TODO: Zig's sort() implementation is type-generic and not very
// small. I suspect we can get a good save on our binary size by using // small. I suspect we can get a good save on our binary size by using
// a smaller or non-generic sort. This doesn't have to be very fast. // a smaller or non-generic sort. This doesn't have to be very fast.
std.sort.sort(*model.Link, list.items, @as(void, undefined), lt); std.sort.block(*model.Link, list.items, @as(void, undefined), lt);
for (list.items) |n,i| if (&n.entry == e) { links_idx = i; }; for (list.items, 0..) |n, i| if (&n.entry == e) {
links_idx = i;
};
links = list; links = list;
} }
} }
@ -625,7 +620,7 @@ const help = struct {
var i = offset*2; var i = offset*2;
while (i < (offset + keylines)*2) : (i += 2) { while (i < (offset + keylines)*2) : (i += 2) {
line += 1; line += 1;
box.move(line, 13 - @intCast(u32, keys[i].len)); box.move(line, 13 - @as(u32, @intCast(keys[i].len)));
ui.style(.key); ui.style(.key);
ui.addstr(keys[i]); ui.addstr(keys[i]);
ui.style(.default); ui.style(.default);
@ -657,8 +652,8 @@ const help = struct {
} }
fn drawAbout(box: ui.Box) void { fn drawAbout(box: ui.Box) void {
for (logo) |s, n| { for (logo, 0..) |s, n| {
box.move(@intCast(u32, n)+3, 12); box.move(@as(u32, @intCast(n)) + 3, 12);
var i: u5 = 28; var i: u5 = 28;
while (true) { while (true) {
ui.style(if (s & (@as(u29,1)<<i) > 0) .sel else .default); ui.style(if (s & (@as(u29,1)<<i) > 0) .sel else .default);
@ -823,7 +818,7 @@ fn keyInputSelection(ch: i32, idx: *usize, len: usize, page: u32) bool {
ui.c.KEY_HOME => idx.* = 0, ui.c.KEY_HOME => idx.* = 0,
ui.c.KEY_END, ui.c.KEY_LL => idx.* = len -| 1, ui.c.KEY_END, ui.c.KEY_LL => idx.* = len -| 1,
ui.c.KEY_PPAGE => idx.* = idx.* -| page, ui.c.KEY_PPAGE => idx.* = idx.* -| page,
ui.c.KEY_NPAGE => idx.* = std.math.min(len -| 1, idx.* + page), ui.c.KEY_NPAGE => idx.* = @min(len -| 1, idx.* + page),
else => return false, else => return false,
} }
return true; return true;

View file

@ -17,11 +17,10 @@ const c = @cImport(@cInclude("locale.h"));
// This allocator never returns an error, it either succeeds or causes ncdu to quit. // 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, // (Which means you'll find a lot of "catch unreachable" sprinkled through the code,
// they look scarier than they are) // they look scarier than they are)
fn wrapAlloc(_: *anyopaque, len: usize, alignment: u29, len_align: u29, return_address: usize) error{OutOfMemory}![]u8 { fn wrapAlloc(_: *anyopaque, len: usize, alignment: u8, return_address: usize) ?[*]u8 {
while (true) { while (true) {
if (std.heap.c_allocator.vtable.alloc(undefined, len, alignment, len_align, return_address)) |r| const r = std.heap.c_allocator.vtable.alloc(undefined, len, alignment, return_address);
return r if (r != null) return r;
else |_| {}
ui.oom(); ui.oom();
} }
} }
@ -272,11 +271,11 @@ fn tryReadArgsFile(path: [:0]const u8) void {
rd.readUntilDelimiterOrEof(&linebuf, '\n') rd.readUntilDelimiterOrEof(&linebuf, '\n')
catch |e| ui.die("Error reading from {s}: {s}\nRun with --ignore-config to skip reading config files.\n", .{ path, ui.errorString(e) }) catch |e| ui.die("Error reading from {s}: {s}\nRun with --ignore-config to skip reading config files.\n", .{ path, ui.errorString(e) })
) |line_| { ) |line_| {
var line = std.mem.trim(u8, line_, &std.ascii.spaces); var line = std.mem.trim(u8, line_, &std.ascii.whitespace);
if (line.len == 0 or line[0] == '#') continue; if (line.len == 0 or line[0] == '#') continue;
if (std.mem.indexOfAny(u8, line, " \t=")) |i| { if (std.mem.indexOfAny(u8, line, " \t=")) |i| {
arglist.append(allocator.dupeZ(u8, line[0..i]) catch unreachable) catch unreachable; arglist.append(allocator.dupeZ(u8, line[0..i]) catch unreachable) catch unreachable;
line = std.mem.trimLeft(u8, line[i+1..], &std.ascii.spaces); line = std.mem.trimLeft(u8, line[i+1..], &std.ascii.whitespace);
} }
arglist.append(allocator.dupeZ(u8, line) catch unreachable) catch unreachable; arglist.append(allocator.dupeZ(u8, line) catch unreachable) catch unreachable;
} }

View file

@ -50,15 +50,15 @@ pub const Entry = extern struct {
const Self = @This(); const Self = @This();
pub fn dir(self: *Self) ?*Dir { pub fn dir(self: *Self) ?*Dir {
return if (self.pack.etype == .dir) @ptrCast(*Dir, self) else null; return if (self.pack.etype == .dir) @as(*Dir, @ptrCast(self)) else null;
} }
pub fn link(self: *Self) ?*Link { pub fn link(self: *Self) ?*Link {
return if (self.pack.etype == .link) @ptrCast(*Link, self) else null; return if (self.pack.etype == .link) @as(*Link, @ptrCast(self)) else null;
} }
pub fn file(self: *Self) ?*File { pub fn file(self: *Self) ?*File {
return if (self.pack.etype == .file) @ptrCast(*File, self) else null; return if (self.pack.etype == .file) @as(*File, @ptrCast(self)) else null;
} }
// Whether this entry should be displayed as a "directory". // Whether this entry should be displayed as a "directory".
@ -69,16 +69,16 @@ pub const Entry = extern struct {
pub fn name(self: *const Self) [:0]const u8 { pub fn name(self: *const Self) [:0]const u8 {
const ptr = switch (self.pack.etype) { const ptr = switch (self.pack.etype) {
.dir => &@ptrCast(*const Dir, self).name, .dir => &@as(*const Dir, @ptrCast(self)).name,
.link => &@ptrCast(*const Link, self).name, .link => &@as(*const Link, @ptrCast(self)).name,
.file => &@ptrCast(*const File, self).name, .file => &@as(*const File, @ptrCast(self)).name,
}; };
return std.mem.sliceTo(@ptrCast([*:0]const u8, ptr), 0); return std.mem.sliceTo(@as([*:0]const u8, @ptrCast(ptr)), 0);
} }
pub fn ext(self: *Self) ?*Ext { pub fn ext(self: *Self) ?*Ext {
if (!self.pack.isext) return null; if (!self.pack.isext) return null;
return @ptrCast(*Ext, @ptrCast([*]Ext, self) - 1); return @as(*Ext, @ptrCast(@as([*]Ext, @ptrCast(self)) - 1));
} }
fn alloc(comptime T: type, etype: EType, isext: bool, ename: []const u8) *Entry { fn alloc(comptime T: type, etype: EType, isext: bool, ename: []const u8) *Entry {
@ -89,12 +89,12 @@ pub const Entry = extern struct {
ui.oom(); ui.oom();
}; };
if (isext) { if (isext) {
@ptrCast(*Ext, ptr).* = .{}; @as(*Ext, @ptrCast(ptr)).* = .{};
ptr = ptr[@sizeOf(Ext)..]; ptr = ptr[@sizeOf(Ext)..];
} }
const e = @ptrCast(*T, ptr); const e = @as(*T, @ptrCast(ptr));
e.* = .{ .entry = .{ .pack = .{ .etype = etype, .isext = isext } } }; e.* = .{ .entry = .{ .pack = .{ .etype = etype, .isext = isext } } };
const n = @ptrCast([*]u8, &e.name)[0..ename.len+1]; const n = @as([*]u8, @ptrCast(&e.name))[0 .. ename.len + 1];
std.mem.copy(u8, n, ename); std.mem.copy(u8, n, ename);
n[ename.len] = 0; n[ename.len] = 0;
return &e.entry; return &e.entry;
@ -320,7 +320,7 @@ pub const devices = struct {
pub fn getId(dev: u64) DevId { pub fn getId(dev: u64) DevId {
var d = lookup.getOrPut(dev) catch unreachable; var d = lookup.getOrPut(dev) catch unreachable;
if (!d.found_existing) { if (!d.found_existing) {
d.value_ptr.* = @intCast(DevId, list.items.len); d.value_ptr.* = @as(DevId, @intCast(list.items.len));
list.append(dev) catch unreachable; list.append(dev) catch unreachable;
} }
return d.value_ptr.*; return d.value_ptr.*;

View file

@ -9,7 +9,6 @@ const util = @import("util.zig");
const exclude = @import("exclude.zig"); const exclude = @import("exclude.zig");
const c_statfs = @cImport(@cInclude("sys/vfs.h")); const c_statfs = @cImport(@cInclude("sys/vfs.h"));
// Concise stat struct for fields we're interested in, with the types used by the model. // Concise stat struct for fields we're interested in, with the types used by the model.
const Stat = struct { const Stat = struct {
blocks: model.Blocks = 0, blocks: model.Blocks = 0,
@ -23,12 +22,12 @@ const Stat = struct {
symlink: bool = false, symlink: bool = false,
ext: model.Ext = .{}, ext: model.Ext = .{},
fn clamp(comptime T: type, comptime field: anytype, x: anytype) std.meta.fieldInfo(T, field).field_type { fn clamp(comptime T: type, comptime field: anytype, x: anytype) std.meta.fieldInfo(T, field).type {
return util.castClamp(std.meta.fieldInfo(T, field).field_type, x); return util.castClamp(std.meta.fieldInfo(T, field).type, x);
} }
fn truncate(comptime T: type, comptime field: anytype, x: anytype) std.meta.fieldInfo(T, field).field_type { fn truncate(comptime T: type, comptime field: anytype, x: anytype) std.meta.fieldInfo(T, field).type {
return util.castTruncate(std.meta.fieldInfo(T, field).field_type, x); return util.castTruncate(std.meta.fieldInfo(T, field).type, x);
} }
fn read(parent: std.fs.Dir, name: [:0]const u8, follow: bool) !Stat { fn read(parent: std.fs.Dir, name: [:0]const u8, follow: bool) !Stat {
@ -787,7 +786,7 @@ const Import = struct {
}, },
'd' => { 'd' => {
if (eq(u8, key, "dsize")) { if (eq(u8, key, "dsize")) {
self.ctx.stat.blocks = @intCast(model.Blocks, self.uint(u64)>>9); self.ctx.stat.blocks = @as(model.Blocks, @intCast(self.uint(u64) >> 9));
return; return;
} }
if (eq(u8, key, "dev")) { if (eq(u8, key, "dev")) {

View file

@ -135,7 +135,7 @@ pub fn shorten(in: [:0]const u8, max_width: u32) [:0] const u8 {
// (The "proper" way is to use mbtowc(), but I'd rather port the musl wcwidth implementation to Zig so that I *know* it'll be Unicode. // (The "proper" way is to use mbtowc(), but I'd rather port the musl wcwidth implementation to Zig so that I *know* it'll be Unicode.
// On the other hand, ncurses also use wcwidth() so that would cause duplicated code. Ugh) // On the other hand, ncurses also use wcwidth() so that would cause duplicated code. Ugh)
const cp_width_ = c.wcwidth(cp); const cp_width_ = c.wcwidth(cp);
const cp_width = @intCast(u32, if (cp_width_ < 0) 0 else cp_width_); const cp_width = @as(u32, @intCast(if (cp_width_ < 0) 0 else cp_width_));
const cp_len = std.unicode.utf8CodepointSequenceLength(cp) catch unreachable; const cp_len = std.unicode.utf8CodepointSequenceLength(cp) catch unreachable;
total_width += cp_width; total_width += cp_width;
if (!prefix_done and prefix_width + cp_width <= @divFloor(max_width-1, 2)-1) { if (!prefix_done and prefix_width + cp_width <= @divFloor(max_width-1, 2)-1) {
@ -155,7 +155,7 @@ pub fn shorten(in: [:0]const u8, max_width: u32) [:0] const u8 {
it = std.unicode.Utf8View.initUnchecked(in[prefix_end..]).iterator(); it = std.unicode.Utf8View.initUnchecked(in[prefix_end..]).iterator();
while (it.nextCodepoint()) |cp| { while (it.nextCodepoint()) |cp| {
const cp_width_ = c.wcwidth(cp); const cp_width_ = c.wcwidth(cp);
const cp_width = @intCast(u32, if (cp_width_ < 0) 0 else cp_width_); const cp_width = @as(u32, @intCast(if (cp_width_ < 0) 0 else cp_width_));
const cp_len = std.unicode.utf8CodepointSequenceLength(cp) catch unreachable; const cp_len = std.unicode.utf8CodepointSequenceLength(cp) catch unreachable;
start_width += cp_width; start_width += cp_width;
start_len += cp_len; start_len += cp_len;
@ -288,21 +288,18 @@ const styles = [_]StyleDef{
pub const Style = lbl: { pub const Style = lbl: {
var fields: [styles.len]std.builtin.Type.EnumField = undefined; var fields: [styles.len]std.builtin.Type.EnumField = undefined;
var decls = [_]std.builtin.Type.Declaration{}; var decls = [_]std.builtin.Type.Declaration{};
inline for (styles) |s, i| { inline for (styles, 0..) |s, i| {
fields[i] = .{ fields[i] = .{
.name = s.name, .name = s.name,
.value = i, .value = i,
}; };
} }
break :lbl @Type(.{ break :lbl @Type(.{ .Enum = .{
.Enum = .{ .tag_type = u8,
.layout = .Auto, .fields = &fields,
.tag_type = u8, .decls = &decls,
.fields = &fields, .is_exhaustive = true,
.decls = &decls, } });
.is_exhaustive = true,
}
});
}; };
const ui = @This(); const ui = @This();
@ -336,8 +333,8 @@ pub const Bg = enum {
fn updateSize() void { fn updateSize() void {
// getmax[yx] macros are marked as "legacy", but Zig can't deal with the "proper" getmaxyx macro. // getmax[yx] macros are marked as "legacy", but Zig can't deal with the "proper" getmaxyx macro.
rows = @intCast(u32, c.getmaxy(c.stdscr)); rows = @as(u32, @intCast(c.getmaxy(c.stdscr)));
cols = @intCast(u32, c.getmaxx(c.stdscr)); cols = @as(u32, @intCast(c.getmaxx(c.stdscr)));
} }
fn clearScr() void { fn clearScr() void {
@ -351,7 +348,7 @@ pub fn init() void {
clearScr(); clearScr();
if (main.config.nc_tty) { if (main.config.nc_tty) {
var tty = c.fopen("/dev/tty", "r+"); var tty = c.fopen("/dev/tty", "r+");
if (tty == null) die("Error opening /dev/tty: {s}.\n", .{ c.strerror(@enumToInt(std.c.getErrno(-1))) }); if (tty == null) die("Error opening /dev/tty: {s}.\n", .{c.strerror(@intFromEnum(std.c.getErrno(-1)))});
var term = c.newterm(null, tty, tty); var term = c.newterm(null, tty, tty);
if (term == null) die("Error initializing ncurses.\n", .{}); if (term == null) die("Error initializing ncurses.\n", .{});
_ = c.set_term(term); _ = c.set_term(term);
@ -366,8 +363,8 @@ pub fn init() void {
_ = c.start_color(); _ = c.start_color();
_ = c.use_default_colors(); _ = c.use_default_colors();
for (styles) |s, i| _ = ncdu_init_pair(@intCast(i16, i+1), s.style().fg, s.style().bg); for (styles, 0..) |s, i| _ = ncdu_init_pair(@as(i16, @intCast(i + 1)), s.style().fg, s.style().bg);
_ = c.bkgd(@intCast(c.chtype, c.COLOR_PAIR(@enumToInt(Style.default)+1))); _ = c.bkgd(@as(c.chtype, @intCast(c.COLOR_PAIR(@intFromEnum(Style.default) + 1))));
inited = true; inited = true;
} }
@ -384,11 +381,11 @@ pub fn deinit() void {
} }
pub fn style(s: Style) void { pub fn style(s: Style) void {
_ = c.attr_set(styles[@enumToInt(s)].style().attr, @enumToInt(s)+1, null); _ = c.attr_set(styles[@intFromEnum(s)].style().attr, @intFromEnum(s) + 1, null);
} }
pub fn move(y: u32, x: u32) void { pub fn move(y: u32, x: u32) void {
_ = c.move(@intCast(i32, y), @intCast(i32, x)); _ = c.move(@as(i32, @intCast(y)), @as(i32, @intCast(x)));
} }
// Wraps to the next line if the text overflows, not sure how to disable that. // Wraps to the next line if the text overflows, not sure how to disable that.
@ -419,7 +416,7 @@ pub const FmtSize = struct {
pub fn fmt(v: u64) @This() { pub fn fmt(v: u64) @This() {
var r: @This() = undefined; var r: @This() = undefined;
var f = @intToFloat(f32, v); var f = @as(f32, @floatFromInt(v));
if (main.config.si) { if (main.config.si) {
if(f < 1000.0) { r.unit = " B"; } if(f < 1000.0) { r.unit = " B"; }
else if(f < 1e6) { r.unit = " KB"; f /= 1e3; } else if(f < 1e6) { r.unit = " KB"; f /= 1e3; }
@ -464,7 +461,7 @@ pub fn addnum(bg: Bg, v: u64) void {
const s = std.fmt.bufPrint(&buf, "{d}", .{v}) catch unreachable; const s = std.fmt.bufPrint(&buf, "{d}", .{v}) catch unreachable;
var f: [64:0]u8 = undefined; var f: [64:0]u8 = undefined;
var i: usize = 0; var i: usize = 0;
for (s) |digit, n| { for (s, 0..) |digit, n| {
if (n != 0 and (s.len - n) % 3 == 0) { if (n != 0 and (s.len - n) % 3 == 0) {
for (main.config.thousands_sep) |ch| { for (main.config.thousands_sep) |ch| {
f[i] = ch; f[i] = ch;
@ -518,7 +515,7 @@ pub fn addts(bg: Bg, ts: u64) void {
} }
pub fn hline(ch: c.chtype, len: u32) void { pub fn hline(ch: c.chtype, len: u32) void {
_ = c.hline(ch, @intCast(i32, len)); _ = c.hline(ch, @as(i32, @intCast(len)));
} }
// Draws a bordered box in the center of the screen. // Draws a bordered box in the center of the screen.
@ -600,6 +597,5 @@ pub fn getch(block: bool) i32 {
} }
return ch; return ch;
} }
die("Error reading keyboard input, assuming TTY has been lost.\n(Potentially nonsensical error message: {s})\n", die("Error reading keyboard input, assuming TTY has been lost.\n(Potentially nonsensical error message: {s})\n", .{c.strerror(@intFromEnum(std.c.getErrno(-1)))});
.{ c.strerror(@enumToInt(std.c.getErrno(-1))) });
} }

View file

@ -11,7 +11,7 @@ pub fn castClamp(comptime T: type, x: anytype) T {
} else if (std.math.minInt(@TypeOf(x)) < std.math.minInt(T) and x < std.math.minInt(T)) { } else if (std.math.minInt(@TypeOf(x)) < std.math.minInt(T) and x < std.math.minInt(T)) {
return std.math.minInt(T); return std.math.minInt(T);
} else { } else {
return @intCast(T, x); return @as(T, @intCast(x));
} }
} }
@ -19,8 +19,8 @@ pub fn castClamp(comptime T: type, x: anytype) T {
pub fn castTruncate(comptime T: type, x: anytype) T { pub fn castTruncate(comptime T: type, x: anytype) T {
const Ti = @typeInfo(T).Int; const Ti = @typeInfo(T).Int;
const Xi = @typeInfo(@TypeOf(x)).Int; const Xi = @typeInfo(@TypeOf(x)).Int;
const nx = if (Xi.signedness != Ti.signedness) @bitCast(std.meta.Int(Ti.signedness, Xi.bits), x) else x; const nx = if (Xi.signedness != Ti.signedness) @as(std.meta.Int(Ti.signedness, Xi.bits), @bitCast(x)) else x;
return if (Xi.bits > Ti.bits) @truncate(T, nx) else nx; return if (Xi.bits > Ti.bits) @as(T, @truncate(nx)) else nx;
} }
// Multiplies by 512, saturating. // Multiplies by 512, saturating.
@ -44,8 +44,8 @@ pub fn strnatcmp(a: [:0]const u8, b: [:0]const u8) std.math.Order {
var bi: usize = 0; var bi: usize = 0;
const isDigit = std.ascii.isDigit; const isDigit = std.ascii.isDigit;
while (true) { while (true) {
while (std.ascii.isSpace(a[ai])) ai += 1; while (std.ascii.isWhitespace(a[ai])) ai += 1;
while (std.ascii.isSpace(b[bi])) bi += 1; while (std.ascii.isWhitespace(b[bi])) bi += 1;
if (isDigit(a[ai]) and isDigit(b[bi])) { if (isDigit(a[ai]) and isDigit(b[bi])) {
if (a[ai] == '0' or b[bi] == '0') { // compare_left if (a[ai] == '0' or b[bi] == '0') { // compare_left
@ -62,8 +62,7 @@ pub fn strnatcmp(a: [:0]const u8, b: [:0]const u8) std.math.Order {
var bias = std.math.Order.eq; var bias = std.math.Order.eq;
while (true) { while (true) {
if (!isDigit(a[ai]) and !isDigit(b[bi])) { if (!isDigit(a[ai]) and !isDigit(b[bi])) {
if (bias != .eq or (a[ai] == 0 and b[bi] == 0)) return bias if (bias != .eq or (a[ai] == 0 and b[bi] == 0)) return bias else break;
else break;
} }
if (!isDigit(a[ai])) return .lt; if (!isDigit(a[ai])) return .lt;
if (!isDigit(b[bi])) return .gt; if (!isDigit(b[bi])) return .gt;