diff --git a/build.zig b/build.zig index 1ed4e1f..c192a6b 100644 --- a/build.zig +++ b/build.zig @@ -24,6 +24,9 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); + const ini = b.dependency("ini", .{}); + exe.addModule("ini", ini.module("ini")); + exe.linkSystemLibrary("pam"); exe.linkSystemLibrary("xcb"); exe.linkLibC(); diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..32efe83 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,10 @@ +.{ + .name = "ly", + .version = "0.7.0", + .dependencies = .{ + .ini = .{ + .url = "https://github.com/AnErrupTion/zig-ini/archive/a40f3cae04939de0d795812a73633e0563cf3132.tar.gz", + .hash = "1220b39fc35714d235fd9633422f5ba3c4aba44f1ecaf29cf91515963f0b08a3da89", + }, + } +} \ No newline at end of file diff --git a/src/config.zig b/src/config.zig index f25d2f0..ef3940e 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1,6 +1,6 @@ const std = @import("std"); +const ini = @import("ini"); const main = @import("main.zig"); -const ini = @import("ini.zig"); const interop = @import("interop.zig"); const INI_CONFIG_PATH: []const u8 = "/etc/ly/"; diff --git a/src/ini.zig b/src/ini.zig deleted file mode 100644 index a2a510b..0000000 --- a/src/ini.zig +++ /dev/null @@ -1,179 +0,0 @@ -const std = @import("std"); - -pub const Token = union(enum) { comment, section: []const u8, key: []const u8, value: []const u8 }; - -pub fn getTok(data: []const u8, pos: *usize) ?Token { - // If the position advances to the end of the data, there's no more tokens for us - if (pos.* >= data.len) { - return null; - } - - while (pos.* < data.len) { - var current = data[pos.*]; - pos.* += 1; - - switch (current) { - ' ', '\t', '\r', '\n' => {}, - '[' => { - var start = pos.*; - - current = data[pos.*]; - - while (current != ']') : (pos.* += 1) { - current = data[pos.*]; - } - - return Token{ .section = data[start .. pos.* - 1] }; - }, - '=' => { - current = data[pos.*]; - - while (current == ' ' or current == '\t') { - pos.* += 1; - current = data[pos.*]; - } - - var start = pos.*; - - while (current != '\n') : (pos.* += 1) { - current = data[pos.*]; - } - - return Token{ .value = if (start == pos.*) "" else data[start .. pos.* - 1] }; - }, - ';', '#' => { - current = data[pos.*]; - - while (current != '\n') : (pos.* += 1) { - current = data[pos.*]; - } - - return Token.comment; - }, - else => { - var start = pos.* - 1; - - current = data[pos.*]; - - while (std.ascii.isAlphanumeric(current) or current == '_') : (pos.* += 1) { - current = data[pos.*]; - } - - pos.* -= 1; - - return Token{ .key = data[start..pos.*] }; - }, - } - } - - return null; -} -pub fn readToStruct(comptime T: type, data: []const u8) !T { - var namespace: []const u8 = ""; - var pos: usize = 0; - var ret = std.mem.zeroes(T); - while (getTok(data, &pos)) |tok| { - switch (tok) { - .comment => {}, - .section => |ns| { - namespace = ns; - }, - .key => |key| { - var next_tok = getTok(data, &pos); - // if there's nothing just give a comment which is also a syntax error - switch (next_tok orelse .comment) { - .value => |value| { - // now we have the namespace, key, and value - // namespace and key are runtime values, so we need to loop the struct instead of using @field - inline for (std.meta.fields(T)) |ns_info| { - if (eql(ns_info.name, namespace)) { - // @field(ret, ns_info.name) contains the inner struct now - // loop over the fields of the inner struct, and check for key matches - inline for (std.meta.fields(@TypeOf(@field(ret, ns_info.name)))) |key_info| { - if (std.mem.eql(u8, key_info.name, key)) { - // now we have a key match, give it the value - const my_type = @TypeOf(@field(@field(ret, ns_info.name), key_info.name)); - @field(@field(ret, ns_info.name), key_info.name) = try convert(my_type, value); - } - } - } - } - }, - // after a key, a value must follow - else => return error.NoValueAfterKey, - } - }, - // if we get a value with no key, that's a bit nonsense - .value => return error.ValueWithNoKey, - } - } - return ret; -} -// I'll add more later -const truthyAndFalsy = std.ComptimeStringMap(bool, .{ .{ "true", true }, .{ "false", false }, .{ "1", true }, .{ "0", false } }); -pub fn convert(comptime T: type, val: []const u8) !T { - return switch (@typeInfo(T)) { - .Int, .ComptimeInt => try parseInt(T, val, 0), - .Float, .ComptimeFloat => try std.fmt.parseFloat(T, val), - .Bool => truthyAndFalsy.get(val).?, - .Enum => std.meta.stringToEnum(T, val).?, - else => @as(T, val), - }; -} -pub fn writeStruct(struct_value: anytype, writer: anytype) !void { - inline for (std.meta.fields(@TypeOf(struct_value))) |field| { - try writer.print("[{s}]\n", .{field.name}); - const pairs = @field(struct_value, field.name); - inline for (std.meta.fields(@TypeOf(pairs))) |pair| { - const key_value = @field(pairs, pair.name); - const key_value_type = @TypeOf(key_value); - const key_value_type_info = @typeInfo(key_value_type); - - if (key_value_type == []const u8) { - try writer.print("{s} = {s}\n", .{ pair.name, key_value }); - } else if (key_value_type_info == .Enum) { - inline for (key_value_type_info.Enum.fields) |f| { - var buffer: [128]u8 = undefined; - var haystack = try std.fmt.bufPrint(&buffer, "{}", .{key_value}); - - // TODO: Check type? - if (std.mem.endsWith(u8, haystack, f.name)) { - try writer.print("{s} = {s}\n", .{ pair.name, f.name }); - } - } - } else { - try writer.print("{s} = {}\n", .{ pair.name, key_value }); - } - } - } -} -// Checks if the string is actually a single ASCII character, else, parse as an integer -fn parseInt(comptime T: type, buf: []const u8, base: u8) std.fmt.ParseIntError!T { - if (buf.len == 1) { - var first_char = buf[0]; - - if (std.ascii.isASCII(first_char) and !std.ascii.isDigit(first_char)) { - return first_char; - } - } - - return std.fmt.parseInt(T, buf, base); -} -// Checks if 2 strings are equal, but comparing " " with "_" -fn eql(a: []const u8, b: []const u8) bool { - if (a.len != b.len) { - return false; - } - - if (a.ptr == b.ptr) { - return true; - } - - for (a, b) |a_elem, b_elem| { - if (a_elem != if (b_elem == ' ') '_' else b_elem) { - return false; - } - } - - return true; -} diff --git a/src/utils.zig b/src/utils.zig index 8e62e49..5cf1891 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -1,6 +1,6 @@ const std = @import("std"); +const ini = @import("ini"); const main = @import("main.zig"); -const ini = @import("ini.zig"); const config = @import("config.zig"); const interop = @import("interop.zig");