Fix json output with invalid unicode.
This commit is contained in:
parent
b7f616a945
commit
419b99c277
|
@ -34,11 +34,6 @@ pub fn build(b: *Builder) void {
|
||||||
"weather_location",
|
"weather_location",
|
||||||
"weather_location",
|
"weather_location",
|
||||||
) orelse "";
|
) orelse "";
|
||||||
if (weather_location.len == 0) {
|
|
||||||
weather_location = "\"\"";
|
|
||||||
} else if (weather_location[0] != '"') {
|
|
||||||
weather_location = std.fmt.allocPrint(b.allocator, "\"{}\"", .{weather_location}) catch "\"\"";
|
|
||||||
}
|
|
||||||
exe.addBuildOption([]const u8, "weather_location", weather_location);
|
exe.addBuildOption([]const u8, "weather_location", weather_location);
|
||||||
|
|
||||||
//exe.strip = true;
|
//exe.strip = true;
|
||||||
|
|
67
build_runner.zig
Normal file
67
build_runner.zig
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
const root = @import("build.zig");
|
||||||
|
const std = @import("std");
|
||||||
|
const io = std.io;
|
||||||
|
const fmt = std.fmt;
|
||||||
|
const Builder = std.build.Builder;
|
||||||
|
const Pkg = std.build.Pkg;
|
||||||
|
const InstallArtifactStep = std.build.InstallArtifactStep;
|
||||||
|
const LibExeObjStep = std.build.LibExeObjStep;
|
||||||
|
const ArrayList = std.ArrayList;
|
||||||
|
|
||||||
|
///! This is a modified build runner to extract information out of build.zig
|
||||||
|
///! Modified from the std.special.build_runner
|
||||||
|
pub fn main() !void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
const allocator = &arena.allocator;
|
||||||
|
|
||||||
|
const builder = try Builder.create(allocator, "", "", "");
|
||||||
|
defer builder.destroy();
|
||||||
|
|
||||||
|
try runBuild(builder);
|
||||||
|
|
||||||
|
const stdout_stream = io.getStdOut().outStream();
|
||||||
|
|
||||||
|
// TODO: We currently add packages from every LibExeObj step that the install step depends on.
|
||||||
|
// Should we error out or keep one step or something similar?
|
||||||
|
// We also flatten them, we should probably keep the nested structure.
|
||||||
|
for (builder.top_level_steps.items) |tls| {
|
||||||
|
for (tls.step.dependencies.items) |step| {
|
||||||
|
try processStep(stdout_stream, step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn processStep(stdout_stream: anytype, step: *std.build.Step) anyerror!void {
|
||||||
|
if (step.cast(InstallArtifactStep)) |install_exe| {
|
||||||
|
for (install_exe.artifact.packages.items) |pkg| {
|
||||||
|
try processPackage(stdout_stream, pkg);
|
||||||
|
}
|
||||||
|
} else if (step.cast(LibExeObjStep)) |exe| {
|
||||||
|
for (exe.packages.items) |pkg| {
|
||||||
|
try processPackage(stdout_stream, pkg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (step.dependencies.items) |unknown_step| {
|
||||||
|
try processStep(stdout_stream, unknown_step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn processPackage(out_stream: anytype, pkg: Pkg) anyerror!void {
|
||||||
|
try out_stream.print("{}\x00{}\n", .{ pkg.name, pkg.path });
|
||||||
|
if (pkg.dependencies) |dependencies| {
|
||||||
|
for (dependencies) |dep| {
|
||||||
|
try processPackage(out_stream, dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runBuild(builder: *Builder) anyerror!void {
|
||||||
|
switch (@typeInfo(@TypeOf(root.build).ReturnType)) {
|
||||||
|
.Void => root.build(builder),
|
||||||
|
.ErrorUnion => try root.build(builder),
|
||||||
|
else => @compileError("expected return type of build to be 'void' or '!void'"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ const log = std.log;
|
||||||
const terminal_version = @import("build_options").terminal_version;
|
const terminal_version = @import("build_options").terminal_version;
|
||||||
const debug_allocator = @import("build_options").debug_allocator;
|
const debug_allocator = @import("build_options").debug_allocator;
|
||||||
const disable_terminal_mouse = @import("build_options").disable_terminal_mouse;
|
const disable_terminal_mouse = @import("build_options").disable_terminal_mouse;
|
||||||
|
const json = @import("json.zig");
|
||||||
|
|
||||||
fn readFromSignalFd(signal_fd: std.os.fd_t) !void {
|
fn readFromSignalFd(signal_fd: std.os.fd_t) !void {
|
||||||
var buf: [@sizeOf(os.linux.signalfd_siginfo)]u8 align(8) = undefined;
|
var buf: [@sizeOf(os.linux.signalfd_siginfo)]u8 align(8) = undefined;
|
||||||
|
@ -14,31 +15,6 @@ fn readFromSignalFd(signal_fd: std.os.fd_t) !void {
|
||||||
return error.Shutdown;
|
return error.Shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn utf8ValidateSlice(s: []const u8) bool {
|
|
||||||
var i: usize = 0;
|
|
||||||
while (i < s.len) {
|
|
||||||
if (std.unicode.utf8ByteSequenceLength(s[i])) |cp_len| {
|
|
||||||
if (i + cp_len > s.len) {
|
|
||||||
log.err(.uni, "oh nos: {} {} {}\n", .{i + cp_len, i, s.len});
|
|
||||||
log.err(.uni, "oh no: {}\n", .{s[i .. i + cp_len]});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std.unicode.utf8Decode(s[i .. i + cp_len])) |_| {} else |_| {
|
|
||||||
log.err(.uni, "oh no: {}\n", .{s[i .. i + cp_len]});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
i += cp_len;
|
|
||||||
} else |err| {
|
|
||||||
log.err(.uni, "oh noz: {} {} {} {} \"{}\" \n", .{s[i], s.len, i, err, s[0..i+1]});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn sigemptyset(set: *std.os.sigset_t) void {
|
fn sigemptyset(set: *std.os.sigset_t) void {
|
||||||
for (set) |*val| {
|
for (set) |*val| {
|
||||||
val.* = 0;
|
val.* = 0;
|
||||||
|
@ -103,7 +79,7 @@ pub const Bar = struct {
|
||||||
// Serialize all bar items and put on stdout.
|
// Serialize all bar items and put on stdout.
|
||||||
try self.out_file.writer().writeAll("[");
|
try self.out_file.writer().writeAll("[");
|
||||||
for (self.infos.items) |info, i| {
|
for (self.infos.items) |info, i| {
|
||||||
try std.json.stringify(info, .{}, self.out_file.writer());
|
try json.stringify(info, .{}, self.out_file.writer());
|
||||||
|
|
||||||
if (i < self.infos.items.len - 1) {
|
if (i < self.infos.items.len - 1) {
|
||||||
try self.out_file.writer().writeAll(",");
|
try self.out_file.writer().writeAll(",");
|
||||||
|
@ -213,8 +189,8 @@ pub const Bar = struct {
|
||||||
current_info_line_length = current_info_line_length + 1;
|
current_info_line_length = current_info_line_length + 1;
|
||||||
}
|
}
|
||||||
// Get the first widget that the click is in.
|
// Get the first widget that the click is in.
|
||||||
if (click_x_position <= current_info_line_length) {
|
if (click_x_position <= current_info_line_length) {
|
||||||
self.dispatch_click_event(infoItem.name, .{ .button = .LeftClick, .x = click_x_position, .y=0,.scale=1, .height=1, .relative_x = click_x_position - previous_length}) catch {};
|
self.dispatch_click_event(infoItem.name, .{ .button = .LeftClick, .x = click_x_position, .y = 0, .scale = 1, .height = 1, .relative_x = click_x_position - previous_length }) catch {};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Compensate for the | seporator on the terminal.
|
// Compensate for the | seporator on the terminal.
|
||||||
|
@ -239,9 +215,9 @@ pub const Bar = struct {
|
||||||
// instead of looping and getting it, maybe then it would make more sense?
|
// instead of looping and getting it, maybe then it would make more sense?
|
||||||
// Anyway this just strips off the prefix of ',' so I can parse the json.
|
// Anyway this just strips off the prefix of ',' so I can parse the json.
|
||||||
if (line[0] == ',') line = line[1..line.len];
|
if (line[0] == ',') line = line[1..line.len];
|
||||||
const parseOptions = std.json.ParseOptions{ .allocator = self.allocator };
|
const parseOptions = json.ParseOptions{ .allocator = self.allocator };
|
||||||
const data = try std.json.parse(MouseEvent, &std.json.TokenStream.init(line), parseOptions);
|
const data = try json.parse(MouseEvent, &json.TokenStream.init(line), parseOptions);
|
||||||
defer std.json.parseFree(MouseEvent, data, parseOptions);
|
defer json.parseFree(MouseEvent, data, parseOptions);
|
||||||
|
|
||||||
self.dispatch_click_event(data.name, data) catch {};
|
self.dispatch_click_event(data.name, data) catch {};
|
||||||
// If mouse_event needs to store the event for after the call is finished,
|
// If mouse_event needs to store the event for after the call is finished,
|
||||||
|
@ -316,9 +292,6 @@ pub const Bar = struct {
|
||||||
}
|
}
|
||||||
// If we reach here then it changed.
|
// If we reach here then it changed.
|
||||||
try self.free_info(infoItem);
|
try self.free_info(infoItem);
|
||||||
if (!utf8ValidateSlice(info.full_text)) {
|
|
||||||
std.log.err(.barerr, "Oh No: {}\n", .{info.full_text});
|
|
||||||
}
|
|
||||||
self.infos.items[index] = try self.dupe_info(info);
|
self.infos.items[index] = try self.dupe_info(info);
|
||||||
try self.print_infos(false);
|
try self.print_infos(false);
|
||||||
}
|
}
|
||||||
|
@ -332,7 +305,7 @@ pub fn initBar(allocator: *std.mem.Allocator) Bar {
|
||||||
.widgets = undefined,
|
.widgets = undefined,
|
||||||
.running = false,
|
.running = false,
|
||||||
.infos = std.ArrayList(Info).init(allocator),
|
.infos = std.ArrayList(Info).init(allocator),
|
||||||
.items_mutex = std.Mutex.init(),
|
.items_mutex = std.Mutex{},
|
||||||
.out_file = std.io.getStdOut(),
|
.out_file = std.io.getStdOut(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
1810
src/bar/json.zig
Normal file
1810
src/bar/json.zig
Normal file
File diff suppressed because it is too large
Load diff
250
src/bar/json/write_stream.zig
Normal file
250
src/bar/json/write_stream.zig
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
const std = @import("../std.zig");
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
const maxInt = std.math.maxInt;
|
||||||
|
const State = enum {
|
||||||
|
Complete,
|
||||||
|
Value,
|
||||||
|
ArrayStart,
|
||||||
|
Array,
|
||||||
|
ObjectStart,
|
||||||
|
Object,
|
||||||
|
};
|
||||||
|
pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
|
||||||
|
return struct {
|
||||||
|
const Self = @This();
|
||||||
|
pub const Stream = OutStream;
|
||||||
|
whitespace: std.json.StringifyOptions.Whitespace = std.json.StringifyOptions.Whitespace{
|
||||||
|
.indent_level = 0,
|
||||||
|
.indent = .{ .Space = 1 },
|
||||||
|
},
|
||||||
|
stream: OutStream,
|
||||||
|
state_index: usize,
|
||||||
|
state: [max_depth]State,
|
||||||
|
pub fn init(stream: OutStream) Self {
|
||||||
|
var self = Self{
|
||||||
|
.stream = stream,
|
||||||
|
.state_index = 1,
|
||||||
|
.state = undefined,
|
||||||
|
};
|
||||||
|
self.state[0] = .Complete;
|
||||||
|
self.state[1] = .Value;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
pub fn beginArray(self: *Self) !void {
|
||||||
|
try self.stream.writeByte('[');
|
||||||
|
self.state[self.state_index] = State.ArrayStart;
|
||||||
|
self.whitespace.indent_level += 1;
|
||||||
|
}
|
||||||
|
pub fn beginObject(self: *Self) !void {
|
||||||
|
try self.stream.writeByte('{');
|
||||||
|
self.state[self.state_index] = State.ObjectStart;
|
||||||
|
self.whitespace.indent_level += 1;
|
||||||
|
}
|
||||||
|
pub fn arrayElem(self: *Self) !void {
|
||||||
|
const state = self.state[self.state_index];
|
||||||
|
switch (state) {
|
||||||
|
.Complete => unreachable,
|
||||||
|
.Value => unreachable,
|
||||||
|
.ObjectStart => unreachable,
|
||||||
|
.Object => unreachable,
|
||||||
|
.Array, .ArrayStart => {
|
||||||
|
if (state == .Array) {
|
||||||
|
try self.stream.writeByte(',');
|
||||||
|
}
|
||||||
|
self.state[self.state_index] = .Array;
|
||||||
|
self.pushState(.Value);
|
||||||
|
try self.indent();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn objectField(self: *Self, name: []const u8) !void {
|
||||||
|
const state = self.state[self.state_index];
|
||||||
|
switch (state) {
|
||||||
|
.Complete => unreachable,
|
||||||
|
.Value => unreachable,
|
||||||
|
.ArrayStart => unreachable,
|
||||||
|
.Array => unreachable,
|
||||||
|
.Object, .ObjectStart => {
|
||||||
|
if (state == .Object) {
|
||||||
|
try self.stream.writeByte(',');
|
||||||
|
}
|
||||||
|
self.state[self.state_index] = .Object;
|
||||||
|
self.pushState(.Value);
|
||||||
|
try self.indent();
|
||||||
|
try self.writeEscapedString(name);
|
||||||
|
try self.stream.writeByte(':');
|
||||||
|
if (self.whitespace.separator) {
|
||||||
|
try self.stream.writeByte(' ');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn endArray(self: *Self) !void {
|
||||||
|
switch (self.state[self.state_index]) {
|
||||||
|
.Complete => unreachable,
|
||||||
|
.Value => unreachable,
|
||||||
|
.ObjectStart => unreachable,
|
||||||
|
.Object => unreachable,
|
||||||
|
.ArrayStart => {
|
||||||
|
self.whitespace.indent_level -= 1;
|
||||||
|
try self.stream.writeByte(']');
|
||||||
|
self.popState();
|
||||||
|
},
|
||||||
|
.Array => {
|
||||||
|
self.whitespace.indent_level -= 1;
|
||||||
|
try self.indent();
|
||||||
|
self.popState();
|
||||||
|
try self.stream.writeByte(']');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn endObject(self: *Self) !void {
|
||||||
|
switch (self.state[self.state_index]) {
|
||||||
|
.Complete => unreachable,
|
||||||
|
.Value => unreachable,
|
||||||
|
.ArrayStart => unreachable,
|
||||||
|
.Array => unreachable,
|
||||||
|
.ObjectStart => {
|
||||||
|
self.whitespace.indent_level -= 1;
|
||||||
|
try self.stream.writeByte('}');
|
||||||
|
self.popState();
|
||||||
|
},
|
||||||
|
.Object => {
|
||||||
|
self.whitespace.indent_level -= 1;
|
||||||
|
try self.indent();
|
||||||
|
self.popState();
|
||||||
|
try self.stream.writeByte('}');
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn emitNull(self: *Self) !void {
|
||||||
|
assert(self.state[self.state_index] == State.Value);
|
||||||
|
try self.stringify(null);
|
||||||
|
self.popState();
|
||||||
|
}
|
||||||
|
pub fn emitBool(self: *Self, value: bool) !void {
|
||||||
|
assert(self.state[self.state_index] == State.Value);
|
||||||
|
try self.stringify(value);
|
||||||
|
self.popState();
|
||||||
|
}
|
||||||
|
pub fn emitNumber(
|
||||||
|
self: *Self,
|
||||||
|
value: anytype,
|
||||||
|
) !void {
|
||||||
|
assert(self.state[self.state_index] == State.Value);
|
||||||
|
switch (@typeInfo(@TypeOf(value))) {
|
||||||
|
.Int => |info| {
|
||||||
|
if (info.bits < 53) {
|
||||||
|
try self.stream.print("{}", .{value});
|
||||||
|
self.popState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value < 4503599627370496 and (!info.is_signed or value > -4503599627370496)) {
|
||||||
|
try self.stream.print("{}", .{value});
|
||||||
|
self.popState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.ComptimeInt => {
|
||||||
|
return self.emitNumber(@as(std.math.IntFittingRange(value, value), value));
|
||||||
|
},
|
||||||
|
.Float, .ComptimeFloat => if (@floatCast(f64, value) == value) {
|
||||||
|
try self.stream.print("{}", .{@floatCast(f64, value)});
|
||||||
|
self.popState();
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
try self.stream.print("\"{}\"", .{value});
|
||||||
|
self.popState();
|
||||||
|
}
|
||||||
|
pub fn emitString(self: *Self, string: []const u8) !void {
|
||||||
|
assert(self.state[self.state_index] == State.Value);
|
||||||
|
try self.writeEscapedString(string);
|
||||||
|
self.popState();
|
||||||
|
}
|
||||||
|
fn writeEscapedString(self: *Self, string: []const u8) !void {
|
||||||
|
assert(std.unicode.utf8ValidateSlice(string));
|
||||||
|
try self.stringify(string);
|
||||||
|
}
|
||||||
|
pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void {
|
||||||
|
assert(self.state[self.state_index] == State.Value);
|
||||||
|
try self.stringify(json);
|
||||||
|
self.popState();
|
||||||
|
}
|
||||||
|
fn indent(self: *Self) !void {
|
||||||
|
assert(self.state_index >= 1);
|
||||||
|
try self.stream.writeByte('\n');
|
||||||
|
try self.whitespace.outputIndent(self.stream);
|
||||||
|
}
|
||||||
|
fn pushState(self: *Self, state: State) void {
|
||||||
|
self.state_index += 1;
|
||||||
|
self.state[self.state_index] = state;
|
||||||
|
}
|
||||||
|
fn popState(self: *Self) void {
|
||||||
|
self.state_index -= 1;
|
||||||
|
}
|
||||||
|
fn stringify(self: *Self, value: anytype) !void {
|
||||||
|
try std.json.stringify(value, std.json.StringifyOptions{
|
||||||
|
.whitespace = self.whitespace,
|
||||||
|
}, self.stream);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub fn writeStream(
|
||||||
|
out_stream: anytype,
|
||||||
|
comptime max_depth: usize,
|
||||||
|
) WriteStream(@TypeOf(out_stream), max_depth) {
|
||||||
|
return WriteStream(@TypeOf(out_stream), max_depth).init(out_stream);
|
||||||
|
}
|
||||||
|
test "json write stream" {
|
||||||
|
var out_buf: [1024]u8 = undefined;
|
||||||
|
var slice_stream = std.io.fixedBufferStream(&out_buf);
|
||||||
|
const out = slice_stream.outStream();
|
||||||
|
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
|
||||||
|
defer arena_allocator.deinit();
|
||||||
|
var w = std.json.writeStream(out, 10);
|
||||||
|
try w.beginObject();
|
||||||
|
try w.objectField("object");
|
||||||
|
try w.emitJson(try getJsonObject(&arena_allocator.allocator));
|
||||||
|
try w.objectField("string");
|
||||||
|
try w.emitString("This is a string");
|
||||||
|
try w.objectField("array");
|
||||||
|
try w.beginArray();
|
||||||
|
try w.arrayElem();
|
||||||
|
try w.emitString("Another string");
|
||||||
|
try w.arrayElem();
|
||||||
|
try w.emitNumber(@as(i32, 1));
|
||||||
|
try w.arrayElem();
|
||||||
|
try w.emitNumber(@as(f32, 3.5));
|
||||||
|
try w.endArray();
|
||||||
|
try w.objectField("int");
|
||||||
|
try w.emitNumber(@as(i32, 10));
|
||||||
|
try w.objectField("float");
|
||||||
|
try w.emitNumber(@as(f32, 3.5));
|
||||||
|
try w.endObject();
|
||||||
|
const result = slice_stream.getWritten();
|
||||||
|
const expected =
|
||||||
|
\\{
|
||||||
|
\\ "object": {
|
||||||
|
\\ "one": 1,
|
||||||
|
\\ "two": 2.0e+00
|
||||||
|
\\ },
|
||||||
|
\\ "string": "This is a string",
|
||||||
|
\\ "array": [
|
||||||
|
\\ "Another string",
|
||||||
|
\\ 1,
|
||||||
|
\\ 3.5e+00
|
||||||
|
\\ ],
|
||||||
|
\\ "int": 10,
|
||||||
|
\\ "float": 3.5e+00
|
||||||
|
\\}
|
||||||
|
;
|
||||||
|
std.testing.expect(std.mem.eql(u8, expected, result));
|
||||||
|
}
|
||||||
|
fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value {
|
||||||
|
var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
|
||||||
|
_ = try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });
|
||||||
|
_ = try value.Object.put("two", std.json.Value{ .Float = 2.0 });
|
||||||
|
return value;
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ const Info = @import("types/info.zig");
|
||||||
const debug_allocator = @import("build_options").debug_allocator;
|
const debug_allocator = @import("build_options").debug_allocator;
|
||||||
|
|
||||||
// Set the log level to warning
|
// Set the log level to warning
|
||||||
//pub const log_level: std.log.Level = .warn;
|
pub const log_level: std.log.Level = .warn;
|
||||||
// Define root.log to override the std implementation
|
// Define root.log to override the std implementation
|
||||||
pub fn log(
|
pub fn log(
|
||||||
comptime level: std.log.Level,
|
comptime level: std.log.Level,
|
||||||
|
@ -63,7 +63,6 @@ pub fn main() !void {
|
||||||
if (!debug_allocator) arena.deinit();
|
if (!debug_allocator) arena.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var bar = barImpl.initBar(allocator);
|
var bar = barImpl.initBar(allocator);
|
||||||
var br = Bar.init(&bar);
|
var br = Bar.init(&bar);
|
||||||
|
|
||||||
|
@ -78,8 +77,8 @@ pub fn main() !void {
|
||||||
bar.widgets = widgets[0..];
|
bar.widgets = widgets[0..];
|
||||||
try br.start();
|
try br.start();
|
||||||
if (debug_allocator) {
|
if (debug_allocator) {
|
||||||
std.log.debug(.main, "Finished cleanup, last allocation info.\n", .{});
|
std.debug.print("Finished cleanup, last allocation info.\n", .{});
|
||||||
std.log.debug(.main, "\n{}\n", .{dbgAlloc.info});
|
std.debug.print("\n{}\n", .{dbgAlloc.info});
|
||||||
dbgAlloc.printRemainingStackTraces();
|
dbgAlloc.printRemainingStackTraces();
|
||||||
dbgAlloc.deinit();
|
dbgAlloc.deinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,19 @@ pub const MemoryWidget = struct {
|
||||||
self.update_bar() catch {};
|
self.update_bar() catch {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_cache(self: *MemoryWidget) !void {
|
||||||
|
var buffer: [512 * 512]u8 = undefined;
|
||||||
|
var fba = std.heap.FixedBufferAllocator.init(&buffer);
|
||||||
|
var allocator = &fba.allocator;
|
||||||
|
var proc = try std.ChildProcess.init(&[_][]const u8{ "bash", "/home/kitteh/Scripts/drop-cache.sh" }, allocator);
|
||||||
|
proc.stdout_behavior = .Close;
|
||||||
|
proc.stdin_behavior = .Close;
|
||||||
|
proc.stderr_behavior = .Close;
|
||||||
|
try proc.spawn();
|
||||||
|
_ = try proc.kill();
|
||||||
|
proc.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
fn update_bar(self: *MemoryWidget) !void {
|
fn update_bar(self: *MemoryWidget) !void {
|
||||||
var buffer: [512]u8 = undefined;
|
var buffer: [512]u8 = undefined;
|
||||||
var fba = std.heap.FixedBufferAllocator.init(&buffer);
|
var fba = std.heap.FixedBufferAllocator.init(&buffer);
|
||||||
|
@ -191,6 +204,11 @@ pub const MemoryWidget = struct {
|
||||||
.full_text = text,
|
.full_text = text,
|
||||||
.markup = "pango",
|
.markup = "pango",
|
||||||
});
|
});
|
||||||
|
if (kibibytesToMegabytes(memInfo.cached) > 1000) {
|
||||||
|
self.clear_cache() catch |err| {
|
||||||
|
std.log.err(.memory, "Can't clear cache {}.\n", .{err});
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(self: *MemoryWidget) anyerror!void {
|
pub fn start(self: *MemoryWidget) anyerror!void {
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub const NetworkWidget = struct {
|
||||||
network_infos: std.ArrayList(NetworkInfo),
|
network_infos: std.ArrayList(NetworkInfo),
|
||||||
num_interfaces: u8 = 0,
|
num_interfaces: u8 = 0,
|
||||||
current_interface: u8 = 0,
|
current_interface: u8 = 0,
|
||||||
update_mutex: std.Mutex = std.Mutex.init(),
|
update_mutex: std.Mutex = std.Mutex{},
|
||||||
|
|
||||||
pub fn name(self: *NetworkWidget) []const u8 {
|
pub fn name(self: *NetworkWidget) []const u8 {
|
||||||
return "network";
|
return "network";
|
||||||
|
@ -94,12 +94,16 @@ pub const NetworkWidget = struct {
|
||||||
pub fn update_network_infos(self: *NetworkWidget) anyerror!void {
|
pub fn update_network_infos(self: *NetworkWidget) anyerror!void {
|
||||||
const lock = self.update_mutex.acquire();
|
const lock = self.update_mutex.acquire();
|
||||||
defer lock.release();
|
defer lock.release();
|
||||||
|
std.log.debug(.network, "Updating network info.\n", .{});
|
||||||
for (self.network_infos.items) |info| {
|
for (self.network_infos.items) |info| {
|
||||||
freeString(self.allocator, info.network_info);
|
freeString(self.allocator, info.network_info);
|
||||||
}
|
}
|
||||||
self.num_interfaces = 0;
|
self.num_interfaces = 0;
|
||||||
var proc = try std.ChildProcess.init(&[_][]const u8{ "nmcli", "-f", "common", "-c", "no", "d" }, self.allocator);
|
var proc = try std.ChildProcess.init(&[_][]const u8{ "nmcli", "-f", "common", "-c", "no", "d" }, self.allocator);
|
||||||
defer { _ = proc.kill() catch {}; proc.deinit(); }
|
defer {
|
||||||
|
_ = proc.kill() catch {};
|
||||||
|
proc.deinit();
|
||||||
|
}
|
||||||
proc.stdout_behavior = .Pipe;
|
proc.stdout_behavior = .Pipe;
|
||||||
try proc.spawn();
|
try proc.spawn();
|
||||||
var i: u8 = 0;
|
var i: u8 = 0;
|
||||||
|
@ -115,8 +119,8 @@ pub const NetworkWidget = struct {
|
||||||
const status = it.next();
|
const status = it.next();
|
||||||
const description = it.next();
|
const description = it.next();
|
||||||
if (connection_type) |t| if (!(eql(u8, t, "wifi") or eql(u8, t, "ethernet"))) continue;
|
if (connection_type) |t| if (!(eql(u8, t, "wifi") or eql(u8, t, "ethernet"))) continue;
|
||||||
try self.network_infos.resize(i+1);
|
try self.network_infos.resize(i + 1);
|
||||||
self.network_infos.items[i] = NetworkInfo{
|
self.network_infos.items[i] = NetworkInfo{
|
||||||
.network_type = toNetworkType(connection_type.?),
|
.network_type = toNetworkType(connection_type.?),
|
||||||
.network_status = toNetworkStatus(status.?),
|
.network_status = toNetworkStatus(status.?),
|
||||||
.network_info = try dupeString(self.allocator, description.?),
|
.network_info = try dupeString(self.allocator, description.?),
|
||||||
|
@ -135,7 +139,7 @@ pub const NetworkWidget = struct {
|
||||||
for (self.network_infos.items) |info, i| {
|
for (self.network_infos.items) |info, i| {
|
||||||
if (i != self.current_interface) continue;
|
if (i != self.current_interface) continue;
|
||||||
//std.log.debug(.network, "item! {} {}\n", .{ info, i });
|
//std.log.debug(.network, "item! {} {}\n", .{ info, i });
|
||||||
const inner_text = try std.fmt.allocPrint(allocator, "{} {}", .{ @tagName(info.network_type), info.network_info });
|
const inner_text = try std.fmt.allocPrint(allocator, "{} {}", .{ @tagName(info.network_type), info.network_info });
|
||||||
const full_text = try colour(allocator, networkStatusToColour(info.network_status), inner_text);
|
const full_text = try colour(allocator, networkStatusToColour(info.network_status), inner_text);
|
||||||
defer allocator.free(full_text);
|
defer allocator.free(full_text);
|
||||||
allocator.free(inner_text);
|
allocator.free(inner_text);
|
||||||
|
|
|
@ -25,12 +25,12 @@ pub const TimeWidget = struct {
|
||||||
|
|
||||||
pub fn start(self: *TimeWidget) anyerror!void {
|
pub fn start(self: *TimeWidget) anyerror!void {
|
||||||
// TODO: find a god damn decent time library thats better than this bullshit.
|
// TODO: find a god damn decent time library thats better than this bullshit.
|
||||||
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
var arena = std.heap.ArenaAllocator.init(self.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
var allocator = &arena.allocator;
|
var allocator = &arena.allocator;
|
||||||
var local = time.Location.getLocal(allocator);
|
var local = time.Location.getLocal(allocator);
|
||||||
while (self.bar.keep_running()) {
|
while (self.bar.keep_running()) {
|
||||||
var now = time.now(&local);
|
var now = time.now(&local);
|
||||||
var date = now.date();
|
var date = now.date();
|
||||||
var clock = now.clock();
|
var clock = now.clock();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue