dotfiles/scripts/mzteinit/src/command.zig

85 lines
2.6 KiB
Zig

const std = @import("std");
const Mutex = @import("mutex.zig").Mutex;
const log = std.log.scoped(.command);
pub const Command = struct {
key: u8,
label: []const u8,
command: [][]const u8,
exit: bool,
pub fn deinit(self: Command, alloc: std.mem.Allocator) void {
alloc.free(self.command);
}
pub fn run(
self: Command,
alloc: std.mem.Allocator,
exit: *@import("util.zig").ExitMode,
env: *Mutex(std.process.EnvMap),
) !void {
if (std.mem.eql(u8, self.command[0], "!quit")) {
exit.* = .delayed;
log.info("user logged out", .{});
return;
}
if (self.exit) exit.* = .immediate;
log.info("run cmd: {s}", .{self.command});
var child = std.ChildProcess.init(self.command, alloc);
{
env.mtx.lock();
defer env.mtx.unlock();
child.env_map = &env.data;
try child.spawn();
}
_ = try child.wait();
}
};
pub fn parseEntriesConfig(alloc: std.mem.Allocator, data: []const u8) ![]Command {
var entries = std.ArrayList(Command).init(alloc);
errdefer entries.deinit();
var line_splits = std.mem.tokenizeScalar(u8, data, '\n');
while (line_splits.next()) |line| {
const line_without_comment = std.mem.sliceTo(line, '#');
if (line_without_comment.len == 0)
continue;
var seg_splits = std.mem.tokenizeScalar(u8, line_without_comment, ':');
const labels = std.mem.trim(u8, seg_splits.next() orelse return error.InvalidConfig, &std.ascii.whitespace);
const command = std.mem.trim(u8, seg_splits.next() orelse return error.InvalidConfig, &std.ascii.whitespace);
var exit = false;
if (seg_splits.next()) |extra| {
if (std.mem.eql(u8, extra, "Q")) {
exit = true;
} else return error.InvalidConfig;
}
if (seg_splits.next()) |_| return error.InvalidConfig;
if (labels.len < 3 or labels[1] != ' ') return error.InvalidConfig;
const key = std.ascii.toUpper(labels[0]);
const label = labels[2..];
var argv = std.ArrayList([]const u8).init(alloc);
errdefer argv.deinit();
var command_splits = std.mem.splitScalar(u8, command, ',');
while (command_splits.next()) |arg|
try argv.append(arg);
if (argv.items.len == 0) return error.InvalidConfig;
try entries.append(.{
.key = key,
.label = label,
.command = try argv.toOwnedSlice(),
.exit = exit,
});
}
return try entries.toOwnedSlice();
}