Skip to content

Commit

Permalink
Unified error reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnau478 committed May 15, 2024
1 parent 4c34e78 commit 1ad4b4b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 23 deletions.
26 changes: 11 additions & 15 deletions src/argparse.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const build_options = @import("build_options");
const hevi = @import("hevi");
const main = @import("main.zig");

pub const ParseResult = struct {
filename: []const u8,
Expand Down Expand Up @@ -32,11 +33,6 @@ const Flag = union(enum) {
},
};

fn printError(comptime fmt: []const u8, args: anytype) noreturn {
std.debug.print("Error: " ++ fmt ++ "\nTip: use `--help` for help\n", args);
std.process.exit(1);
}

fn printHelp() noreturn {
std.debug.print(
\\hevi - hex viewer
Expand Down Expand Up @@ -124,7 +120,7 @@ pub fn parse(args: [][]const u8) ParseResult {
var string_ptr: *?[]const u8 = undefined;
for (args) |arg| {
if (take_string) {
if (arg[0] == '-') printError("expected arg string!", .{});
if (arg[0] == '-') main.fail("expected arg string", .{});
string_ptr.* = arg;

take_string = false;
Expand All @@ -133,7 +129,7 @@ pub fn parse(args: [][]const u8) ParseResult {

if (arg[0] == '-') {
if (arg.len <= 1) {
printError("expected flag", .{});
main.fail("expected flag", .{});
}
switch (arg[1]) {
'h' => {
Expand All @@ -144,7 +140,7 @@ pub fn parse(args: [][]const u8) ParseResult {
},
'-' => {
const name = arg[2..];
if (name.len == 0) printError("expected flag", .{});
if (name.len == 0) main.fail("expected flag", .{});

const flags: []const Flag = &.{
.{ .action = .{ .flag = "help", .action = .help } },
Expand Down Expand Up @@ -181,8 +177,8 @@ pub fn parse(args: [][]const u8) ParseResult {
if (set) |s| {
if (toggle.boolean.* != null) {
if (toggle.boolean.*.? != s) {
printError("`--{s}` and `--{s}` are mutually exclusive", .{ toggle.enable, toggle.disable });
} else printError("`--{s}` specified multiple times", .{if (s) toggle.enable else toggle.disable});
main.fail("`--{s}` and `--{s}` are mutually exclusive", .{ toggle.enable, toggle.disable });
} else main.fail("`--{s}` specified multiple times", .{if (s) toggle.enable else toggle.disable});
} else toggle.boolean.* = s;

break :blk true;
Expand All @@ -199,27 +195,27 @@ pub fn parse(args: [][]const u8) ParseResult {
break :blk false;
};

if (!found) printError("invalid flag `{s}`", .{arg});
if (!found) main.fail("invalid flag `{s}`", .{arg});
},
else => printError("invalid flag `{s}`", .{arg}),
else => main.fail("invalid flag `{s}`", .{arg}),
}
} else {
if (filename) |_| {
printError("multiple files specified", .{});
main.fail("multiple files specified", .{});
} else filename = arg;
}
}

return .{
.filename = filename orelse printError("no file specified", .{}),
.filename = filename orelse main.fail("no file specified", .{}),
.color = color,
.uppercase = uppercase,
.show_size = show_size,
.show_offset = show_offset,
.show_ascii = show_ascii,
.skip_lines = skip_lines,
.parser = if (parser) |p|
std.meta.stringToEnum(hevi.Parser, p) orelse printError("no parser named {s}", .{p})
std.meta.stringToEnum(hevi.Parser, p) orelse main.fail("no parser named {s}", .{p})
else
null,
};
Expand Down
3 changes: 1 addition & 2 deletions src/hevi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ fn getColors(allocator: std.mem.Allocator, reader: std.io.AnyReader, options: Di
parser.getColors(colors, data);
return colors;
} else {
std.debug.print("Error: the specified parser doesn't match the file format!\n", .{});
std.process.exit(1);
return error.NonMatchingParser;
}
}
} else if (parser.matches(data)) {
Expand Down
29 changes: 23 additions & 6 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,41 @@ const hevi = @import("hevi");
const argparse = @import("argparse.zig");
const options = @import("options.zig");

pub fn main() !void {
pub fn fail(comptime fmt: []const u8, args: anytype) noreturn {
std.log.err(fmt, args);
std.process.exit(1);
}

pub fn main() void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer if (gpa.deinit() == .leak) std.debug.print("Error: MEMORY LEAK!\n", .{});
defer if (gpa.deinit() == .leak) fail("Memory leak detected", .{});

const allocator = gpa.allocator();

const args = try std.process.argsAlloc(allocator);
const args = std.process.argsAlloc(allocator) catch fail("Out of memory", .{});
defer std.process.argsFree(allocator, args);

const parsed_args = argparse.parse(args[1..]);

const file = try std.fs.cwd().openFile(parsed_args.filename, .{});
const file = std.fs.cwd().openFile(parsed_args.filename, .{}) catch |err| switch (err) {
error.FileNotFound => fail("{s} not found", .{parsed_args.filename}),
error.IsDir => fail("{s} is a directory", .{parsed_args.filename}),
else => fail("{s} could not be opened", .{parsed_args.filename}),
};
defer file.close();

const data = try file.readToEndAlloc(allocator, std.math.maxInt(usize));
const data = file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch fail("Out of memory", .{});
defer allocator.free(data);

const stdout = std.io.getStdOut();

try hevi.dump(allocator, data, stdout.writer().any(), try options.getOptions(allocator, parsed_args, stdout));
const opts = options.getOptions(allocator, parsed_args, stdout) catch |err| switch (err) {
error.InvalidConfig => fail("Invalid config found", .{}),
else => fail("Error getting options and config file", .{}),
};

hevi.dump(allocator, data, stdout.writer().any(), opts) catch |err| switch (err) {
error.NonMatchingParser => fail("{s} does not match parser {s}", .{ parsed_args.filename, @tagName(opts.parser.?) }),
else => fail("{s}", .{@errorName(err)}),
};
}

0 comments on commit 1ad4b4b

Please sign in to comment.