From 87908ff7a12c969ca21338ab7ed27ed93a9b09c3 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 14:54:19 +0100 Subject: datatype: fix parsing of time type Properly detect time strings in the lexer without quotation marks. Signed-off-by: Patrick McHardy --- src/datatype.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/datatype.c') diff --git a/src/datatype.c b/src/datatype.c index c93f76a3..0772b507 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -775,8 +775,6 @@ static void time_type_print(const struct expr *expr) minutes = seconds / 60; seconds %= 60; - printf("\""); - if (days > 0) printf("%"PRIu64"d", days); if (hours > 0) @@ -785,8 +783,6 @@ static void time_type_print(const struct expr *expr) printf("%"PRIu64"m", minutes); if (seconds > 0) printf("%"PRIu64"s", seconds); - - printf("\""); } enum { -- cgit v1.2.3 From 262b97bd112cbaed098c7941bd452c7b16a89646 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 14:56:16 +0100 Subject: datatype: less strict time parsing Don't require hours to be in range 0-23 and minutes/seconds in range 0-59. The time_type is used for relative times where it is entirely reasonable to specify 180s instead of 3m. Signed-off-by: Patrick McHardy --- src/datatype.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'src/datatype.c') diff --git a/src/datatype.c b/src/datatype.c index 0772b507..1c837152 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -831,10 +831,6 @@ static struct error_record *time_type_parse(const struct expr *sym, } h = str2int(tmp, c, k); k = 0; - if (h > 23) { - return error(&sym->location, - "Hour needs to be 0-23"); - } mask |= HOUR; break; case 'm': @@ -844,10 +840,6 @@ static struct error_record *time_type_parse(const struct expr *sym, } m = str2int(tmp, c, k); k = 0; - if (m > 59) { - return error(&sym->location, - "Minute needs to be 0-59"); - } mask |= MIN; break; case 's': @@ -857,10 +849,6 @@ static struct error_record *time_type_parse(const struct expr *sym, } s = str2int(tmp, c, k); k = 0; - if (s > 59) { - return error(&sym->location, - "second needs to be 0-59"); - } mask |= SECS; break; default: -- cgit v1.2.3 From 0974fa84f162aecf16b4c252dcb438f7149856ab Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 15:59:44 +0100 Subject: datatype: seperate time parsing/printing from time_type Seperate relative time parsing and printing from the time_type to make it usable for set and set element time related parameters. Signed-off-by: Patrick McHardy --- src/datatype.c | 66 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 25 deletions(-) (limited to 'src/datatype.c') diff --git a/src/datatype.c b/src/datatype.c index 1c837152..f93337b1 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -760,11 +760,9 @@ const struct datatype icmpx_code_type = { .sym_tbl = &icmpx_code_tbl, }; -static void time_type_print(const struct expr *expr) +void time_print(uint64_t seconds) { - uint64_t days, hours, minutes, seconds; - - seconds = mpz_get_uint64(expr->value); + uint64_t days, hours, minutes; days = seconds / 86400; seconds %= 86400; @@ -801,8 +799,8 @@ static uint32_t str2int(char *tmp, const char *c, int k) return atoi(tmp); } -static struct error_record *time_type_parse(const struct expr *sym, - struct expr **res) +struct error_record *time_parse(const struct location *loc, const char *str, + uint64_t *res) { int i, len; unsigned int k = 0; @@ -811,64 +809,82 @@ static struct error_record *time_type_parse(const struct expr *sym, uint64_t d = 0, h = 0, m = 0, s = 0; uint32_t mask = 0; - c = sym->identifier; + c = str; len = strlen(c); for (i = 0; i < len; i++, c++) { switch (*c) { case 'd': - if (mask & DAY) { - return error(&sym->location, + if (mask & DAY) + return error(loc, "Day has been specified twice"); - } + d = str2int(tmp, c, k); k = 0; mask |= DAY; break; case 'h': - if (mask & HOUR) { - return error(&sym->location, + if (mask & HOUR) + return error(loc, "Hour has been specified twice"); - } + h = str2int(tmp, c, k); k = 0; mask |= HOUR; break; case 'm': - if (mask & MIN) { - return error(&sym->location, + if (mask & MIN) + return error(loc, "Minute has been specified twice"); - } + m = str2int(tmp, c, k); k = 0; mask |= MIN; break; case 's': - if (mask & SECS) { - return error(&sym->location, + if (mask & SECS) + return error(loc, "Second has been specified twice"); - } + s = str2int(tmp, c, k); k = 0; mask |= SECS; break; default: if (!isdigit(*c)) - return error(&sym->location, "wrong format"); + return error(loc, "wrong time format"); - if (k++ >= array_size(tmp)) { - return error(&sym->location, - "value too large"); - } + if (k++ >= array_size(tmp)) + return error(loc, "value too large"); break; } } /* default to seconds if no unit was specified */ if (!mask) - s = atoi(sym->identifier); + s = atoi(str); else s = 24*60*60*d+60*60*h+60*m+s; + *res = s; + return NULL; +} + + +static void time_type_print(const struct expr *expr) +{ + time_print(mpz_get_uint64(expr->value)); +} + +static struct error_record *time_type_parse(const struct expr *sym, + struct expr **res) +{ + struct error_record *erec; + uint64_t s; + + erec = time_parse(&sym->location, sym->identifier, &s); + if (erec != NULL) + return erec; + if (s > UINT32_MAX) return error(&sym->location, "value too large"); -- cgit v1.2.3