From e0976a8c3f307d412d425c501c219d622a85555e Mon Sep 17 00:00:00 2001 From: Julian Hurst Date: Fri, 15 Nov 2024 03:09:58 +0100 Subject: Support an ini config file --- config.ha | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ hatask.ha | 24 ++++++++++++++++++------ 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/config.ha b/config.ha index 4936492..a452665 100644 --- a/config.ha +++ b/config.ha @@ -1,4 +1,56 @@ +use dirs; +use path; +use format::ini; +use os; +use fs; +use strings; +use io; + type config = struct { tasksdir: str, context: str, }; + +type cerror = !(fs::error | path::error | ini::error); + +fn readconfig() (config | cerror) = { + const c = dirs::config("hatask"); + const buf = path::init(c, "config.ini")?; + const cpath = path::string(&buf); + const f = os::open(cpath)?; + defer io::close(f)!; + const sc = ini::scan(f); + const c = config { + tasksdir = strings::dup("tasks"), + context = strings::dup("*"), + }; + for (const en => ini::next(&sc)?) { + switch (en.1) { + case "tasksdir" => + c.tasksdir = strings::dup(strings::trim(en.2)); + case "context" => + c.tasksdir = strings::dup(strings::trim(en.2)); + case => + void; + }; + }; + return c; +}; + +fn cfinish(cfg: *config) void = { + free(cfg.tasksdir); + free(cfg.context); +}; + +fn strcerror(e: cerror) str = { + return match (e) { + case let e: fs::error => + yield fs::strerror(e); + case let e: path::error => + yield path::strerror(e); + case let e: ini::error => + yield ini::strerror(e); + case => + abort(); + }; +}; diff --git a/hatask.ha b/hatask.ha index c92f688..0d3374f 100644 --- a/hatask.ha +++ b/hatask.ha @@ -13,6 +13,7 @@ use encoding::utf8; use getopt; use sort; use fnmatch; +use errors; type task = struct { name: str, @@ -157,22 +158,33 @@ export fn main() void = { ); defer getopt::finish(&cmd); - const cfg: config = config { - tasksdir = "tasks", - context = "*", + const cfg: config = match (readconfig()) { + case let cfg: config => + yield cfg; + case let e: fs::error => + match (e) { + case let e: errors::noentry => + fmt::fatal("No config file found"); + case => + fmt::fatal(fs::strerror(e)); + }; + case let e: cerror => + fmt::fatal(strcerror(e)); }; + defer cfinish(&cfg); + + for (let opt .. cmd.opts) { switch (opt.0) { case 'f' => - cfg.tasksdir = opt.1; + cfg.tasksdir = strings::dup(opt.1); case 'c' => - cfg.context = opt.1; + cfg.context = strings::dup(opt.1); case => abort(); }; }; - const tasks = match (listtasks(cfg.tasksdir, cfg.context)) { case let e: rtaskerror => fmt::fatal(strrtaskerror(e)); -- cgit v1.2.3