int __pakfire_strftime_now(char* buffer, const size_t length, const char* format)
__attribute__((format(strftime, 3, 0)));
+size_t pakfire_string_parse_bytes(const char* s);
+
#endif
#endif /* PAKFIRE_STRING_H */
return __pakfire_strftime(buffer, length, format, t);
}
+
+size_t pakfire_string_parse_bytes(const char* s) {
+ const char* units = "kMGT";
+ char* unit = NULL;
+
+ // Read the numeric value
+ size_t bytes = strtoul(s, &unit, 10);
+
+ // Return bytes if there is no unit
+ if (!unit || !*unit)
+ return bytes;
+
+ // Is the unit of the correct length?
+ const size_t length = strlen(unit);
+ if (length > 1)
+ goto ERROR;
+
+ // Walk through all units and find a match
+ for (const char* u = units; *u; u++) {
+ bytes *= 1024;
+
+ // End if the unit matches
+ if (*unit == *u)
+ return bytes;
+ }
+
+ERROR:
+ errno = EINVAL;
+ return 0;
+}
return EXIT_FAILURE;
}
+static int test_parse_bytes(const struct test* t) {
+ // Zero without unit
+ ASSERT(pakfire_string_parse_bytes("0") == (size_t)0);
+
+ // Zero with valid units
+ ASSERT(pakfire_string_parse_bytes("0k") == (size_t)0);
+ ASSERT(pakfire_string_parse_bytes("0M") == (size_t)0);
+ ASSERT(pakfire_string_parse_bytes("0G") == (size_t)0);
+ ASSERT(pakfire_string_parse_bytes("0T") == (size_t)0);
+
+ // Zero with invalid units
+ ASSERT_ERRNO(pakfire_string_parse_bytes("0X") == (size_t)0, EINVAL);
+ ASSERT_ERRNO(pakfire_string_parse_bytes("0XX") == (size_t)0, EINVAL);
+ ASSERT_ERRNO(pakfire_string_parse_bytes("0MM") == (size_t)0, EINVAL);
+
+ // One with valid units
+ ASSERT(pakfire_string_parse_bytes("1") == (size_t)1);
+ ASSERT(pakfire_string_parse_bytes("1k") == (size_t)1024);
+ ASSERT(pakfire_string_parse_bytes("1M") == (size_t)1024 * 1024);
+ ASSERT(pakfire_string_parse_bytes("1G") == (size_t)1024 * 1024 * 1024);
+ ASSERT(pakfire_string_parse_bytes("1T") == (size_t)1024 * 1024 * 1024 * 1024);
+
+ return EXIT_SUCCESS;
+
+FAIL:
+ return EXIT_FAILURE;
+}
+
int main(int argc, const char* argv[]) {
testsuite_add_test(test_string_set);
testsuite_add_test(test_string_startswith);
testsuite_add_test(test_string_split);
testsuite_add_test(test_string_join);
testsuite_add_test(test_format_size);
+ testsuite_add_test(test_parse_bytes);
return testsuite_run(argc, argv);
}