use dirs; use path; use format::ini; use os; use fs; use strings; use io; use fmt; type config = struct { tasksdir: str, context: str, tags: []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("*"), tags = [], }; for (const en => ini::next(&sc)?) { switch (en.1) { case "tasksdir" => c.tasksdir = strings::dup(strings::trim(en.2)); case "context" => c.context = strings::dup(strings::trim(en.2)); case "tags" => c.tags = strings::dupall(strings::split(strings::trim(en.2), ",")); case => void; }; }; return c; }; fn cfinish(cfg: *config) void = { free(cfg.tasksdir); free(cfg.context); strings::freeall(cfg.tags); }; 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(); }; }; fn printconfig(cfg: config) void = { fmt::errorln(cfg.tasksdir)!; fmt::errorln(cfg.context)!; for (const tag .. cfg.tags) { fmt::errorln(tag)!; }; };