aboutsummaryrefslogtreecommitdiff
path: root/src/conf.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf.zig')
-rw-r--r--src/conf.zig102
1 files changed, 50 insertions, 52 deletions
diff --git a/src/conf.zig b/src/conf.zig
index 419c369..97238c3 100644
--- a/src/conf.zig
+++ b/src/conf.zig
@@ -1,21 +1,23 @@
const std = @import("std");
const assert = std.debug.assert;
+const fs = @import("fs.zig");
+
pub const Var = struct {
key: []const u8,
val: []const u8,
- pub fn format(self: Var, w: *std.io.Writer) !void {
+ pub fn format(self: Var, w: *std.Io.Writer) !void {
const spacebuf = [_]u8{' '} ** 32;
const equal_sign = " = ";
try w.writeAll(self.key);
try w.writeAll(equal_sign);
- if (std.mem.indexOfScalar(u8, self.val, '\n')) |eol0| {
+ if (std.mem.findScalar(u8, self.val, '\n')) |eol0| {
try w.writeAll(self.val[0 .. eol0 + 1]);
var val = self.val[eol0 + 1 ..];
while (val.len > 0) {
- const eol = std.mem.indexOfScalar(u8, val, '\n') orelse val.len - 1;
+ const eol = std.mem.findScalar(u8, val, '\n') orelse val.len - 1;
const line = val[0 .. eol + 1];
var spaces = self.key.len;
while (spaces > 0) {
@@ -86,45 +88,44 @@ pub const Config = struct {
return .{ .allocator = allocator, .buf = &.{}, .len = 0 };
}
- pub fn from_file(allocator: std.mem.Allocator, path: []const u8) !Parse_Result {
- var file = std.fs.openFileAbsolute(path, .{}) catch |err| {
- return switch (err) {
- error.FileNotFound => .{ .conf = .init(allocator) },
- else => err,
- };
+ pub fn from_file(allocator: std.mem.Allocator, path: *const fs.Path) !Parse_Result {
+ var read_buf: [512]u8 = undefined;
+ var r = fs.file_reader(path, &read_buf) catch |err| {
+ if (err == error.FileNotFound) return .{ .conf = .init(allocator) };
+ return err;
};
- defer file.close();
-
- var read_buf: [1024]u8 = undefined;
- var reader = file.reader(&read_buf);
- return parse(allocator, &reader.interface, read_buf.len);
+ defer r.deinit();
+ return parse(allocator, &r.interface, read_buf.len);
}
- fn parse(allocator: std.mem.Allocator, reader: *std.io.Reader, comptime max_line_len: usize) !Parse_Result {
+ /// Parse the string in the given buffer. The buffer is reused to store the raw config data.
+ fn parse(allocator: std.mem.Allocator, reader: *std.Io.Reader, comptime max_line_len: usize) !Parse_Result {
const spaces = " \t\r";
- var allocating: std.io.Writer.Allocating = .init(allocator);
-
+ var allocating: std.Io.Writer.Allocating = .init(allocator);
var header: Var_Header = undefined;
var header_off: usize = 0;
var need_key = true;
var file_line: usize = 0;
while (true) {
file_line += 1;
- const raw_line = reader.takeDelimiterExclusive('\n') catch |err| switch (err) {
- error.StreamTooLong => {
- return .{
- .err = .{
- .msg = std.fmt.comptimePrint("key/value line exceeds the maximum of {} bytes", .{max_line_len}),
- .line = file_line,
- },
- };
- },
- error.EndOfStream => {
- break;
- },
- else => unreachable,
+ const raw_line = reader.takeDelimiterExclusive('\n') catch |err| {
+ switch (err) {
+ error.StreamTooLong => {
+ return .{
+ .err = .{
+ .msg = std.fmt.comptimePrint("key/value line exceeds the maximum of {} bytes", .{max_line_len}),
+ .line = file_line,
+ },
+ };
+ },
+ error.EndOfStream => {
+ break;
+ },
+ else => unreachable,
+ }
};
+ if (reader.bufferedLen() > 0) reader.toss(1);
const line = std.mem.trim(u8, raw_line, spaces);
if (line.len == 0 or line[0] == '#') {
@@ -142,8 +143,8 @@ pub const Config = struct {
};
};
- const key = std.mem.trimRight(u8, line[0..eq], spaces);
- const val = std.mem.trimLeft(u8, line[eq + 1 ..], spaces);
+ const key = std.mem.trimEnd(u8, line[0..eq], spaces);
+ const val = std.mem.trimStart(u8, line[eq + 1 ..], spaces);
if (key.len == 0) {
// We have a value continuation here. So we append a newline
@@ -235,11 +236,10 @@ pub const Config = struct {
};
test "parse config - empty" {
- var input = std.io.Reader.fixed("");
- var buf: [32]u8 = undefined;
- var reader = std.io.Reader.limited(&input, std.io.Limit.limited(input.buffer.len), &buf);
+ const input = "";
+ var input_r = std.Io.Reader.fixed(input);
- var result = try Config.parse(std.testing.allocator, &reader.interface, buf.len);
+ var result = try Config.parse(std.testing.allocator, &input_r, input.len);
try std.testing.expect(result == .conf);
try std.testing.expectEqualSlices(u8, "", result.conf.buf[0..result.conf.len]);
defer result.conf.deinit();
@@ -248,12 +248,11 @@ test "parse config - empty" {
try std.testing.expect(vars.next() == null);
}
-test "parse config - singe line" {
- var input = std.io.Reader.fixed("foo one = bar one");
- var buf: [32]u8 = undefined;
- var reader = std.io.Reader.limited(&input, std.io.Limit.limited(input.buffer.len), &buf);
+test "parse config - single line" {
+ const input = "foo one = bar one";
+ var input_r = std.Io.Reader.fixed(input);
- var result = try Config.parse(std.testing.allocator, &reader.interface, buf.len);
+ var result = try Config.parse(std.testing.allocator, &input_r, input.len);
try std.testing.expect(result == .conf);
try std.testing.expectEqualSlices(
u8,
@@ -272,8 +271,8 @@ test "parse config - singe line" {
}
test "parse config - mixed" {
- var input = std.io.Reader.fixed(
- \\foo_one = bar one
+ const input =
+ \\ foo_one = bar one
\\foo_two = bar two 1
\\ = bar two 2
\\ =
@@ -292,11 +291,10 @@ test "parse config - mixed" {
\\
\\foo_five =
\\
- );
- var buf: [32]u8 = undefined;
- var reader = std.io.Reader.limited(&input, std.io.Limit.limited(input.buffer.len), &buf);
+ ;
+ var input_r = std.Io.Reader.fixed(input);
- var result = try Config.parse(std.testing.allocator, &reader.interface, buf.len);
+ var result = try Config.parse(std.testing.allocator, &input_r, input.len);
try std.testing.expect(result == .conf);
try std.testing.expectEqualSlices(
u8,
@@ -336,7 +334,8 @@ test "parse config - mixed" {
}
test "parse config - with comment" {
- var input = std.io.Reader.fixed(
+ const input =
+ \\
\\# first var:
\\foo_one = bar one
\\# second var:
@@ -348,11 +347,10 @@ test "parse config - with comment" {
\\foo_three =
\\ = bar three 2
\\ = bar three 3
- );
- var buf: [32]u8 = undefined;
- var reader = std.io.Reader.limited(&input, std.io.Limit.limited(input.buffer.len), &buf);
+ ;
+ var input_r = std.Io.Reader.fixed(input);
- var result = try Config.parse(std.testing.allocator, &reader.interface, buf.len);
+ var result = try Config.parse(std.testing.allocator, &input_r, input.len);
try std.testing.expect(result == .conf);
try std.testing.expectEqualSlices(
u8,