summaryrefslogtreecommitdiff
path: root/src/utils.c
diff options
context:
space:
mode:
authorLukas Fleischer <lfleischer@calcurse.org>2016-02-10 08:06:37 +0100
committerLukas Fleischer <lfleischer@calcurse.org>2016-02-10 08:24:01 +0100
commitfe0621bafd21acaf9909cb2f8ea65fa56560faed (patch)
treefb6d78acdf2a5ac072c15344297baab30f51f2fe /src/utils.c
parenta3b0c8eed288dacf4c76c6c90c42a99139b1ca01 (diff)
downloadcalcurse-fe0621bafd21acaf9909cb2f8ea65fa56560faed.zip
Allow decimals in durations
Parse durations containing decimal numbers (such as "1.5h") gracefully. Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/utils.c b/src/utils.c
index a6ccec9..4ce9364 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -907,7 +907,7 @@ int parse_duration(const char *string, unsigned *duration)
} state = STATE_INITIAL;
const char *p;
- unsigned in = 0;
+ unsigned in = 0, frac = 0, denom = 1;
unsigned dur = 0;
if (!string || *string == '\0')
@@ -919,20 +919,26 @@ int parse_duration(const char *string, unsigned *duration)
return 0;
} else if ((*p >= '0') && (*p <= '9')) {
in = in * 10 + (int)(*p - '0');
+ if (frac)
+ denom *= 10;
+ } else if (*p == '.') {
+ if (frac)
+ return 0;
+ frac++;
} else {
switch (state) {
case STATE_INITIAL:
if (*p == ':') {
- dur += in * HOURINMIN;
+ dur += in * HOURINMIN / denom;
state = STATE_HHMM_MM;
} else if (*p == 'd') {
- dur += in * DAYINMIN;
+ dur += in * DAYINMIN / denom;
state = STATE_DDHHMM_HH;
} else if (*p == 'h') {
- dur += in * HOURINMIN;
+ dur += in * HOURINMIN / denom;
state = STATE_DDHHMM_MM;
} else if (*p == 'm') {
- dur += in;
+ dur += in / denom;
state = STATE_DONE;
} else {
return 0;
@@ -940,10 +946,10 @@ int parse_duration(const char *string, unsigned *duration)
break;
case STATE_DDHHMM_HH:
if (*p == 'h') {
- dur += in * HOURINMIN;
+ dur += in * HOURINMIN / denom;
state = STATE_DDHHMM_MM;
} else if (*p == 'm') {
- dur += in;
+ dur += in / denom;
state = STATE_DONE;
} else {
return 0;
@@ -951,7 +957,7 @@ int parse_duration(const char *string, unsigned *duration)
break;
case STATE_DDHHMM_MM:
if (*p == 'm') {
- dur += in;
+ dur += in / denom;
state = STATE_DONE;
} else {
return 0;
@@ -964,7 +970,8 @@ int parse_duration(const char *string, unsigned *duration)
break;
}
- in = 0;
+ in = frac = 0;
+ denom = 1;
}
}