From 6b32f45534443a24b1e82a7ea4461f2e0932b18b Mon Sep 17 00:00:00 2001 From: dusk Date: Thu, 28 Sep 2023 18:22:44 +0200 Subject: [PATCH] implment config file parsing via iterator --- src/Config/config.zig | 90 +++++++++++++++++++++++++++++++++++-------- src/main.zig | 7 +++- 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/Config/config.zig b/src/Config/config.zig index 7ed5ccc..3e7ac7b 100644 --- a/src/Config/config.zig +++ b/src/Config/config.zig @@ -2,27 +2,85 @@ const std = @import("std"); const fs = std.fs; const io = std.io; -pub fn getConfig(path: []const u8) void { - var file = fs.cwd().createFile(path, .{.read = true, .truncate = false}) catch |err| { - // TODO: Tirar error cap a dalt - std.debug.print("Error opening config file '{s}': {any}", .{ path, err }); - return; - }; - defer file.close(); +pub const Option = struct { + key: []const u8, + value: []const u8, +}; - var buf: [256]u8 = undefined; +pub const ConfigIterator = struct { + filename: []const u8, + file: fs.File, + buf: [1024]u8, + i: i32 = 0, - var fbs = io.fixedBufferStream(&buf); + pub fn next(self: *ConfigIterator) ?Option { + if (self.i >= 1024) { + std.debug.print("WARNING: Maximum number of lines in config reached, ignoring the rest.\n", .{}); + return null; + } - var reader = file.reader(); + var reader = self.file.reader(); + var fbs = io.fixedBufferStream(&self.buf); + var writer = fbs.writer(); - while (true) { - reader.streamUntilDelimiter(fbs.writer(), '\n', buf.len) catch |err| { - std.debug.print("{any}\n", .{err}); - break; + reader.streamUntilDelimiter(writer, '\n', self.buf.len) catch |err| { + if (err == error.EndOfStream) { + return null; + } else { + std.debug.print("ConfigIterator Error: {any}\n", .{err}); + unreachable; + } }; - defer fbs.reset(); - std.debug.print("{s}\n", .{fbs.getWritten()}); + var line = fbs.getWritten(); + + var keyval = std.mem.split(u8, line, "="); + + var result = Option{ + .key = keyval.next() orelse { + std.debug.print("Config {s}: line {} with contents '{s}' is invalid. Skipping.\n", .{ + self.filename, + self.i, + line, + }); + self.i += 1; + return self.next(); + }, + .value = keyval.next() orelse { + std.debug.print("Config {s}: line {} with contents '{s}' is invalid. Skipping.\n", .{ + self.filename, + self.i, + line, + }); + self.i += 1; + return self.next(); + }, + }; + + if (keyval.next() != null) { + std.debug.print("Config {s}: line {} with contents '{s}' is invalid. Skipping.\n", .{ + self.filename, + self.i, + line, + }); + self.i += 1; + return self.next(); + } + + self.i += 1; + return result; } + pub fn deinit(self: *ConfigIterator) void { + self.file.close(); + } +}; + +pub fn getConfigIterator(path: []const u8) !ConfigIterator { + var iterator = ConfigIterator{ + .filename = path, + .file = try fs.cwd().createFile(path, .{ .read = true, .truncate = false }), + .buf = undefined, + }; + + return iterator; } diff --git a/src/main.zig b/src/main.zig index ceea022..b285b4b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -11,7 +11,12 @@ const State = @import("flow.zig").State; pub fn main() !void { - config.getConfig("test"); + var configIterator = config.getConfigIterator("test") catch unreachable; + while (configIterator.next()) |option| { + std.debug.print("Key: {s}, Option: {s}\n", .{option.key, option.value}); + } + configIterator.deinit(); + var renderer = try Renderer.init(); defer renderer.deinit();