summaryrefslogtreecommitdiff
path: root/src/tc-string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tc-string.c')
-rw-r--r--src/tc-string.c245
1 files changed, 234 insertions, 11 deletions
diff --git a/src/tc-string.c b/src/tc-string.c
index 6e85f66..77235c2 100644
--- a/src/tc-string.c
+++ b/src/tc-string.c
@@ -1,11 +1,5 @@
/* long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing */
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifndef __cplusplus
# include <assert.h>
# include <errno.h>
@@ -90,9 +84,12 @@ static void t_strncat(void)
{
char data[5] = "DATA";
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-truncation"
if (snprintf(data, sizeof(data), "12345678") >=
static_cast(ssize_t, sizeof(data)))
printf("Not enough space\n");
+#pragma GCC diagnostic pop
printf("String: >%s<\n", data);
HX_strlcat(data, "pqrstuv__", 2);
@@ -271,11 +268,13 @@ static void t_strlcpy(void)
HX_timespec_sub(&d2, &stop, &start);
HX_timespec_sub(&d3, &d1, &d2);
- printf("%4zu->%4zu: %1ld.%09ld (str=%ld.%09ld mem=%ld.%09ld)\n",
+ printf("%4zu->%4zu: " HX_TIMESPEC_FMT
+ " (str=" HX_TIMESPEC_FMT
+ " mem=" HX_TIMESPEC_FMT ")\n",
strlen(ibuf), picksizes[opick],
- static_cast(long, d3.tv_sec), d3.tv_nsec,
- static_cast(long, d1.tv_sec), d1.tv_nsec,
- static_cast(long, d2.tv_sec), d2.tv_nsec
+ HX_TIMESPEC_EXP(&d3),
+ HX_TIMESPEC_EXP(&d1),
+ HX_TIMESPEC_EXP(&d2)
);
}
}
@@ -288,6 +287,222 @@ static void t_strlcpy2(void)
assert(a[0] == 49 && a[0] == a[1] && a[1] == a[2]);
}
+static void t_units(void)
+{
+ static const struct {
+ unsigned long long num;
+ const char exp_1024[6], exp_1000[6];
+ } vt[] = {
+ {1023, "1023", "1023"},
+ {1024, "1024", "1024"},
+ {1945, "1945", "1945"},
+ {1946, "1946", "1946"},
+ {1022975, "998k", "1022k"},
+ {1022976, "999k", "1022k"},
+ {1022977, "999k", "1022k"},
+ {1047552, "1023k", "1047k"},
+ {1047553, "1023k", "1047k"},
+ {1992294, "1945k", "1992k"},
+ {1992295, "1945k", "1992k"},
+ {1072693248, "1023M", "1072M"},
+ {1072693249, "1023M", "1072M"},
+ {ULLONG_MAX, "15E", "18E"},
+ };
+ char buf[HXSIZEOF_Z64+3];
+ printf("unit_size:\n");
+
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ HX_unit_size(buf, ARRAY_SIZE(buf), vt[i].num, 1024, 9120);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1024) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1024);
+ abort();
+ }
+ HX_unit_size(buf, ARRAY_SIZE(buf), vt[i].num, 1000, 9120);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1000) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1000);
+ abort();
+ }
+ }
+}
+
+static void t_units_cu(void)
+{
+ static const struct {
+ unsigned long long num;
+ const char exp_1024[6], exp_1000[6];
+ } vt[] = {
+ {1023, "1023", "1.1k"},
+ {1024, "1.0k", "1.1k"},
+ {1945, "1.9k", "2.0k"},
+ {1946, "2.0k", "2.0k"},
+ {1022975, "999k", "1.1M"},
+ {1022976, "999k", "1.1M"},
+ {1022977, "1000k", "1.1M"},
+ {1047552, "1023k", "1.1M"},
+ {1047553, "1.0M", "1.1M"},
+ {1992294, "1.9M", "2.0M"},
+ {1992295, "2.0M", "2.0M"},
+ {1072693248, "1023M", "1.1G"},
+ {1072693249, "1.0G", "1.1G"},
+ {ULLONG_MAX, "16E", "19E"},
+ };
+ char buf[80];
+ printf("unit_size_cu:\n");
+
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ HX_unit_size_cu(buf, ARRAY_SIZE(buf), vt[i].num, 1024);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1024) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1024);
+ abort();
+ }
+ HX_unit_size_cu(buf, ARRAY_SIZE(buf), vt[i].num, 1000);
+ printf("\t%llu -> %s\n", vt[i].num, buf);
+ if (strcmp(buf, vt[i].exp_1000) != 0) {
+ printf("\texpected %s\n", vt[i].exp_1000);
+ abort();
+ }
+ }
+}
+
+static void t_units_strto(void)
+{
+ static const struct {
+ const char input[24];
+ unsigned int exponent;
+ unsigned long long expect_out;
+ const char expect_rem[8];
+ } vt[] = {
+ {"-5k", 1000, ULLONG_MAX, "-5k"},
+ {" -5.2k", 1000, ULLONG_MAX, "-5.2k"},
+ {"1", 9999, 1, ""},
+ {"1024", 9999, 1ULL << 10, ""},
+ {"1048576", 9999, 1ULL << 20, ""},
+ {"1073741824", 9999, 1ULL << 30, ""},
+ {"1099511627776", 9999, 1ULL << 40, ""},
+ {"1125899906842624", 9999, 1ULL << 50, ""},
+ {"1152921504606846976", 9999, 1ULL << 60, ""},
+ {"18446744073709551615", 9, ULLONG_MAX, ""},
+ {"1k", 1000, 1000ULL, ""},
+ {"1M", 1000, 1000000ULL, ""},
+ {"1G", 1000, 1000000000ULL, ""},
+ {"1T", 1000, 1000000000000ULL, ""},
+ {"1P", 1000, 1000000000000000ULL, ""},
+ {"1E", 1000, 1000000000000000000ULL, ""},
+ {"1k", 1024, 1ULL << 10, ""},
+ {"1M", 1024, 1ULL << 20, ""},
+ {"1G", 1024, 1ULL << 30, ""},
+ {"1T", 1024, 1ULL << 40, ""},
+ {"1P", 1024, 1ULL << 50, ""},
+ {"1E", 1024, 1ULL << 60, ""},
+ {"0", 0, 0, ""},
+ {"0k", 0, 0, ""},
+ {"0 Z", 0, 0, ""},
+ {"0.1k", 1000, 100, ""},
+ {"0.1k", 1024, 102, ""},
+ {" 0.1k", 1024, 102, ""},
+ {"0.00000000000000001E", 1024, 11, ""},
+ {"1.525444GiB", 1000, 1525444000, "iB"},
+ {"1.525444GiB", 1024, 1637933022, "iB"},
+ };
+ char *end;
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ unsigned long long q = HX_strtoull_unit(vt[i].input, &end, vt[i].exponent);
+ printf("%s -> %llu __ %s\n", vt[i].input, q, end);
+ if (q != vt[i].expect_out || strcmp(end, vt[i].expect_rem) != 0)
+ printf("BUG\n");
+ }
+}
+
+static void t_time_units(void)
+{
+ static const struct {
+ unsigned long long input;
+ unsigned int flags;
+ const char expect_out[24];
+ } vt[] = {
+ {31536000, 0, "365d"},
+ {31622400, 0, "366d"},
+ {31622400, HXUNIT_YEARS, "1y18h"},
+ {31622400, HXUNIT_MONTHS, "1y"},
+ {31622400, HXUNIT_WEEKS, "1y"},
+ {31622400, HXUNIT_MONTHS | HXUNIT_WEEKS, "1y"},
+ {2678400, HXUNIT_MONTHS, "1month13h30min"},
+ {2592000, HXUNIT_MONTHS, "30d"},
+ {608400, HXUNIT_WEEKS, "1week1h"},
+ {90061, 0, "1d1h1min1s"},
+ {3692, 0, "1h1min32s"},
+ {67, 0, "1min7s"},
+ {1, 0, "1s"},
+ {0, 0, "0s"},
+ };
+ printf("===== HX_unit_seconds\n");
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ char out[60];
+ char *ret = HX_unit_seconds(out, ARRAY_SIZE(out), vt[i].input, vt[i].flags);
+ printf("%llus => \"%s\"\n", vt[i].input, ret);
+ if (strcmp(ret, vt[i].expect_out) != 0)
+ printf("\tBUG, expected \"%s\"\n", vt[i].expect_out);
+ }
+}
+
+static void t_time_strto(void)
+{
+ static const struct {
+ const char *input;
+ unsigned long long expect_out;
+ const char expect_rem[4];
+ } vt[] = {
+ {"1y1month1week1d1h1min1s ", 31557600+2629800+86400*8+3600+60+1, ""},
+ {" -1d", 0, "-1d"},
+ {"1 -", 1, "-"},
+ {"1s", 1, ""},
+ {"1min", 60, ""},
+ {"0", 0, ""},
+ };
+ char *end;
+ printf("===== t_time_strto\n");
+ for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) {
+ unsigned long long q = HX_strtoull_sec(vt[i].input, &end);
+ printf("\"%s\" => %llus + \"%s\"\n", vt[i].input, q, end);
+ if (q != vt[i].expect_out)
+ printf("\tBUG: expected %llus\n", vt[i].expect_out);
+ if (strcmp(end, vt[i].expect_rem) != 0)
+ printf("\tBUG: expected remainder \"%s\"\n", vt[i].expect_rem);
+ }
+}
+
+static int t_strmid(void)
+{
+#define T(spar,opar,lpar,xpar) do { \
+ char *s = HX_strmid((spar), (opar), (lpar)); \
+ if (s == nullptr) \
+ return EXIT_FAILURE; \
+ int ret = strcmp(s, (xpar)); \
+ if (ret != 0) { \
+ fprintf(stderr, "Faillure: substr %s,%d,%d = %s\n", \
+ (spar), static_cast(int, (opar)), static_cast(int, (lpar)), s); \
+ free(s); \
+ return ret; \
+ } \
+ free(s); \
+ } while (false)
+
+ T("Hello World", -12, 5, "");
+ T("bark", -3, -1, "ar");
+ T("cake", -3, -3, "");
+ T("cake", -3, -4, "");
+ T("fun", 0, 0, "");
+ T("bark", 0, 1, "b");
+ T("bark", 0, 5, "bark");
+ T("bark", -4, 1, "b");
+ T("bark", -4, 5, "bark");
+ return EXIT_SUCCESS;
+#undef T
+}
+
int main(int argc, const char **argv)
{
hxmc_t *tx = NULL;
@@ -296,6 +511,9 @@ int main(int argc, const char **argv)
if (HX_init() <= 0)
abort();
+ int ret = t_strmid();
+ if (ret != EXIT_SUCCESS)
+ return EXIT_FAILURE;
fp = fopen(file, "r");
if (fp == NULL) {
@@ -316,6 +534,11 @@ int main(int argc, const char **argv)
t_strtrim();
t_split();
t_split2();
+ t_units();
+ t_units_cu();
+ t_units_strto();
+ t_time_units();
+ t_time_strto();
t_strlcpy();
t_strlcpy2();
HXmc_free(tx);