New time format: "1h30m7s".
This is fairly flexible, so you could say 10s1h, or even 1h1h1h (which is equivalent to 3h). Time parsing is now implemented by a single function, so there should be no inconsistencies. The old [[HH:]MM:]SS syntax is still supported, but not used in prompts.
This commit is contained in:
parent
c0df452c04
commit
34712e643c
6 changed files with 119 additions and 129 deletions
|
|
@ -12,7 +12,7 @@ VPATH = @top_srcdir@
|
|||
|
||||
CC = @CC@
|
||||
MAKEDEPEND = @CC@ -M
|
||||
CPPFLAGS = @CPPFLAGS@ -D_XOPEN_SOURCE=700 -D_XOPEN_SOURCE_EXTENDED
|
||||
CPPFLAGS = @CPPFLAGS@ -D_XOPEN_SOURCE_EXTENDED
|
||||
CFLAGS = @CFLAGS@ -I@top_srcdir@ -I@top_builddir@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
|
|
|||
105
functions.c
105
functions.c
|
|
@ -332,9 +332,7 @@ wchar_t *new;
|
|||
void
|
||||
kedtime()
|
||||
{
|
||||
wchar_t *new, old[64];
|
||||
time_t n;
|
||||
int h, m, s;
|
||||
|
||||
if (!curent) {
|
||||
drawstatus(L"No entry selected.");
|
||||
|
|
@ -344,22 +342,13 @@ int h, m, s;
|
|||
n = curent->en_secs;
|
||||
if (curent->en_started)
|
||||
n += time(NULL) - curent->en_started;
|
||||
h = n / (60 * 60);
|
||||
n %= (60 * 60);
|
||||
m = n / 60;
|
||||
n %= 60;
|
||||
s = n;
|
||||
|
||||
swprintf(old, wsizeof(old), L"%02d:%02d:%02d", h, m, s);
|
||||
if ((new = prompt(L"Duration [HH:MM:SS]:", old, NULL)) == NULL)
|
||||
return;
|
||||
|
||||
if (!swscanf(new, L"%d:%d:%d", &h, &m, &s)) {
|
||||
free(new);
|
||||
if ((n = prduration(L"Duration:", n)) == (time_t) -1) {
|
||||
drawstatus(L"Invalid duration.");
|
||||
return;
|
||||
}
|
||||
|
||||
curent->en_secs = (h * 60 * 60) + (m * 60) + s;
|
||||
curent->en_secs = n;
|
||||
if (curent->en_started)
|
||||
time(&curent->en_started);
|
||||
|
||||
|
|
@ -421,47 +410,17 @@ entry_t *en;
|
|||
void
|
||||
kaddtime()
|
||||
{
|
||||
wchar_t *tstr;
|
||||
int h = 0, m = 0, s = 0, secs;
|
||||
time_t secs;
|
||||
if (!curent) {
|
||||
drawstatus(L"No entry selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((tstr = prompt(L"Time to add ([[HH:]MM:]SS):", NULL, NULL)) == NULL)
|
||||
return;
|
||||
|
||||
if (!*tstr) {
|
||||
drawstatus(L"");
|
||||
free(tstr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (swscanf(tstr, L"%d:%d:%d", &h, &m, &s) != 3) {
|
||||
h = 0;
|
||||
if (swscanf(tstr, L"%d:%d", &m, &s) != 2) {
|
||||
m = 0;
|
||||
if (swscanf(tstr, L"%d", &s) != 1) {
|
||||
free(tstr);
|
||||
if ((secs = prduration(L"Time to add:", 0)) == (time_t) -1) {
|
||||
drawstatus(L"Invalid time format.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(tstr);
|
||||
|
||||
if (m >= 60) {
|
||||
drawstatus(L"Minutes cannot be more than 59.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s >= 60) {
|
||||
drawstatus(L"Seconds cannot be more than 59.");
|
||||
return;
|
||||
}
|
||||
|
||||
secs = s + m*60 + h*60*60;
|
||||
curent->en_secs += secs;
|
||||
save();
|
||||
}
|
||||
|
|
@ -469,48 +428,19 @@ int h = 0, m = 0, s = 0, secs;
|
|||
void
|
||||
kdeltime()
|
||||
{
|
||||
wchar_t *tstr;
|
||||
int h = 0, m = 0, s = 0, secs;
|
||||
time_t secs;
|
||||
if (!curent) {
|
||||
drawstatus(L"No entry selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((tstr = prompt(L"Time to subtract, ([[HH:]MM:]SS):", NULL, NULL)) == NULL)
|
||||
return;
|
||||
|
||||
if (!*tstr) {
|
||||
drawstatus(L"");
|
||||
free(tstr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (swscanf(tstr, L"%d:%d:%d", &h, &m, &s) != 3) {
|
||||
h = 0;
|
||||
if (swscanf(tstr, L"%d:%d", &m, &s) != 2) {
|
||||
m = 0;
|
||||
if (swscanf(tstr, L"%d", &s) != 1) {
|
||||
free(tstr);
|
||||
if ((secs = prduration(L"Time to subtract:", 0)) == (time_t) -1) {
|
||||
drawstatus(L"Invalid time format.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(tstr);
|
||||
if (m >= 60) {
|
||||
drawstatus(L"Minutes cannot be more than 59.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s >= 60) {
|
||||
drawstatus(L"Seconds cannot be more than 59.");
|
||||
return;
|
||||
}
|
||||
|
||||
entry_account(curent);
|
||||
|
||||
secs = s + m*60 + h*60*60;
|
||||
if (curent->en_secs - secs < 0) {
|
||||
drawstatus(L"Remaining time cannot be less than zero.");
|
||||
return;
|
||||
|
|
@ -526,7 +456,8 @@ kmerge()
|
|||
entry_t *en, *ten;
|
||||
int nmarked = 0;
|
||||
wchar_t pr[128];
|
||||
int h, m, s = 0;
|
||||
wchar_t *ct;
|
||||
int s = 0;
|
||||
|
||||
if (!curent) {
|
||||
drawstatus(L"No entry selected.");
|
||||
|
|
@ -550,13 +481,11 @@ int h, m, s = 0;
|
|||
return;
|
||||
}
|
||||
|
||||
h = s / (60 * 60);
|
||||
s %= (60 * 60);
|
||||
m = s / 60;
|
||||
s %= 60;
|
||||
ct = maketime(s);
|
||||
swprintf(pr, wsizeof(pr), L"Merge %d marked entries [%ls] into current entry?",
|
||||
nmarked, ct);
|
||||
free(ct);
|
||||
|
||||
swprintf(pr, wsizeof(pr), L"Merge %d marked entries [%02d:%02d:%02d] into current entry?",
|
||||
nmarked, h, m, s);
|
||||
if (!yesno(pr))
|
||||
return;
|
||||
|
||||
|
|
@ -699,15 +628,7 @@ wchar_t *name;
|
|||
return;
|
||||
}
|
||||
|
||||
if (itime) {
|
||||
duration = time(NULL) - itime;
|
||||
} else {
|
||||
int h, m, s;
|
||||
if (prduration(L"Duration [HH:MM:SS]:", &h, &m, &s) == -1)
|
||||
return;
|
||||
|
||||
duration = (h * 60 * 60) + (m * 60) + s;
|
||||
}
|
||||
|
||||
itime = 0;
|
||||
running->en_secs += (time(NULL) - running->en_started);
|
||||
|
|
|
|||
78
str.c
78
str.c
|
|
@ -133,3 +133,81 @@ wchar_t **p;
|
|||
free(*vec);
|
||||
}
|
||||
|
||||
time_t
|
||||
parsetime(tm)
|
||||
wchar_t *tm;
|
||||
{
|
||||
int h = 0, m = 0, s = 0;
|
||||
time_t i = 0, r = 0;
|
||||
|
||||
/* The empty string is not a valid duration */
|
||||
if (!*tm)
|
||||
return (time_t) -1;
|
||||
/* Check for "hh:mm:ss" or "mm:ss" */
|
||||
if (swscanf(tm, L"%d:%d:%d", &h, &m, &s) == 3)
|
||||
return (h * 60 * 60) + (m * 60) + s;
|
||||
|
||||
if (swscanf(tm, L"%d:%d", &m, &s) == 2)
|
||||
return (m * 60) + s;
|
||||
|
||||
/*
|
||||
* The string could either be a format like 3h10m, or a simle number like 47
|
||||
* (meaning seconds), which is also handled here. This is effectively an
|
||||
* implementation of atoi with special meaning for 'h', 'm' and 's' characters.
|
||||
*
|
||||
* Note that we make no attempt to handle overflow.
|
||||
*/
|
||||
for (; *tm; tm++) {
|
||||
switch (*tm) {
|
||||
case L'h':
|
||||
r += i * (60 * 60);
|
||||
i = 0;
|
||||
continue;
|
||||
|
||||
case L'm':
|
||||
r += i * 60;
|
||||
i = 0;
|
||||
continue;
|
||||
|
||||
case L's':
|
||||
r += i;
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wcschr(L"0123456789", *tm) == NULL)
|
||||
return (time_t) -1;
|
||||
|
||||
i *= 10;
|
||||
i += *tm - L'0';
|
||||
}
|
||||
|
||||
return r + i;
|
||||
}
|
||||
|
||||
wchar_t *
|
||||
maketime(tm)
|
||||
time_t tm;
|
||||
{
|
||||
wchar_t res[64] = {};
|
||||
wchar_t t[16];
|
||||
|
||||
if (tm >= (60 * 60)) {
|
||||
swprintf(t, wsizeof(t), L"%dh", tm / (60 * 60));
|
||||
wcslcat(res, t, sizeof(res));
|
||||
tm %= (60 * 60);
|
||||
}
|
||||
|
||||
if (tm >= 60) {
|
||||
swprintf(t, wsizeof(t), L"%dm", tm / 60);
|
||||
wcslcat(res, t, sizeof(res));
|
||||
tm %= 60;
|
||||
}
|
||||
|
||||
if (tm) {
|
||||
swprintf(t, wsizeof(t), L"%ds", tm);
|
||||
wcslcat(res, t, sizeof(res));
|
||||
}
|
||||
|
||||
return wcsdup(res);
|
||||
}
|
||||
|
|
|
|||
6
str.h
6
str.h
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
#include "wide.h"
|
||||
|
||||
size_t tokenise(const wchar_t *, wchar_t ***result);
|
||||
void tokfree(wchar_t ***);
|
||||
size_t tokenise (const wchar_t *, wchar_t ***result);
|
||||
void tokfree (wchar_t ***);
|
||||
time_t parsetime (wchar_t *);
|
||||
wchar_t *maketime (time_t);
|
||||
|
||||
#endif /* !TTS_STR_H */
|
||||
|
|
|
|||
43
ui.c
43
ui.c
|
|
@ -14,6 +14,7 @@
|
|||
#include "ui.h"
|
||||
#include "tts.h"
|
||||
#include "style.h"
|
||||
#include "str.h"
|
||||
|
||||
WINDOW *titwin, *statwin, *listwin;
|
||||
int in_curses;
|
||||
|
|
@ -601,15 +602,23 @@ chtype oldbg;
|
|||
wbkgdset(listwin, oldbg);
|
||||
}
|
||||
|
||||
int
|
||||
prduration(pr, hh, mm, ss)
|
||||
time_t
|
||||
prduration(pr, def)
|
||||
wchar_t *pr;
|
||||
int *hh, *mm, *ss;
|
||||
time_t def;
|
||||
{
|
||||
wchar_t *defstr = NULL;
|
||||
wchar_t *tstr;
|
||||
int h, m, s;
|
||||
if ((tstr = prompt(pr, L"00:00:00", NULL)) == NULL)
|
||||
time_t ret;
|
||||
|
||||
defstr = maketime(def);
|
||||
|
||||
if ((tstr = prompt(pr, defstr, NULL)) == NULL) {
|
||||
free(defstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(defstr);
|
||||
|
||||
if (!*tstr) {
|
||||
drawstatus(L"No duration entered");
|
||||
|
|
@ -617,33 +626,13 @@ int h, m, s;
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (swscanf(tstr, L"%d:%d:%d", &h, &m, &s) != 3) {
|
||||
h = 0;
|
||||
if (swscanf(tstr, L"%d:%d", &m, &s) != 2) {
|
||||
m = 0;
|
||||
if (swscanf(tstr, L"%d", &s) != 1) {
|
||||
if ((ret = parsetime(tstr)) == (time_t) -1) {
|
||||
free(tstr);
|
||||
drawstatus(L"Invalid time format.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(tstr);
|
||||
|
||||
if (m >= 60) {
|
||||
drawstatus(L"Minutes cannot be more than 59.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s >= 60) {
|
||||
drawstatus(L"Seconds cannot be more than 59.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*hh = h;
|
||||
*mm = m;
|
||||
*ss = s;
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
2
ui.h
2
ui.h
|
|
@ -30,7 +30,7 @@ void drawheader (void);
|
|||
void drawentries (void);
|
||||
|
||||
wchar_t *prompt (wchar_t const *, wchar_t const *, history_t *);
|
||||
int prduration (wchar_t *prompt, int *h, int *m, int *s);
|
||||
time_t prduration (wchar_t *prompt, time_t def);
|
||||
int yesno (wchar_t const *);
|
||||
void errbox (wchar_t const *, ...);
|
||||
void verrbox (wchar_t const *, va_list);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue