]> git.ipfire.org Git - pakfire.git/commitdiff
string: Add function to format/parse intervals
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 31 Aug 2023 05:17:58 +0000 (05:17 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 31 Aug 2023 05:17:58 +0000 (05:17 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/string.h
src/libpakfire/string.c
tests/libpakfire/string.c

index bcdbd0773bf59713fbce39b9e56260bdb13b9189..b650895d61b3ceaf5be6cadc416033493a9936df 100644 (file)
@@ -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
index 56d5a12116073918c1b0aba7f176666b0e39d9d7..cf04f05b3d738c6fe727754c3b8dec2fdbe93959 100644 (file)
@@ -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;
index f584e60156e714b48588ac4d1aa767a8e3e4d52e..c8520be3102c62a7bcc4c009e12b62e0bc68454b 100644 (file)
@@ -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);
 }