summaryrefslogtreecommitdiff
path: root/src/Config.zig
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2021-12-21 05:56:41 +0200
committerGravatar Uko Kokņevičs2021-12-21 05:56:41 +0200
commit2d2278364b6186c6cdf0f0497b0498431dfe7dd1 (patch)
tree8f2329afbc90817c855f5c5154a547a58a9458aa /src/Config.zig
downloades-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.tar.gz
es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.tar.xz
es-2d2278364b6186c6cdf0f0497b0498431dfe7dd1.zip
Initial config
Diffstat (limited to 'src/Config.zig')
-rw-r--r--src/Config.zig78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/Config.zig b/src/Config.zig
new file mode 100644
index 0000000..b8b45a5
--- /dev/null
+++ b/src/Config.zig
@@ -0,0 +1,78 @@
1// TODO: Change this to proper TOML in the future :)
2
3const std = @import("std");
4
5const Allocator = std.mem.Allocator;
6const BufMap = std.BufMap;
7const Config = @This();
8
9const config_path = "arkta/es/es.ini";
10
11line_limit: usize = 100,
12page_overlap: usize = 2,
13tab_stop: usize = 8,
14
15pub fn readConfig(allocator: Allocator) !Config {
16 var config = Config {};
17
18 var env_map = try std.process.getEnvMap(allocator);
19 defer env_map.deinit();
20
21 if (env_map.get("XDG_CONFIG_DIRS")) |base_dirs| {
22 var it = std.mem.split(u8, base_dirs, ":");
23 while (it.next()) |base_dir| {
24 try readConfigInBaseDir(allocator, &config, base_dir);
25 }
26 } else {
27 try readConfigInBaseDir(allocator, &config, "/etc/xdg");
28 }
29
30 if (env_map.get("XDG_CONFIG_HOME")) |base_dir| {
31 try readConfigInBaseDir(allocator, &config, base_dir);
32 } else {
33 // TODO: Maybe return an error instead of .?
34 const home = env_map.get("HOME").?;
35 const home_config = try std.fs.path.join(allocator, &.{home, ".config"});
36 defer allocator.free(home_config);
37
38 try readConfigInBaseDir(allocator, &config, home_config);
39 }
40
41 return config;
42}
43
44fn readConfigInBaseDir(allocator: Allocator, config: *Config, base_dir: []const u8) !void {
45 const filename = try std.fs.path.join(allocator, &.{base_dir, config_path});
46 defer allocator.free(filename);
47
48 const file = std.fs.openFileAbsolute(filename, .{ .read = true }) catch |err| switch (err) {
49 error.FileNotFound => return,
50 else => return err,
51 };
52 defer file.close();
53
54 const reader = file.reader();
55 while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', 4096)) |line_buf| {
56 defer allocator.free(line_buf);
57
58 var line = std.mem.trim(u8, line_buf, &std.ascii.spaces);
59 if (line.len == 0 or line[0] == '#') {
60 continue;
61 }
62
63 const split = if (std.mem.indexOfScalar(u8, line, '=')) |idx| idx else {
64 return error.MalformedConfig;
65 };
66
67 const key = std.mem.trimRight(u8, line[0..split], &std.ascii.spaces);
68 const value = std.mem.trimLeft(u8, line[(split + 1)..], &std.ascii.spaces);
69 if (std.mem.eql(u8, key, "line-limit")) {
70 config.line_limit = try std.fmt.parseUnsigned(usize, value, 0);
71 } else if (std.mem.eql(u8, key, "page-overlap")) {
72 config.page_overlap = try std.fmt.parseUnsigned(usize, value, 0);
73 } else if (std.mem.eql(u8, key, "line-limit")) {
74 config.line_limit = try std.fmt.parseUnsigned(usize, value, 0);
75 }
76 // TODO: else ??
77 }
78}