command: make args type 0-terminated

Since we often need to pass these args back C code, keeping the 0 byte
around saves some allocations.
This commit is contained in:
Isaac Freund 2021-07-15 00:13:16 +02:00
parent 3c951fed74
commit 604cf98047
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
26 changed files with 67 additions and 77 deletions

View file

@ -31,7 +31,7 @@ const util = @import("util.zig");
const Seat = @import("Seat.zig");
const Server = @import("Server.zig");
const ArgMap = std.AutoHashMap(struct { client: *wl.Client, id: u32 }, std.ArrayListUnmanaged([]const u8));
const ArgMap = std.AutoHashMap(struct { client: *wl.Client, id: u32 }, std.ArrayListUnmanaged([:0]const u8));
global: *wl.Global,
@ -72,7 +72,7 @@ fn handleRequest(control: *zriver.ControlV1, request: zriver.ControlV1.Request,
switch (request) {
.destroy => control.destroy(),
.add_argument => |add_argument| {
const owned_slice = mem.dupe(util.gpa, u8, mem.span(add_argument.argument)) catch {
const owned_slice = util.gpa.dupeZ(u8, mem.span(add_argument.argument)) catch {
control.getClient().postNoMemory();
return;
};

View file

@ -25,7 +25,7 @@ const util = @import("util.zig");
keysym: xkb.Keysym,
modifiers: wlr.Keyboard.ModifierMask,
command_args: []const []const u8,
command_args: []const [:0]const u8,
/// When set to true the mapping will be executed on key release rather than on press
release: bool,
@ -36,11 +36,11 @@ pub fn init(
release: bool,
command_args: []const []const u8,
) !Self {
const owned_args = try util.gpa.alloc([]u8, command_args.len);
const owned_args = try util.gpa.alloc([:0]u8, command_args.len);
errdefer util.gpa.free(owned_args);
for (command_args) |arg, i| {
errdefer for (owned_args[0..i]) |a| util.gpa.free(a);
owned_args[i] = try std.mem.dupe(util.gpa, u8, arg);
owned_args[i] = try std.mem.dupeZ(util.gpa, u8, arg);
}
return Self{
.keysym = keysym,

View file

@ -40,7 +40,7 @@ pub const Orientation = enum {
// zig fmt: off
const str_to_impl_fn = [_]struct {
name: []const u8,
impl: fn (*std.mem.Allocator, *Seat, []const []const u8, *?[]const u8) Error!void,
impl: fn (*std.mem.Allocator, *Seat, []const [:0]const u8, *?[]const u8) Error!void,
}{
.{ .name = "attach-mode", .impl = @import("command/attach_mode.zig").attachMode },
.{ .name = "background-color", .impl = @import("command/config.zig").backgroundColor },
@ -99,9 +99,9 @@ pub const Error = error{
InvalidButton,
InvalidCharacter,
InvalidDirection,
InvalidType,
InvalidPhysicalDirection,
InvalidOrientation,
InvalidType,
InvalidRgba,
InvalidValue,
UnknownOption,
@ -119,7 +119,7 @@ pub const Error = error{
pub fn run(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
std.debug.assert(out.* == null);
@ -144,9 +144,9 @@ pub fn errToMsg(err: Error) [:0]const u8 {
Error.InvalidButton => "invalid button",
Error.InvalidCharacter => "invalid character in argument",
Error.InvalidDirection => "invalid direction. Must be 'next' or 'previous'",
Error.InvalidType => "invalid type",
Error.InvalidPhysicalDirection => "invalid direction. Must be 'up', 'down', 'left' or 'right'",
Error.InvalidOrientation => "invalid orientation. Must be 'horizontal', or 'vertical'",
Error.InvalidType => "invalid type",
Error.InvalidRgba => "invalid color format, must be #RRGGBB or #RRGGBBAA",
Error.InvalidValue => "invalid value",
Error.OutOfMemory => "out of memory",

View file

@ -27,7 +27,7 @@ const Seat = @import("../Seat.zig");
pub fn attachMode(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -24,7 +24,7 @@ const Seat = @import("../Seat.zig");
pub fn close(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
// Note: we don't call arrange() here as it will be called

View file

@ -26,7 +26,7 @@ const Config = @import("../Config.zig");
pub fn borderWidth(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -40,7 +40,7 @@ pub fn borderWidth(
pub fn backgroundColor(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -55,7 +55,7 @@ pub fn backgroundColor(
pub fn borderColorFocused(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -70,7 +70,7 @@ pub fn borderColorFocused(
pub fn borderColorUnfocused(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -85,7 +85,7 @@ pub fn borderColorUnfocused(
pub fn setCursorWarp(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -29,7 +29,7 @@ const Seat = @import("../Seat.zig");
pub fn declareMode(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -26,7 +26,7 @@ const Seat = @import("../Seat.zig");
pub fn enterMode(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -26,7 +26,7 @@ const Seat = @import("../Seat.zig");
pub fn exit(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len > 1) return Error.TooManyArguments;

View file

@ -30,7 +30,7 @@ const Seat = @import("../Seat.zig");
pub fn floatFilterAdd(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -45,7 +45,7 @@ pub fn floatFilterAdd(
pub fn floatFilterRemove(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -57,7 +57,7 @@ pub fn floatFilterRemove(
pub fn csdFilterAdd(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -74,7 +74,7 @@ pub fn csdFilterAdd(
pub fn csdFilterRemove(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -27,7 +27,7 @@ const Seat = @import("../Seat.zig");
pub fn focusFollowsCursor(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -30,7 +30,7 @@ const ViewStack = @import("../view_stack.zig").ViewStack;
pub fn focusView(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -30,7 +30,7 @@ const InputManager = @import("../InputManager.zig");
pub fn listInputs(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
var input_list = std.ArrayList(u8).init(allocator);
@ -61,7 +61,7 @@ pub fn listInputs(
pub fn listInputConfigs(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
var input_list = std.ArrayList(u8).init(allocator);
@ -124,7 +124,7 @@ pub fn listInputConfigs(
pub fn input(
allocator: *mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 4) return Error.NotEnoughArguments;
@ -197,9 +197,7 @@ pub fn input(
input_config.scroll_method = std.meta.stringToEnum(InputConfig.ScrollMethod, args[3]) orelse
return Error.UnknownOption;
} else if (mem.eql(u8, "scroll-button", args[2])) {
const event_code_name = try std.cstr.addNullByte(allocator, args[3]);
defer allocator.free(event_code_name);
const ret = c.libevdev_event_code_from_name(c.EV_KEY, event_code_name);
const ret = c.libevdev_event_code_from_name(c.EV_KEY, args[3]);
if (ret < 1) return Error.InvalidButton;
input_config.scroll_button = InputConfig.ScrollButton{ .button = @intCast(u32, ret) };
} else {

View file

@ -28,7 +28,7 @@ const Seat = @import("../Seat.zig");
pub fn outputLayout(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -42,7 +42,7 @@ pub fn outputLayout(
pub fn defaultLayout(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -68,7 +68,7 @@ const SetType = enum {
pub fn setLayoutValue(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 5) return Error.NotEnoughArguments;
@ -117,7 +117,7 @@ const ModType = enum {
pub fn modLayoutValue(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 5) return Error.NotEnoughArguments;

View file

@ -36,7 +36,7 @@ const Seat = @import("../Seat.zig");
pub fn map(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const optionals = parseOptionalArgs(args[1..]);
@ -68,7 +68,7 @@ pub fn map(
pub fn mapPointer(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 5) return Error.NotEnoughArguments;
@ -148,24 +148,20 @@ fn pointerMappingExists(
return null;
}
fn parseEventCode(allocator: *std.mem.Allocator, event_code_str: []const u8, out: *?[]const u8) !u32 {
const event_code_name = try std.cstr.addNullByte(allocator, event_code_str);
defer allocator.free(event_code_name);
const ret = c.libevdev_event_code_from_name(c.EV_KEY, event_code_name);
if (ret < 1) {
out.* = try std.fmt.allocPrint(allocator, "unknown button {s}", .{event_code_str});
fn parseEventCode(allocator: *std.mem.Allocator, name: [:0]const u8, out: *?[]const u8) !u32 {
const event_code = c.libevdev_event_code_from_name(c.EV_KEY, name);
if (event_code < 1) {
out.* = try std.fmt.allocPrint(allocator, "unknown button {s}", .{name});
return Error.Other;
}
return @intCast(u32, ret);
return @intCast(u32, event_code);
}
fn parseKeysym(allocator: *std.mem.Allocator, keysym_str: []const u8, out: *?[]const u8) !xkb.Keysym {
const keysym_name = try std.cstr.addNullByte(allocator, keysym_str);
defer allocator.free(keysym_name);
const keysym = xkb.Keysym.fromName(keysym_name, .case_insensitive);
fn parseKeysym(allocator: *std.mem.Allocator, name: [:0]const u8, out: *?[]const u8) !xkb.Keysym {
const keysym = xkb.Keysym.fromName(name, .case_insensitive);
if (keysym == .NoSymbol) {
out.* = try std.fmt.allocPrint(allocator, "invalid keysym '{s}'", .{keysym_str});
out.* = try std.fmt.allocPrint(allocator, "invalid keysym '{s}'", .{name});
return Error.Other;
}
return keysym;
@ -240,7 +236,7 @@ fn parseOptionalArgs(args: []const []const u8) OptionalArgsContainer {
pub fn unmap(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const optionals = parseOptionalArgs(args[1..]);
@ -266,7 +262,7 @@ pub fn unmap(
pub fn unmapPointer(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 4) return Error.NotEnoughArguments;

View file

@ -29,7 +29,7 @@ const Box = @import("../Box.zig");
pub fn move(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 3) return Error.NotEnoughArguments;
@ -53,7 +53,7 @@ pub fn move(
pub fn snap(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -80,7 +80,7 @@ pub fn snap(
pub fn resize(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 3) return Error.NotEnoughArguments;

View file

@ -32,7 +32,7 @@ fn opacityUpdateFilter(view: *View, context: void) bool {
pub fn opacity(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 6) return Error.NotEnoughArguments;

View file

@ -30,7 +30,7 @@ const Seat = @import("../Seat.zig");
pub fn focusOutput(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
@ -50,7 +50,7 @@ pub fn focusOutput(
pub fn sendToOutput(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -26,7 +26,7 @@ const Seat = @import("../Seat.zig");
pub fn setRepeat(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 3) return Error.NotEnoughArguments;

View file

@ -26,17 +26,15 @@ const Seat = @import("../Seat.zig");
pub fn spawn(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
const cmd = try std.mem.join(allocator, " ", args[1..]);
const cmd = try std.mem.joinZ(allocator, " ", args[1..]);
defer allocator.free(cmd);
const cmdZ = try std.cstr.addNullByte(allocator, cmd);
defer allocator.free(cmdZ);
const child_args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmdZ, null };
const child_args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", cmd, null };
const pid = std.os.fork() catch {
out.* = try std.fmt.allocPrint(allocator, "fork/execve failed", .{});

View file

@ -29,7 +29,7 @@ const ViewStack = @import("../view_stack.zig").ViewStack;
pub fn swap(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -26,7 +26,7 @@ const Seat = @import("../Seat.zig");
pub fn setFocusedTags(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const tags = try parseTags(allocator, args, out);
@ -42,7 +42,7 @@ pub fn setFocusedTags(
pub fn spawnTagmask(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const tags = try parseTags(allocator, args, out);
@ -53,7 +53,7 @@ pub fn spawnTagmask(
pub fn setViewTags(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const tags = try parseTags(allocator, args, out);
@ -69,7 +69,7 @@ pub fn setViewTags(
pub fn toggleFocusedTags(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const tags = try parseTags(allocator, args, out);
@ -87,7 +87,7 @@ pub fn toggleFocusedTags(
pub fn toggleViewTags(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
const tags = try parseTags(allocator, args, out);
@ -104,7 +104,7 @@ pub fn toggleViewTags(
fn parseTags(
allocator: *std.mem.Allocator,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!u32 {
if (args.len < 2) return Error.NotEnoughArguments;

View file

@ -27,7 +27,7 @@ const Seat = @import("../Seat.zig");
pub fn toggleFloat(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len > 1) return Error.TooManyArguments;

View file

@ -27,7 +27,7 @@ const Seat = @import("../Seat.zig");
pub fn toggleFullscreen(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len > 1) return Error.TooManyArguments;

View file

@ -23,15 +23,13 @@ const Seat = @import("../Seat.zig");
pub fn xcursorTheme(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len < 2) return Error.NotEnoughArguments;
if (args.len > 3) return Error.TooManyArguments;
// TODO: get rid of this allocation
const name = try std.cstr.addNullByte(allocator, args[1]);
defer allocator.free(name);
const name = args[1];
const size = if (args.len == 3) try std.fmt.parseInt(u32, args[2], 10) else null;
try seat.cursor.setTheme(name, size);

View file

@ -29,7 +29,7 @@ const ViewStack = @import("../view_stack.zig").ViewStack;
pub fn zoom(
allocator: *std.mem.Allocator,
seat: *Seat,
args: []const []const u8,
args: []const [:0]const u8,
out: *?[]const u8,
) Error!void {
if (args.len > 1) return Error.TooManyArguments;