1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
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,
debug: bool,
};
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 = [],
debug = false,
};
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 "debug" =>
c.debug = en.2 == "true";
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::errorfln("tasksdir: {}", cfg.tasksdir)!;
fmt::errorfln("context: {}", cfg.context)!;
const stags = strings::join(",", cfg.tags...);
defer free(stags);
fmt::errorfln("tags: {}", stags)!;
};
|