commit bb47b8c7080fef280782cdbc00a07a4a2f0403b6
parent 6393a61c8e9727deed182e362c37ebbd2eacecff
Author: vaplv <vaplv@free.fr>
Date: Tue, 26 Jul 2022 14:36:05 +0200
Implement and test the size_to_cstr function
Diffstat:
| M | src/cstr.c | | | 93 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
| M | src/cstr.h | | | 17 | +++++++++++++++++ |
| M | src/test_cstr.c | | | 97 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/test_time.c | | | 14 | +++++++------- |
4 files changed, 213 insertions(+), 8 deletions(-)
diff --git a/src/cstr.c b/src/cstr.c
@@ -28,7 +28,7 @@
#define CSTR_LIST_SUFFIX uint
#include "cstr_to_list.h"
-RSYS_API res_T
+res_T
cstr_parse_list
(const char* str,
const char delimiter,
@@ -68,3 +68,94 @@ error:
goto exit;
}
+void
+size_to_cstr
+ (const size_t size_byte,
+ const int flag, /* Combination of size_unit */
+ size_t* real_cstr_len, /* May be NULL */
+ char* cstr, /* May be NULL */
+ const size_t sizeof_cstr)
+{
+ size_t available_cstr_space = sizeof_cstr;
+ size_t size = size_byte;
+ char* dst = cstr;
+ ASSERT((!sizeof_cstr || cstr));
+ ASSERT(size_byte <= INT64_MAX);
+
+ if(real_cstr_len) *real_cstr_len = 0;
+ if(sizeof_cstr > 0) cstr[0] = '\0';
+ if(!flag) return;
+
+ #define NBYTES_PER_KBYTE ((size_t)1024)
+ #define NBYTES_PER_MBYTE ((size_t)1024 * NBYTES_PER_KBYTE)
+ #define NBYTES_PER_GBYTE ((size_t)1024 * NBYTES_PER_MBYTE)
+ #define NBYTES_PER_TBYTE ((size_t)1024 * NBYTES_PER_GBYTE)
+
+ #define DUMP(Size, Suffix) \
+ { \
+ const int len = snprintf \
+ (dst, available_cstr_space, "%li %s ", (long)Size, Suffix); \
+ ASSERT(len >= 0); \
+ if(real_cstr_len) { \
+ *real_cstr_len += (size_t)len; \
+ } \
+ if((size_t)len < available_cstr_space) { \
+ dst += len; \
+ available_cstr_space -= (size_t)len; \
+ } else if(dst) { \
+ available_cstr_space = 0; \
+ dst = NULL; \
+ } \
+ } (void) 0
+
+ if(flag & SIZE_TBYTE) {
+ const size_t nb_teras = size / NBYTES_PER_TBYTE;
+ if(nb_teras) DUMP(nb_teras, "TB");
+ size -= nb_teras * NBYTES_PER_TBYTE;
+ }
+ if(flag & SIZE_GBYTE) {
+ const size_t nb_gigas = size / NBYTES_PER_GBYTE;
+ if(nb_gigas) DUMP(nb_gigas, "GB");
+ size -= nb_gigas * NBYTES_PER_GBYTE;
+ }
+ if(flag & SIZE_MBYTE) {
+ const size_t nb_megas = size / NBYTES_PER_MBYTE;
+ if(nb_megas) DUMP(nb_megas, "MB");
+ size -= nb_megas * NBYTES_PER_MBYTE;
+ }
+ if(flag & SIZE_KBYTE) {
+ const size_t nb_kilos = size / NBYTES_PER_KBYTE;
+ if(nb_kilos) DUMP(nb_kilos, "KB");
+ size -= nb_kilos * NBYTES_PER_KBYTE;
+ }
+ if(flag & SIZE_BYTE) {
+ if(size) DUMP(size, "B");
+ }
+
+ /* Remove last space */
+ if(real_cstr_len) *real_cstr_len -= 1;
+
+ if(sizeof_cstr > 0) {
+ size_t cstr_len = strlen(cstr);
+
+ if(!cstr_len && flag) {
+ ASSERT(size_byte == 0);
+ if(flag & SIZE_BYTE) { DUMP(0, "B");
+ } else if(flag & SIZE_KBYTE) { DUMP(0, "KB");
+ } else if(flag & SIZE_MBYTE) { DUMP(0, "MB");
+ } else if(flag & SIZE_GBYTE) { DUMP(0, "GB");
+ } else if(flag & SIZE_TBYTE) { DUMP(0, "TB");
+ }
+ cstr_len = strlen(cstr);
+ }
+ /* Remove last space */
+ if(cstr[cstr_len-1] == ' ') {
+ cstr[cstr_len-1] = '\0';
+ }
+ }
+ #undef NBYTES_PER_KBYTE
+ #undef NBYTES_PER_MBYTE
+ #undef NBYTES_PER_GBYTE
+ #undef NBYTES_PER_TBYTE
+ #undef DUMP
+}
diff --git a/src/cstr.h b/src/cstr.h
@@ -25,6 +25,15 @@
#include <limits.h>
#include <stdlib.h>
+enum size_unit {
+ SIZE_BYTE = BIT(0),
+ SIZE_KBYTE = BIT(1),
+ SIZE_MBYTE = BIT(2),
+ SIZE_GBYTE = BIT(3),
+ SIZE_TBYTE = BIT(4),
+ SIZE_ALL = -1
+};
+
static INLINE res_T
cstr_to_double(const char* str, double* dst)
{
@@ -188,6 +197,14 @@ cstr_to_list_uint
size_t* length,
const size_t max_length);
+RSYS_API void
+size_to_cstr
+ (const size_t size,
+ const int flag, /* Combination of size_unit */
+ size_t* real_cstr_len, /* May be NULL (does not handle null char) */
+ char* cstr, /* May be NULL */
+ const size_t sizeof_cstr); /* Include null char */
+
END_DECLS
#endif /* CSTR_H */
diff --git a/src/test_cstr.c b/src/test_cstr.c
@@ -343,6 +343,102 @@ test_res_to_cstr(void)
printf("%s\n", res_to_cstr(RES_EOF));
}
+static INLINE size_t
+size
+ (const size_t teras,
+ const size_t gigas,
+ const size_t megas,
+ const size_t kilos,
+ const size_t bytes)
+{
+ return (size_t)1024*((size_t)1024*((size_t)1024*((size_t)1024*
+ teras + gigas) + megas) + kilos) + bytes;
+}
+
+static void
+test_size_to_cstr(void)
+{
+ char dump[512];
+ size_t len;
+ size_t sz;
+ size_t dump_len;
+ char* tk = 0;
+
+ sz = size(2, 450, 987, 243, 42);
+
+ size_to_cstr(sz, SIZE_ALL, &len, NULL, 0);
+ CHK(len == 30);
+ size_to_cstr(sz, SIZE_ALL, NULL, dump, sizeof(dump));
+ printf("%s\n", dump);
+ dump_len = strlen(dump);
+ CHK(len == dump_len);
+
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "2"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "TB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "450"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "GB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "987"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "MB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "243"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "KB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "42"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "B"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ /* Check string truncation */
+ size_to_cstr(sz, SIZE_ALL, &len, dump, dump_len - 3 + 1/*null char*/);
+ CHK(len == 30);
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "2"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "TB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "450"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "GB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "987"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "MB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "243"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "KB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "4"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ size_to_cstr(sz, SIZE_GBYTE|SIZE_MBYTE, &len, dump, sizeof(dump));
+ CHK(len == strlen(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "2498"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "GB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "987"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "MB"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ size_to_cstr(sz, SIZE_GBYTE|SIZE_KBYTE|SIZE_BYTE, &len, dump, sizeof(dump));
+ CHK(len == strlen(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "2498"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "GB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "1010931"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "KB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "42"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "B"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ size_to_cstr(sz, 0, &len, dump, sizeof(dump));
+ CHK(len == 0 && dump[0] == '\0');
+
+ size_to_cstr(0, SIZE_ALL, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "0"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "B"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ size_to_cstr(0, SIZE_TBYTE, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "0"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "TB"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ sz = size(0, 3, 0, 17, 0);
+ size_to_cstr(sz, SIZE_ALL, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "3"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "GB"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "17"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "KB"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+}
+
int
main(int argc, char** argv)
{
@@ -358,5 +454,6 @@ main(int argc, char** argv)
test_list_float();
test_list_uint();
test_res_to_cstr();
+ test_size_to_cstr();
return 0;
}
diff --git a/src/test_time.c b/src/test_time.c
@@ -42,14 +42,14 @@ main(int argc, char** argv)
time_dump
(&res, TIME_SEC|TIME_MSEC|TIME_USEC, &dump_len, dump, sizeof(dump));
CHK(dump_len == strlen(dump));
- printf(">>> %s.\n", dump);
+ printf("%s\n", dump);
time_dump(&res, TIME_ALL, NULL, dump, sizeof(dump));
- printf(">>> %s.\n", dump);
+ printf("%s\n", dump);
CHK(time_add(&res, &res, &res) == &res);
CHK(time_val(&res, TIME_NSEC) == 2*time);
time_dump(&res, TIME_ALL, NULL, dump, sizeof(dump));
- printf(">>> %s.\n", dump);
+ printf("%s\n", dump);
time = time_val(&res, TIME_NSEC);
CHK(time_zero(&start) == &start);
@@ -64,19 +64,19 @@ main(int argc, char** argv)
CHK(time_sub(&res, &end, &end) == &res);
CHK(time_val(&res, TIME_NSEC) == 0);
time_dump(&res, TIME_ALL, NULL, dump, sizeof(dump));
- printf(">>> %s.\n", dump);
+ printf("%s\n", dump);
time_dump(&res, 0, NULL, dump, sizeof(dump));
- printf(">>> %s.\n", dump);
+ printf("%s\n", dump);
res.sec = 5;
res.nsec = 524198207;
time_dump(&res, TIME_ALL, &dump_len, buf, sizeof(buf));
CHK(dump_len >= strlen(buf));
- printf(">>> %s.\n", buf);
+ printf("%s\n", buf);
time_dump(&res, TIME_ALL, &dump_len, dump, sizeof(dump));
CHK(dump_len >= strlen(dump));
- printf(">>> %s.\n", dump);
+ printf("%s\n", dump);
return 0;
}