aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2021-07-24 16:44:11 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2021-07-24 16:44:11 +0200
commitf6fa3425de1efb16cc2b7967eb6420afac4fdab4 (patch)
treeb06e3c2d8c9aeace6c10e570647182c2022f7c4d
parent32d35cdf91f7ff31070e844785adbd33febef229 (diff)
downloadriver-f6fa3425de1efb16cc2b7967eb6420afac4fdab4.tar.gz
river-f6fa3425de1efb16cc2b7967eb6420afac4fdab4.tar.xz
river: use common CLI arg parsing code
This makes river's main() function quite a bit cleaner.
-rw-r--r--build.zig3
-rw-r--r--common/args.zig (renamed from rivertile/args.zig)4
-rw-r--r--river/main.zig79
-rw-r--r--rivertile/main.zig4
4 files changed, 42 insertions, 48 deletions
diff --git a/build.zig b/build.zig
index b432ca3..b792964 100644
--- a/build.zig
+++ b/build.zig
@@ -116,6 +116,7 @@ pub fn build(b: *zbs.Builder) !void {
rivertile.step.dependOn(&scanner.step);
rivertile.addPackage(scanner.getPkg());
+ rivertile.addPackagePath("args", "common/args.zig");
rivertile.linkLibC();
rivertile.linkSystemLibrary("wayland-client");
@@ -208,6 +209,8 @@ fn addServerDeps(exe: *zbs.LibExeObjStep, scanner: *ScanProtocolsStep) void {
exe.addPackage(wlroots);
exe.linkSystemLibrary("wlroots");
+ exe.addPackagePath("args", "common/args.zig");
+
// TODO: remove when zig issue #131 is implemented
scanner.addCSource(exe);
}
diff --git a/rivertile/args.zig b/common/args.zig
index 31b57bc..669f9f9 100644
--- a/rivertile/args.zig
+++ b/common/args.zig
@@ -113,14 +113,14 @@ pub fn Args(comptime num_positionals: comptime_int, comptime flag_defs: []const
for (self.flags) |flag| {
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 {
for (self.flags) |flag| {
if (cstr.cmp(flag.name, flag_name) == 0) return flag.value.arg;
}
- unreachable;
+ unreachable; // Invalid flag_name
}
};
}
diff --git a/river/main.zig b/river/main.zig
index 212cc69..56a9477 100644
--- a/river/main.zig
+++ b/river/main.zig
@@ -15,12 +15,14 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
+const build_options = @import("build_options");
const std = @import("std");
const fs = std.fs;
+const io = std.io;
const os = std.os;
const wlr = @import("wlroots");
-
-const build_options = @import("build_options");
+const Args = @import("args").Args;
+const FlagDef = @import("args").FlagDef;
const c = @import("c.zig");
const util = @import("util.zig");
@@ -47,43 +49,35 @@ const usage: []const u8 =
;
pub fn main() anyerror!void {
- var startup_command: ?[:0]const u8 = null;
- {
- var it = std.process.args();
- // Skip our name
- _ = it.nextPosix();
- while (it.nextPosix()) |arg| {
- if (std.mem.eql(u8, arg, "-h")) {
- const stdout = std.io.getStdOut().writer();
- try stdout.print(usage, .{});
- os.exit(0);
- } else if (std.mem.eql(u8, arg, "-c")) {
- if (it.nextPosix()) |command| {
- // 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);
- }
- }
+ // This line is here because of https://github.com/ziglang/zig/issues/7807
+ const argv: [][*:0]const u8 = os.argv;
+ const args = Args(0, &[_]FlagDef{
+ .{ .name = "-h", .kind = .boolean },
+ .{ .name = "-version", .kind = .boolean },
+ .{ .name = "-c", .kind = .arg },
+ .{ .name = "-l", .kind = .arg },
+ }).parse(argv[1..]);
+
+ if (args.boolFlag("-h")) {
+ try io.getStdOut().writeAll(usage);
+ os.exit(0);
+ }
+ 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) {
.debug => .debug,
@@ -91,8 +85,6 @@ pub fn main() anyerror!void {
.warn, .err, .crit, .alert, .emerg => .err,
});
- if (startup_command == null) startup_command = try defaultInitPath();
-
std.log.info("initializing server", .{});
try server.init();
defer server.deinit();
@@ -125,9 +117,8 @@ pub fn main() anyerror!void {
std.log.info("shutting down", .{});
}
-fn printErrorExit(comptime format: []const u8, args: anytype) noreturn {
- const stderr = std.io.getStdErr().writer();
- stderr.print(format ++ "\n", args) catch os.exit(1);
+pub fn fatal(comptime format: []const u8, args: anytype) noreturn {
+ io.getStdErr().writer().print(format ++ "\n", args) catch {};
os.exit(1);
}
@@ -160,7 +151,7 @@ pub fn log(
if (@enumToInt(message_level) <= @enumToInt(level)) {
// Don't store/log messages in release small mode to save space
if (std.builtin.mode != .ReleaseSmall) {
- const stderr = std.io.getStdErr().writer();
+ const stderr = io.getStdErr().writer();
stderr.print(@tagName(message_level) ++ ": (" ++ @tagName(scope) ++ ") " ++
format ++ "\n", args) catch return;
}
diff --git a/rivertile/main.zig b/rivertile/main.zig
index ff57475..cc977b4 100644
--- a/rivertile/main.zig
+++ b/rivertile/main.zig
@@ -45,8 +45,8 @@ const wayland = @import("wayland");
const wl = wayland.client.wl;
const river = wayland.client.river;
-const Args = @import("args.zig").Args;
-const FlagDef = @import("args.zig").FlagDef;
+const Args = @import("args").Args;
+const FlagDef = @import("args").FlagDef;
const usage =
\\Usage: rivertile [options]