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
|
use fmt;
use ev;
use getopt;
use os;
use time;
use strings;
use strconv;
use math;
type uniterror = !void;
fn timer_handler(file: *ev::file) void = {
const loop = ev::getloop(file);
const t = ev::getuser(file): *time::instant;
const t = *t;
const tn = time::now(time::clock::MONOTONIC);
const currentduration = time::diff(tn, t);
fmt::fprint(os::stderr, "\x1B[1K\r")!;
fmt::fprint(os::stderr, math::ceilf64(currentduration: f64 / time::SECOND: f64): u64)!;
if (currentduration <= 0) {
ev::stop(loop);
};
};
fn parse_duration(duration: const str) (time::duration | uniterror | strconv::invalid | strconv::overflow) = {
const s = strings::toutf8(duration);
const unit = s[len(s)-1];
const unit = switch (unit) {
case 's' =>
yield time::SECOND;
case 'm' =>
yield time::MINUTE;
case 'h' =>
yield time::HOUR;
case =>
return uniterror;
};
const d = strconv::stoi(strings::sub(duration, 0, len(duration) - 1))?;
return d * unit;
};
export fn main() void = {
const cmd = getopt::parse(os::args,
"timer for alarms",
"duration",
);
defer getopt::finish(&cmd);
if (len(cmd.args) != 1) {
getopt::printusage(os::stderr, os::args[0], cmd.help)!;
os::exit(os::status::FAILURE);
};
const duration = cmd.args[0];
const duration = parse_duration(duration)!;
const loop = ev::newloop()!;
const t = time::now(time::clock::MONOTONIC);
const t = time::add(t, duration);
defer ev::finish(&loop);
const f = ev::newtimer(&loop, &timer_handler, time::clock::MONOTONIC)!;
ev::setuser(f, &t);
ev::timer_configure(f, 1 * time::SECOND, 1 * time::SECOND);
for (ev::dispatch(&loop, -1)!) void;
fmt::println()!;
};
|