diff --git a/src/Config.zig b/src/Config.zig index 05397b7..1e3b3da 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -5,31 +5,37 @@ const lj = @import("./labjack.zig"); const Config = @This(); -var global_internal: Config = undefined; -pub const global: *const Config = &global_internal; +var global_internal: std.json.Parsed(Config) = undefined; +pub const global: *const Config = &global_internal.value; pub fn load(allocator: std.mem.Allocator, reader: anytype, err_writer: anytype) !void { var jread = std.json.Reader(1024, @TypeOf(reader)).init(allocator, reader); defer jread.deinit(); - global_internal = try std.json.parseFromTokenSourceLeaky( + global_internal = try std.json.parseFromTokenSource( Config, allocator, &jread, .{}, ); - try global_internal.validate(err_writer); + try global.validate(err_writer); } pub fn loadDefault(allocator: std.mem.Allocator) void { - _ = allocator; - global_internal = .{}; + const arena = allocator.create(std.heap.ArenaAllocator) catch unreachable; + arena.* = std.heap.ArenaAllocator.init(allocator); + global_internal = .{ + .arena = arena, + .value = .{}, + }; } -pub fn destroy(allocator: std.mem.Allocator) void { +pub fn deinit() void { // TODO: implement this probably - _ = allocator; + const allocator = global_internal.arena.child_allocator; + global_internal.arena.deinit(); + allocator.destroy(global_internal.arena); } pub fn validate(self: Config, err_writer: anytype) !void { diff --git a/src/main.zig b/src/main.zig index c011763..0abfca4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -53,37 +53,23 @@ pub fn main() !u8 { } Config.loadDefault(allocator); + defer Config.deinit(); return writeDefaultConfig(if (args.len == 3) args[2] else null); } else if (std.mem.eql(u8, args[1], commands.run)) { if (args.len > 3) { printHelp(exename, .run); return 1; } - blk: { - const confpath = if (args.len == 3) args[2] else "yaes.json"; - const conf_file = std.fs.cwd().openFile(confpath, .{}) catch { - log.warn("Could not load config file '{s}'. Using default config.", .{confpath}); - Config.loadDefault(allocator); - break :blk; - }; - defer conf_file.close(); + loadConfigOrDefault(allocator, if (args.len == 3) args[2] else null) catch + return 1; - Config.load(allocator, conf_file.reader(), std.io.getStdErr().writer()) catch |err| { - log.err("Could not parse config file '{s}': {s}.", .{ confpath, @errorName(err) }); - return 1; - }; - } - defer Config.destroy(allocator); - - const ver = lj.getDriverVersion(); - std.debug.print("Driver version: {d}\n", .{ver}); + defer Config.deinit(); RotCtl.run(allocator) catch |err| { log.err("rotator controller ceased unexpectedly! {s}", .{@errorName(err)}); return 1; }; - return 0; } else if (std.mem.eql(u8, args[1], commands.help)) { if (args.len != 3) { printHelp(exename, .help); @@ -103,6 +89,24 @@ pub fn main() !u8 { printHelp(exename, .main); return 1; } + + return 0; +} + +fn loadConfigOrDefault(allocator: std.mem.Allocator, path: ?[]const u8) !void { + const confpath = path orelse "yaes.json"; + const conf_file = std.fs.cwd().openFile(confpath, .{}) catch { + log.warn("Could not load config file '{s}'. Using default config.", .{confpath}); + Config.loadDefault(allocator); + return; + }; + defer conf_file.close(); + + Config.load(allocator, conf_file.reader(), std.io.getStdErr().writer()) catch |err| { + log.err("Could not parse config file '{s}': {s}.", .{ confpath, @errorName(err) }); + return error.InvalidConfig; + }; + log.info("Loaded config from '{s}'.", .{confpath}); } fn installUdevRules(outpath: ?[]const u8) u8 {