mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-12 17:08:39 -09:00
Consolidate @cImports into a single c.zig
Which is, AFAIK, a recommended practice. Reduces the number of times translate-c is being run and (most likely) simplifies a possible future transition if/when @cImport is thrown out of the language. Also uses zstd.h instead of my own definitions, mainly because I plan to use the streaming API as well and those need more definitions.
This commit is contained in:
parent
28d9eaecab
commit
bd442673d2
9 changed files with 52 additions and 50 deletions
|
|
@ -7,9 +7,7 @@ const model = @import("model.zig");
|
||||||
const sink = @import("sink.zig");
|
const sink = @import("sink.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
const ui = @import("ui.zig");
|
const ui = @import("ui.zig");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
extern fn ZSTD_compress(dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, srcSize: usize, compressionLevel: c_int) usize;
|
|
||||||
extern fn ZSTD_isError(code: usize) c_uint;
|
|
||||||
|
|
||||||
pub const global = struct {
|
pub const global = struct {
|
||||||
var fd: std.fs.File = undefined;
|
var fd: std.fs.File = undefined;
|
||||||
|
|
@ -65,9 +63,6 @@ inline fn blockHeader(id: u4, len: u28) [4]u8 { return bigu32((@as(u32, id) << 2
|
||||||
|
|
||||||
inline fn cborByte(major: CborMajor, arg: u5) u8 { return (@as(u8, @intFromEnum(major)) << 5) | arg; }
|
inline fn cborByte(major: CborMajor, arg: u5) u8 { return (@as(u8, @intFromEnum(major)) << 5) | arg; }
|
||||||
|
|
||||||
// ZSTD_COMPRESSBOUND(), assuming input does not exceed ZSTD_MAX_INPUT_SIZE
|
|
||||||
fn compressBound(size: usize) usize { return size + (size>>8) + (if (size < (128<<10)) ((128<<10) - size) >> 11 else 0); }
|
|
||||||
|
|
||||||
|
|
||||||
// (Uncompressed) data block size.
|
// (Uncompressed) data block size.
|
||||||
// Start with 64k, then use increasingly larger block sizes as the export file
|
// Start with 64k, then use increasingly larger block sizes as the export file
|
||||||
|
|
@ -100,8 +95,8 @@ pub const Thread = struct {
|
||||||
|
|
||||||
fn compressZstd(in: []const u8, out: []u8) usize {
|
fn compressZstd(in: []const u8, out: []u8) usize {
|
||||||
while (true) {
|
while (true) {
|
||||||
const r = ZSTD_compress(out.ptr, out.len, in.ptr, in.len, main.config.complevel);
|
const r = c.ZSTD_compress(out.ptr, out.len, in.ptr, in.len, main.config.complevel);
|
||||||
if (ZSTD_isError(r) == 0) return r;
|
if (c.ZSTD_isError(r) == 0) return r;
|
||||||
ui.oom(); // That *ought* to be the only reason the above call can fail.
|
ui.oom(); // That *ought* to be the only reason the above call can fail.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +105,7 @@ pub const Thread = struct {
|
||||||
var out = std.ArrayList(u8).init(main.allocator);
|
var out = std.ArrayList(u8).init(main.allocator);
|
||||||
if (t.block_num == std.math.maxInt(u32) or t.off == 0) return out;
|
if (t.block_num == std.math.maxInt(u32) or t.off == 0) return out;
|
||||||
|
|
||||||
out.ensureTotalCapacityPrecise(12 + compressBound(t.off)) catch unreachable;
|
out.ensureTotalCapacityPrecise(12 + c.ZSTD_COMPRESSBOUND(t.off)) catch unreachable;
|
||||||
out.items.len = out.capacity;
|
out.items.len = out.capacity;
|
||||||
const bodylen = compressZstd(t.buf[0..t.off], out.items[8..]);
|
const bodylen = compressZstd(t.buf[0..t.off], out.items[8..]);
|
||||||
out.items.len = 12 + bodylen;
|
out.items.len = 12 + bodylen;
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@ const util = @import("util.zig");
|
||||||
const sink = @import("sink.zig");
|
const sink = @import("sink.zig");
|
||||||
const ui = @import("ui.zig");
|
const ui = @import("ui.zig");
|
||||||
const bin_export = @import("bin_export.zig");
|
const bin_export = @import("bin_export.zig");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
extern fn ZSTD_decompress(dst: ?*anyopaque, dstCapacity: usize, src: ?*const anyopaque, compressedSize: usize) usize;
|
|
||||||
extern fn ZSTD_getFrameContentSize(src: ?*const anyopaque, srcSize: usize) c_ulonglong;
|
|
||||||
|
|
||||||
|
|
||||||
const CborMajor = bin_export.CborMajor;
|
const CborMajor = bin_export.CborMajor;
|
||||||
|
|
@ -103,11 +101,11 @@ fn readBlock(num: u32) []const u8 {
|
||||||
catch |e| ui.die("Error reading from file: {s}\n", .{ui.errorString(e)});
|
catch |e| ui.die("Error reading from file: {s}\n", .{ui.errorString(e)});
|
||||||
if (rdlen != buf.len) die();
|
if (rdlen != buf.len) die();
|
||||||
|
|
||||||
const rawlen = ZSTD_getFrameContentSize(buf.ptr, buf.len);
|
const rawlen = c.ZSTD_getFrameContentSize(buf.ptr, buf.len);
|
||||||
if (rawlen <= 0 or rawlen >= (1<<24)) die();
|
if (rawlen <= 0 or rawlen >= (1<<24)) die();
|
||||||
block.data = main.allocator.alloc(u8, @intCast(rawlen)) catch unreachable;
|
block.data = main.allocator.alloc(u8, @intCast(rawlen)) catch unreachable;
|
||||||
|
|
||||||
const res = ZSTD_decompress(block.data.ptr, block.data.len, buf.ptr, buf.len);
|
const res = c.ZSTD_decompress(block.data.ptr, block.data.len, buf.ptr, buf.len);
|
||||||
if (res != block.data.len) ui.die("Error decompressing block {} (expected {} got {})\n", .{ num, block.data.len, res });
|
if (res != block.data.len) ui.die("Error decompressing block {} (expected {} got {})\n", .{ num, block.data.len, res });
|
||||||
|
|
||||||
return block.data;
|
return block.data;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const mem_sink = @import("mem_sink.zig");
|
||||||
const bin_reader = @import("bin_reader.zig");
|
const bin_reader = @import("bin_reader.zig");
|
||||||
const delete = @import("delete.zig");
|
const delete = @import("delete.zig");
|
||||||
const ui = @import("ui.zig");
|
const ui = @import("ui.zig");
|
||||||
const c = @cImport(@cInclude("time.h"));
|
const c = @import("c.zig").c;
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
|
||||||
// Currently opened directory.
|
// Currently opened directory.
|
||||||
|
|
@ -644,8 +644,8 @@ const info = struct {
|
||||||
fn keyInput(ch: i32) bool {
|
fn keyInput(ch: i32) bool {
|
||||||
if (entry.?.pack.etype == .link) {
|
if (entry.?.pack.etype == .link) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
'1', 'h', ui.c.KEY_LEFT => { set(entry, .info); return true; },
|
'1', 'h', c.KEY_LEFT => { set(entry, .info); return true; },
|
||||||
'2', 'l', ui.c.KEY_RIGHT => { set(entry, .links); return true; },
|
'2', 'l', c.KEY_RIGHT => { set(entry, .links); return true; },
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -802,9 +802,9 @@ const help = struct {
|
||||||
'1' => tab = .keys,
|
'1' => tab = .keys,
|
||||||
'2' => tab = .flags,
|
'2' => tab = .flags,
|
||||||
'3' => tab = .about,
|
'3' => tab = .about,
|
||||||
'h', ui.c.KEY_LEFT => tab = if (tab == .about) .flags else .keys,
|
'h', c.KEY_LEFT => tab = if (tab == .about) .flags else .keys,
|
||||||
'l', ui.c.KEY_RIGHT => tab = if (tab == .keys) .flags else .about,
|
'l', c.KEY_RIGHT => tab = if (tab == .keys) .flags else .about,
|
||||||
'j', ' ', ui.c.KEY_DOWN, ui.c.KEY_NPAGE => {
|
'j', ' ', c.KEY_DOWN, c.KEY_NPAGE => {
|
||||||
const max = switch (tab) {
|
const max = switch (tab) {
|
||||||
.keys => keys.len/2 - keylines,
|
.keys => keys.len/2 - keylines,
|
||||||
else => @as(u32, 0),
|
else => @as(u32, 0),
|
||||||
|
|
@ -812,7 +812,7 @@ const help = struct {
|
||||||
if (offset < max)
|
if (offset < max)
|
||||||
offset += 1;
|
offset += 1;
|
||||||
},
|
},
|
||||||
'k', ui.c.KEY_UP, ui.c.KEY_PPAGE => { if (offset > 0) offset -= 1; },
|
'k', c.KEY_UP, c.KEY_PPAGE => { if (offset > 0) offset -= 1; },
|
||||||
else => state = .main,
|
else => state = .main,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -917,16 +917,16 @@ fn sortToggle(col: main.config.SortCol, default_order: main.config.SortOrder) vo
|
||||||
|
|
||||||
fn keyInputSelection(ch: i32, idx: *usize, len: usize, page: u32) bool {
|
fn keyInputSelection(ch: i32, idx: *usize, len: usize, page: u32) bool {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
'j', ui.c.KEY_DOWN => {
|
'j', c.KEY_DOWN => {
|
||||||
if (idx.*+1 < len) idx.* += 1;
|
if (idx.*+1 < len) idx.* += 1;
|
||||||
},
|
},
|
||||||
'k', ui.c.KEY_UP => {
|
'k', c.KEY_UP => {
|
||||||
if (idx.* > 0) idx.* -= 1;
|
if (idx.* > 0) idx.* -= 1;
|
||||||
},
|
},
|
||||||
ui.c.KEY_HOME => idx.* = 0,
|
c.KEY_HOME => idx.* = 0,
|
||||||
ui.c.KEY_END, ui.c.KEY_LL => idx.* = len -| 1,
|
c.KEY_END, c.KEY_LL => idx.* = len -| 1,
|
||||||
ui.c.KEY_PPAGE => idx.* = idx.* -| page,
|
c.KEY_PPAGE => idx.* = idx.* -| page,
|
||||||
ui.c.KEY_NPAGE => idx.* = @min(len -| 1, idx.* + page),
|
c.KEY_NPAGE => idx.* = @min(len -| 1, idx.* + page),
|
||||||
else => return false,
|
else => return false,
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1017,7 +1017,7 @@ pub fn keyInput(ch: i32) void {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
10, 'l', ui.c.KEY_RIGHT => {
|
10, 'l', c.KEY_RIGHT => {
|
||||||
if (dir_items.items.len == 0) {
|
if (dir_items.items.len == 0) {
|
||||||
} else if (dir_items.items[cursor_idx]) |e| {
|
} else if (dir_items.items[cursor_idx]) |e| {
|
||||||
if (e.dir()) |d| {
|
if (e.dir()) |d| {
|
||||||
|
|
@ -1032,7 +1032,7 @@ pub fn keyInput(ch: i32) void {
|
||||||
state = .main;
|
state = .main;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'h', '<', ui.c.KEY_BACKSPACE, ui.c.KEY_LEFT => {
|
'h', '<', c.KEY_BACKSPACE, c.KEY_LEFT => {
|
||||||
if (dir_parents.items.len > 1) {
|
if (dir_parents.items.len > 1) {
|
||||||
//const h = dir_parent.entry.nameHash();
|
//const h = dir_parent.entry.nameHash();
|
||||||
enterParent();
|
enterParent();
|
||||||
|
|
|
||||||
17
src/c.zig
Normal file
17
src/c.zig
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// SPDX-FileCopyrightText: Yorhel <projects@yorhel.nl>
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pub const c = @cImport({
|
||||||
|
@cDefine("_XOPEN_SOURCE", "1"); // for wcwidth()
|
||||||
|
@cInclude("stdio.h"); // fopen(), used to initialize ncurses
|
||||||
|
@cInclude("string.h"); // strerror()
|
||||||
|
@cInclude("time.h"); // strftime()
|
||||||
|
@cInclude("wchar.h"); // wcwidth()
|
||||||
|
@cInclude("locale.h"); // setlocale() and localeconv()
|
||||||
|
@cInclude("fnmatch.h"); // fnmatch()
|
||||||
|
if (@import("builtin").os.tag == .linux) {
|
||||||
|
@cInclude("sys/vfs.h"); // statfs()
|
||||||
|
}
|
||||||
|
@cInclude("curses.h");
|
||||||
|
@cInclude("zstd.h");
|
||||||
|
});
|
||||||
|
|
@ -7,6 +7,7 @@ const model = @import("model.zig");
|
||||||
const ui = @import("ui.zig");
|
const ui = @import("ui.zig");
|
||||||
const browser = @import("browser.zig");
|
const browser = @import("browser.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
var parent: *model.Dir = undefined;
|
var parent: *model.Dir = undefined;
|
||||||
var entry: *model.Entry = undefined;
|
var entry: *model.Entry = undefined;
|
||||||
|
|
@ -178,11 +179,11 @@ pub fn draw() void {
|
||||||
pub fn keyInput(ch: i32) void {
|
pub fn keyInput(ch: i32) void {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.confirm => switch (ch) {
|
.confirm => switch (ch) {
|
||||||
'h', ui.c.KEY_LEFT => confirm = switch (confirm) {
|
'h', c.KEY_LEFT => confirm = switch (confirm) {
|
||||||
.ignore => .no,
|
.ignore => .no,
|
||||||
else => .yes,
|
else => .yes,
|
||||||
},
|
},
|
||||||
'l', ui.c.KEY_RIGHT => confirm = switch (confirm) {
|
'l', c.KEY_RIGHT => confirm = switch (confirm) {
|
||||||
.yes => .no,
|
.yes => .no,
|
||||||
else => .ignore,
|
else => .ignore,
|
||||||
},
|
},
|
||||||
|
|
@ -202,11 +203,11 @@ pub fn keyInput(ch: i32) void {
|
||||||
main.state = .browse;
|
main.state = .browse;
|
||||||
},
|
},
|
||||||
.err => switch (ch) {
|
.err => switch (ch) {
|
||||||
'h', ui.c.KEY_LEFT => error_option = switch (error_option) {
|
'h', c.KEY_LEFT => error_option = switch (error_option) {
|
||||||
.all => .ignore,
|
.all => .ignore,
|
||||||
else => .abort,
|
else => .abort,
|
||||||
},
|
},
|
||||||
'l', ui.c.KEY_RIGHT => error_option = switch (error_option) {
|
'l', c.KEY_RIGHT => error_option = switch (error_option) {
|
||||||
.abort => .ignore,
|
.abort => .ignore,
|
||||||
else => .all,
|
else => .all,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const main = @import("main.zig");
|
const main = @import("main.zig");
|
||||||
const c = @cImport(@cInclude("fnmatch.h"));
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
// Reference:
|
// Reference:
|
||||||
// https://manned.org/glob.7
|
// https://manned.org/glob.7
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ const browser = @import("browser.zig");
|
||||||
const delete = @import("delete.zig");
|
const delete = @import("delete.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
const exclude = @import("exclude.zig");
|
const exclude = @import("exclude.zig");
|
||||||
const c = @cImport(@cInclude("locale.h"));
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
test "imports" {
|
test "imports" {
|
||||||
_ = model;
|
_ = model;
|
||||||
|
|
@ -634,14 +634,14 @@ pub fn handleEvent(block: bool, force_draw: bool) void {
|
||||||
while (ui.oom_threads.load(.monotonic) > 0) ui.oom();
|
while (ui.oom_threads.load(.monotonic) > 0) ui.oom();
|
||||||
|
|
||||||
if (block or force_draw or event_delay_timer.read() > config.update_delay) {
|
if (block or force_draw or event_delay_timer.read() > config.update_delay) {
|
||||||
if (ui.inited) _ = ui.c.erase();
|
if (ui.inited) _ = c.erase();
|
||||||
switch (state) {
|
switch (state) {
|
||||||
.scan, .refresh => sink.draw(),
|
.scan, .refresh => sink.draw(),
|
||||||
.browse => browser.draw(),
|
.browse => browser.draw(),
|
||||||
.delete => delete.draw(),
|
.delete => delete.draw(),
|
||||||
.shell => unreachable,
|
.shell => unreachable,
|
||||||
}
|
}
|
||||||
if (ui.inited) _ = ui.c.refresh();
|
if (ui.inited) _ = c.refresh();
|
||||||
event_delay_timer.reset();
|
event_delay_timer.reset();
|
||||||
}
|
}
|
||||||
if (!ui.inited) {
|
if (!ui.inited) {
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,13 @@ const model = @import("model.zig");
|
||||||
const sink = @import("sink.zig");
|
const sink = @import("sink.zig");
|
||||||
const ui = @import("ui.zig");
|
const ui = @import("ui.zig");
|
||||||
const exclude = @import("exclude.zig");
|
const exclude = @import("exclude.zig");
|
||||||
const c_statfs = @cImport(@cInclude("sys/vfs.h"));
|
const c = @import("c.zig").c;
|
||||||
|
|
||||||
|
|
||||||
// This function only works on Linux
|
// This function only works on Linux
|
||||||
fn isKernfs(dir: std.fs.Dir) bool {
|
fn isKernfs(dir: std.fs.Dir) bool {
|
||||||
var buf: c_statfs.struct_statfs = undefined;
|
var buf: c.struct_statfs = undefined;
|
||||||
if (c_statfs.fstatfs(dir.fd, &buf) != 0) return false; // silently ignoring errors isn't too nice.
|
if (c.fstatfs(dir.fd, &buf) != 0) return false; // silently ignoring errors isn't too nice.
|
||||||
const iskern = switch (util.castTruncate(u32, buf.f_type)) {
|
const iskern = switch (util.castTruncate(u32, buf.f_type)) {
|
||||||
// These numbers are documented in the Linux 'statfs(2)' man page, so I assume they're stable.
|
// These numbers are documented in the Linux 'statfs(2)' man page, so I assume they're stable.
|
||||||
0x42494e4d, // BINFMTFS_MAGIC
|
0x42494e4d, // BINFMTFS_MAGIC
|
||||||
|
|
|
||||||
11
src/ui.zig
11
src/ui.zig
|
|
@ -6,16 +6,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const main = @import("main.zig");
|
const main = @import("main.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
const c = @import("c.zig").c;
|
||||||
pub const c = @cImport({
|
|
||||||
@cDefine("_XOPEN_SOURCE", "1");
|
|
||||||
@cInclude("stdio.h");
|
|
||||||
@cInclude("string.h");
|
|
||||||
@cInclude("curses.h");
|
|
||||||
@cInclude("time.h");
|
|
||||||
@cInclude("wchar.h");
|
|
||||||
@cInclude("locale.h");
|
|
||||||
});
|
|
||||||
|
|
||||||
pub var inited: bool = false;
|
pub var inited: bool = false;
|
||||||
pub var main_thread: std.Thread.Id = undefined;
|
pub var main_thread: std.Thread.Id = undefined;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue