Clean error when file not found
This commit is contained in:
parent
dfc8884406
commit
3ae79d3dfe
2 changed files with 68 additions and 10 deletions
66
src/main.zig
66
src/main.zig
|
@ -24,8 +24,9 @@ pub fn main() anyerror!void {
|
||||||
var fba = heap.FixedBufferAllocator.init(&buffer);
|
var fba = heap.FixedBufferAllocator.init(&buffer);
|
||||||
const allocator = fba.allocator();
|
const allocator = fba.allocator();
|
||||||
|
|
||||||
const config: Config = parseArgs() catch |err| switch (err) {
|
const config: Config = parseArgs(allocator) catch |err| switch (err) {
|
||||||
error.EarlyExit => return,
|
error.EarlyExit => return,
|
||||||
|
error.FileNotFound => return,
|
||||||
else => @panic("Unknown error"),
|
else => @panic("Unknown error"),
|
||||||
};
|
};
|
||||||
defer config.deinit();
|
defer config.deinit();
|
||||||
|
@ -40,12 +41,14 @@ pub fn main() anyerror!void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const errors = error {
|
const errors = error {
|
||||||
EarlyExit
|
EarlyExit,
|
||||||
|
FileNotFound
|
||||||
};
|
};
|
||||||
|
|
||||||
const Config = struct {
|
const Config = struct {
|
||||||
lines: u32,
|
lines: u32,
|
||||||
file: ?fs.File,
|
file: ?fs.File,
|
||||||
|
line: ?[]const u8 = null,
|
||||||
|
|
||||||
pub fn deinit(self: @This()) void {
|
pub fn deinit(self: @This()) void {
|
||||||
if (self.file) |f| {
|
if (self.file) |f| {
|
||||||
|
@ -54,10 +57,11 @@ const Config = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn parseArgs() !Config {
|
fn parseArgs(allocator: mem.Allocator) !Config {
|
||||||
const params = comptime [_]clap.Param(clap.Help) {
|
const params = comptime [_]clap.Param(clap.Help) {
|
||||||
clap.parseParam("<N> The number of lines to skip") catch unreachable,
|
clap.parseParam("<N> The number of lines to skip") catch unreachable,
|
||||||
clap.parseParam("[<FILE>] The file to read or stdin if not given") catch unreachable,
|
clap.parseParam("[<FILE>] The file to read or stdin if not given") catch unreachable,
|
||||||
|
clap.parseParam("-l, --line <STR> Skip until N lines matching this") catch unreachable,
|
||||||
clap.parseParam("-h, --help Display this help and exit") catch unreachable,
|
clap.parseParam("-h, --help Display this help and exit") catch unreachable,
|
||||||
clap.parseParam("-v, --version Display the version") catch unreachable,
|
clap.parseParam("-v, --version Display the version") catch unreachable,
|
||||||
};
|
};
|
||||||
|
@ -77,6 +81,10 @@ fn parseArgs() !Config {
|
||||||
try clap.help(io.getStdErr().writer(), ¶ms);
|
try clap.help(io.getStdErr().writer(), ¶ms);
|
||||||
return error.EarlyExit;
|
return error.EarlyExit;
|
||||||
}
|
}
|
||||||
|
var line: ?[]const u8 = null;
|
||||||
|
if (args.option("--line")) |match| {
|
||||||
|
line = try allocator.dupe(u8, match);
|
||||||
|
}
|
||||||
|
|
||||||
var n: u32 = 0;
|
var n: u32 = 0;
|
||||||
var file: ?fs.File = null;
|
var file: ?fs.File = null;
|
||||||
|
@ -89,11 +97,18 @@ fn parseArgs() !Config {
|
||||||
}
|
}
|
||||||
if (args.positionals().len >= 2) {
|
if (args.positionals().len >= 2) {
|
||||||
const filename = args.positionals()[1];
|
const filename = args.positionals()[1];
|
||||||
file = try fs.cwd().openFile(filename, .{ .read = true, .write = false });
|
file = fs.cwd().openFile(filename, .{ .read = true, .write = false }) catch |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
try io.getStdErr().writer().print("Error: File not found: {s}\n", .{ filename });
|
||||||
|
return err;
|
||||||
|
},
|
||||||
|
else => return err,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return Config {
|
return Config {
|
||||||
.lines = n,
|
.lines = n,
|
||||||
.file = file,
|
.file = file,
|
||||||
|
.line = line,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +117,17 @@ fn dumpInput(config: Config, in: fs.File, out: fs.File, allocator: mem.Allocator
|
||||||
const reader = in.reader();
|
const reader = in.reader();
|
||||||
var it: LineIterator = lineIterator(reader, allocator);
|
var it: LineIterator = lineIterator(reader, allocator);
|
||||||
var c: u32 = 0;
|
var c: u32 = 0;
|
||||||
while (c < config.lines) : (c += 1) {
|
while (c < config.lines) {
|
||||||
const line = it.next();
|
const line = it.next();
|
||||||
|
if (config.line) |match| {
|
||||||
|
if (line) |memory| {
|
||||||
|
if (mem.eql(u8, match, memory)) {
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c += 1;
|
||||||
|
}
|
||||||
if (line) |memory| {
|
if (line) |memory| {
|
||||||
allocator.free(memory);
|
allocator.free(memory);
|
||||||
} else return;
|
} else return;
|
||||||
|
@ -111,7 +135,7 @@ fn dumpInput(config: Config, in: fs.File, out: fs.File, allocator: mem.Allocator
|
||||||
try pumpIterator(&it, writer, allocator);
|
try pumpIterator(&it, writer, allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "dumpInput" {
|
test "dumpInput skip 1 line" {
|
||||||
const file = try fs.cwd().openFile("src/test/two-lines.txt", .{ .read = true, .write = false });
|
const file = try fs.cwd().openFile("src/test/two-lines.txt", .{ .read = true, .write = false });
|
||||||
defer file.close();
|
defer file.close();
|
||||||
|
|
||||||
|
@ -140,6 +164,36 @@ test "dumpInput" {
|
||||||
try testing.expect(eof == null);
|
try testing.expect(eof == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "dumpInput skip 2 line 'alpha'" {
|
||||||
|
const file = try fs.cwd().openFile("src/test/four-lines.txt", .{ .read = true, .write = false });
|
||||||
|
defer file.close();
|
||||||
|
|
||||||
|
const tempFile = "zig-cache/test.txt";
|
||||||
|
|
||||||
|
const output = try fs.cwd().createFile(tempFile, .{});
|
||||||
|
defer output.close();
|
||||||
|
|
||||||
|
const config = Config{
|
||||||
|
.lines = 2,
|
||||||
|
.file = file,
|
||||||
|
.line = "alpha",
|
||||||
|
};
|
||||||
|
|
||||||
|
try dumpInput(config, file, output, testing.allocator);
|
||||||
|
|
||||||
|
const result = try fs.cwd().openFile(tempFile, .{ .read = true });
|
||||||
|
defer result.close();
|
||||||
|
|
||||||
|
var rit = lineIterator(result.reader(), testing.allocator);
|
||||||
|
|
||||||
|
const line1 = rit.next().?;
|
||||||
|
defer testing.allocator.free(line1);
|
||||||
|
try testing.expectEqualStrings("gamma", line1);
|
||||||
|
|
||||||
|
const eof = rit.next();
|
||||||
|
try testing.expect(eof == null);
|
||||||
|
}
|
||||||
|
|
||||||
fn pumpIterator(it: *LineIterator, writer: fs.File.Writer, allocator: mem.Allocator) !void {
|
fn pumpIterator(it: *LineIterator, writer: fs.File.Writer, allocator: mem.Allocator) !void {
|
||||||
while (it.next()) |line| {
|
while (it.next()) |line| {
|
||||||
defer allocator.free(line);
|
defer allocator.free(line);
|
||||||
|
|
4
src/test/four-lines.txt
Normal file
4
src/test/four-lines.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
alpha
|
||||||
|
beta
|
||||||
|
alpha
|
||||||
|
gamma
|
Loading…
Reference in a new issue