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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <poll.h>
int parse(char *s) {
int cur=0,tot=0;
int pos; char c;
for (pos=0; c=s[pos],c!=0; pos++) {
if ('0'<=c && c<='9') {
cur*=10;
cur+=c-'0';
} else {
switch(c) {
case 'h': cur *= 60;
case 'm': cur *= 60;
case 's': break;
default: return -1;
}
tot+=cur; cur=0;
}
}
return tot+cur;
}
void disp(int secs) {
int rem;
int h = secs/3600; rem= secs%3600;
int m = rem/60; int s = rem%60;
if (h>0) printf("%02dh",h);
if (h>0||m>0) printf("%02dm",m);
printf("%02ds",s);
fflush(stdout);
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s TIMESPEC\n", argv[0]);
exit(1);
}
int secs = parse(argv[1]);
if (secs==0) return 0;
if (secs<0) {
fprintf(stderr, "%s: invalid timespec %s\n", argv[0], argv[1]);
exit(1);
}
struct termios orig_term, new_term;
tcgetattr(0, &orig_term);
memcpy(&new_term, &orig_term, sizeof(struct termios));
cfmakeraw(&new_term);
tcsetattr(0, TCSADRAIN, &new_term);
int paused = 0;
struct pollfd pf = {
.fd = 0,
.events = POLLIN,
};
while (secs>0) {
if (paused) printf("[paused] ");
disp(secs);
int rc = poll(&pf, 1, paused ? -1 : 1000);
if (rc == 0 && !paused) secs--;
printf("\033[2K\033[G");
if (pf.revents & POLLIN) {
char c;
read(0,&c,1);
switch(c){
case 'q':
case 3: // ctrl-C
goto end;
case '+':
secs+=10;
break;
case '=':
secs++;
break;
case '_':
secs -= 10;
if (secs <= 0) secs=10;
break;
case '-':
secs--;
if (secs <= 0) secs=1;
break;
case ' ':
paused = !paused;
break;
}
}
}
end:
tcsetattr(0, TCSADRAIN, &orig_term);
return 0;
}
|