From: Michael Tremer Date: Thu, 31 Aug 2023 05:17:58 +0000 (+0000) Subject: string: Add function to format/parse intervals X-Git-Tag: 0.9.29~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7edbe258be51c3b9fc709da6a7acef72730943bb;p=pakfire.git string: Add function to format/parse intervals Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/string.h b/src/libpakfire/include/pakfire/string.h index bcdbd0773..b650895d6 100644 --- a/src/libpakfire/include/pakfire/string.h +++ b/src/libpakfire/include/pakfire/string.h @@ -86,6 +86,9 @@ int __pakfire_format_time(char* buffer, const size_t length, const time_t t); size_t pakfire_string_parse_bytes(const char* s); +char* pakfire_string_format_interval(const time_t t); +time_t pakfire_string_parse_interval(const char* buffer); + int pakfire_string_is_url(const char* s); #endif diff --git a/src/libpakfire/string.c b/src/libpakfire/string.c index 56d5a1211..cf04f05b3 100644 --- a/src/libpakfire/string.c +++ b/src/libpakfire/string.c @@ -396,6 +396,93 @@ int __pakfire_format_time(char* buffer, const size_t length, const time_t t) { return __pakfire_strftime(buffer, length, format, t); } +char* pakfire_string_format_interval(const time_t t) { + char* buffer = NULL; + int r; + + if (t < 0) + return NULL; + + // Weeks + else if (t >= 604800) + r = asprintf(&buffer, "%ldw", t / 604800); + + // Days + else if (t >= 86400) + r = asprintf(&buffer, "%ldd", t / 86400); + + // Hours + else if (t >= 3600) + r = asprintf(&buffer, "%ldh", t / 3600); + + // Minutes + else if (t >= 60) + r = asprintf(&buffer, "%ldm", t / 60); + + // Seconds + else + r = asprintf(&buffer, "%lds", t); + + // Handle any errors + if (r < 0) + return NULL; + + return buffer; +} + +time_t pakfire_string_parse_interval(const char* buffer) { + char* unit = NULL; + + // Check inputs + if (!buffer) + return -1; + + // Try reading some numeric value + time_t t = strtoul(buffer, &unit, 10); + + // Convert any units + if (unit && *unit) { + switch (*unit) { + // Weeks + case 'w': + t *= 604800; + break; + + // Days + case 'd': + t *= 86400; + break; + + // Hours + case 'h': + t *= 3600; + break; + + // Minutes + case 'm': + t *= 60; + break; + + // Seconds + case 's': + break; + + // Unknown unit + default: + return -1; + } + + // Move forward + unit++; + + // If there are extra characters after the unit we will have to fail + if (*unit) + return -1; + } + + return t; +} + size_t pakfire_string_parse_bytes(const char* s) { const char* units = "kMGT"; char* unit = NULL; diff --git a/tests/libpakfire/string.c b/tests/libpakfire/string.c index f584e6015..c8520be31 100644 --- a/tests/libpakfire/string.c +++ b/tests/libpakfire/string.c @@ -318,6 +318,50 @@ FAIL: return EXIT_FAILURE; } +static int test_intervals(const struct test* t) { + int r = EXIT_FAILURE; + + // Parse + ASSERT(pakfire_string_parse_interval("0") == 0); + ASSERT(pakfire_string_parse_interval("0s") == 0); + ASSERT(pakfire_string_parse_interval("0m") == 0); + + ASSERT(pakfire_string_parse_interval("1") == 1); + ASSERT(pakfire_string_parse_interval("1s") == 1); + ASSERT(pakfire_string_parse_interval("1m") == 60); + ASSERT(pakfire_string_parse_interval("1d") == 86400); + ASSERT(pakfire_string_parse_interval("1w") == 604800); + + ASSERT(pakfire_string_parse_interval("2s") == 2); + ASSERT(pakfire_string_parse_interval("2m") == 120); + ASSERT(pakfire_string_parse_interval("2h") == 7200); + + // Invalid inputs + ASSERT(pakfire_string_parse_interval(NULL) == -1); + ASSERT(pakfire_string_parse_interval("abc") == -1); + ASSERT(pakfire_string_parse_interval("abc0") == -1); + ASSERT(pakfire_string_parse_interval("0abc") == -1); + + // Format + ASSERT_STRING_EQUALS(pakfire_string_format_interval(0), "0s"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(1), "1s"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(5), "5s"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(60), "1m"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(61), "1m"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(3600), "1h"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(86400), "1d"); + ASSERT_STRING_EQUALS(pakfire_string_format_interval(604800), "1w"); + + // Invalid inputs + ASSERT(pakfire_string_format_interval(-1) == NULL); + + // Everything passed + r = EXIT_SUCCESS; + +FAIL: + return r; +} + int main(int argc, const char* argv[]) { testsuite_add_test(test_string_set); testsuite_add_test(test_string_startswith); @@ -329,6 +373,7 @@ int main(int argc, const char* argv[]) { testsuite_add_test(test_string_join); testsuite_add_test(test_format_size); testsuite_add_test(test_parse_bytes); + testsuite_add_test(test_intervals); return testsuite_run(argc, argv); }