river: use common CLI arg parsing code
This makes river's main() function quite a bit cleaner.
This commit is contained in:
parent
32d35cdf91
commit
f6fa3425de
4 changed files with 42 additions and 48 deletions
|
@ -116,6 +116,7 @@ pub fn build(b: *zbs.Builder) !void {
|
||||||
|
|
||||||
rivertile.step.dependOn(&scanner.step);
|
rivertile.step.dependOn(&scanner.step);
|
||||||
rivertile.addPackage(scanner.getPkg());
|
rivertile.addPackage(scanner.getPkg());
|
||||||
|
rivertile.addPackagePath("args", "common/args.zig");
|
||||||
rivertile.linkLibC();
|
rivertile.linkLibC();
|
||||||
rivertile.linkSystemLibrary("wayland-client");
|
rivertile.linkSystemLibrary("wayland-client");
|
||||||
|
|
||||||
|
@ -208,6 +209,8 @@ fn addServerDeps(exe: *zbs.LibExeObjStep, scanner: *ScanProtocolsStep) void {
|
||||||
exe.addPackage(wlroots);
|
exe.addPackage(wlroots);
|
||||||
exe.linkSystemLibrary("wlroots");
|
exe.linkSystemLibrary("wlroots");
|
||||||
|
|
||||||
|
exe.addPackagePath("args", "common/args.zig");
|
||||||
|
|
||||||
// TODO: remove when zig issue #131 is implemented
|
// TODO: remove when zig issue #131 is implemented
|
||||||
scanner.addCSource(exe);
|
scanner.addCSource(exe);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,14 +113,14 @@ pub fn Args(comptime num_positionals: comptime_int, comptime flag_defs: []const
|
||||||
for (self.flags) |flag| {
|
for (self.flags) |flag| {
|
||||||
if (cstr.cmp(flag.name, flag_name) == 0) return flag.value.boolean;
|
if (cstr.cmp(flag.name, flag_name) == 0) return flag.value.boolean;
|
||||||
}
|
}
|
||||||
unreachable;
|
unreachable; // Invalid flag_name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn argFlag(self: Self, flag_name: [*:0]const u8) ?[*:0]const u8 {
|
pub fn argFlag(self: Self, flag_name: [*:0]const u8) ?[*:0]const u8 {
|
||||||
for (self.flags) |flag| {
|
for (self.flags) |flag| {
|
||||||
if (cstr.cmp(flag.name, flag_name) == 0) return flag.value.arg;
|
if (cstr.cmp(flag.name, flag_name) == 0) return flag.value.arg;
|
||||||
}
|
}
|
||||||
unreachable;
|
unreachable; // Invalid flag_name
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -15,12 +15,14 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
const build_options = @import("build_options");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
|
const io = std.io;
|
||||||
const os = std.os;
|
const os = std.os;
|
||||||
const wlr = @import("wlroots");
|
const wlr = @import("wlroots");
|
||||||
|
const Args = @import("args").Args;
|
||||||
const build_options = @import("build_options");
|
const FlagDef = @import("args").FlagDef;
|
||||||
|
|
||||||
const c = @import("c.zig");
|
const c = @import("c.zig");
|
||||||
const util = @import("util.zig");
|
const util = @import("util.zig");
|
||||||
|
@ -47,43 +49,35 @@ const usage: []const u8 =
|
||||||
;
|
;
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
var startup_command: ?[:0]const u8 = null;
|
// This line is here because of https://github.com/ziglang/zig/issues/7807
|
||||||
{
|
const argv: [][*:0]const u8 = os.argv;
|
||||||
var it = std.process.args();
|
const args = Args(0, &[_]FlagDef{
|
||||||
// Skip our name
|
.{ .name = "-h", .kind = .boolean },
|
||||||
_ = it.nextPosix();
|
.{ .name = "-version", .kind = .boolean },
|
||||||
while (it.nextPosix()) |arg| {
|
.{ .name = "-c", .kind = .arg },
|
||||||
if (std.mem.eql(u8, arg, "-h")) {
|
.{ .name = "-l", .kind = .arg },
|
||||||
const stdout = std.io.getStdOut().writer();
|
}).parse(argv[1..]);
|
||||||
try stdout.print(usage, .{});
|
|
||||||
os.exit(0);
|
if (args.boolFlag("-h")) {
|
||||||
} else if (std.mem.eql(u8, arg, "-c")) {
|
try io.getStdOut().writeAll(usage);
|
||||||
if (it.nextPosix()) |command| {
|
os.exit(0);
|
||||||
// If the user used '-c' multiple times the variable
|
|
||||||
// already holds a path and needs to be freed.
|
|
||||||
if (startup_command) |cmd| util.gpa.free(cmd);
|
|
||||||
startup_command = try util.gpa.dupeZ(u8, command);
|
|
||||||
} else {
|
|
||||||
printErrorExit("Error: flag '-c' requires exactly one argument", .{});
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, arg, "-l")) {
|
|
||||||
if (it.nextPosix()) |level_str| {
|
|
||||||
const log_level = std.fmt.parseInt(u3, level_str, 10) catch
|
|
||||||
printErrorExit("Error: invalid log level '{s}'", .{level_str});
|
|
||||||
level = @intToEnum(std.log.Level, log_level);
|
|
||||||
} else {
|
|
||||||
printErrorExit("Error: flag '-l' requires exactly one argument", .{});
|
|
||||||
}
|
|
||||||
} else if (std.mem.eql(u8, arg, "-version")) {
|
|
||||||
try std.io.getStdOut().writeAll(build_options.version);
|
|
||||||
os.exit(0);
|
|
||||||
} else {
|
|
||||||
const stderr = std.io.getStdErr().writer();
|
|
||||||
try stderr.print(usage, .{});
|
|
||||||
os.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (args.boolFlag("-version")) {
|
||||||
|
try io.getStdOut().writeAll(@import("build_options").version);
|
||||||
|
os.exit(0);
|
||||||
|
}
|
||||||
|
if (args.argFlag("-l")) |level_str| {
|
||||||
|
const log_level = std.fmt.parseInt(u3, std.mem.span(level_str), 10) catch
|
||||||
|
fatal("Error: invalid log level '{s}'", .{level_str});
|
||||||
|
level = @intToEnum(std.log.Level, log_level);
|
||||||
|
}
|
||||||
|
const startup_command = blk: {
|
||||||
|
if (args.argFlag("-c")) |command| {
|
||||||
|
break :blk try util.gpa.dupeZ(u8, std.mem.span(command));
|
||||||
|
} else {
|
||||||
|
break :blk try defaultInitPath();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
wlr.log.init(switch (level) {
|
wlr.log.init(switch (level) {
|
||||||
.debug => .debug,
|
.debug => .debug,
|
||||||
|
@ -91,8 +85,6 @@ pub fn main() anyerror!void {
|
||||||
.warn, .err, .crit, .alert, .emerg => .err,
|
.warn, .err, .crit, .alert, .emerg => .err,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (startup_command == null) startup_command = try defaultInitPath();
|
|
||||||
|
|
||||||
std.log.info("initializing server", .{});
|
std.log.info("initializing server", .{});
|
||||||
try server.init();
|
try server.init();
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
|
@ -125,9 +117,8 @@ pub fn main() anyerror!void {
|
||||||
std.log.info("shutting down", .{});
|
std.log.info("shutting down", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn printErrorExit(comptime format: []const u8, args: anytype) noreturn {
|
pub fn fatal(comptime format: []const u8, args: anytype) noreturn {
|
||||||
const stderr = std.io.getStdErr().writer();
|
io.getStdErr().writer().print(format ++ "\n", args) catch {};
|
||||||
stderr.print(format ++ "\n", args) catch os.exit(1);
|
|
||||||
os.exit(1);
|
os.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +151,7 @@ pub fn log(
|
||||||
if (@enumToInt(message_level) <= @enumToInt(level)) {
|
if (@enumToInt(message_level) <= @enumToInt(level)) {
|
||||||
// Don't store/log messages in release small mode to save space
|
// Don't store/log messages in release small mode to save space
|
||||||
if (std.builtin.mode != .ReleaseSmall) {
|
if (std.builtin.mode != .ReleaseSmall) {
|
||||||
const stderr = std.io.getStdErr().writer();
|
const stderr = io.getStdErr().writer();
|
||||||
stderr.print(@tagName(message_level) ++ ": (" ++ @tagName(scope) ++ ") " ++
|
stderr.print(@tagName(message_level) ++ ": (" ++ @tagName(scope) ++ ") " ++
|
||||||
format ++ "\n", args) catch return;
|
format ++ "\n", args) catch return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,8 @@ const wayland = @import("wayland");
|
||||||
const wl = wayland.client.wl;
|
const wl = wayland.client.wl;
|
||||||
const river = wayland.client.river;
|
const river = wayland.client.river;
|
||||||
|
|
||||||
const Args = @import("args.zig").Args;
|
const Args = @import("args").Args;
|
||||||
const FlagDef = @import("args.zig").FlagDef;
|
const FlagDef = @import("args").FlagDef;
|
||||||
|
|
||||||
const usage =
|
const usage =
|
||||||
\\Usage: rivertile [options]
|
\\Usage: rivertile [options]
|
||||||
|
|
Loading…
Reference in a new issue