commit ee9242b65847d58d08b93abb9ce4cd5e51413d78
parent bb949e4e15c4ecb5a0daae58ed067fb841a147c8
Author: vaplv <vaplv@free.fr>
Date: Mon, 22 Aug 2022 10:12:36 +0200
Merge branch 'develop' into feature_posix_make
Diffstat:
6 files changed, 304 insertions(+), 20 deletions(-)
diff --git a/src/clock_time.c b/src/clock_time.c
@@ -157,7 +157,7 @@ time_dump
ASSERT(time && (!max_dump_len || dump));
if(real_dump_len) *real_dump_len = 0;
- if(dump) dump[0] = '\0';
+ if(max_dump_len > 0) dump[0] = '\0';
if(!flag) return;
#define DUMP(Time, Suffix) \
@@ -216,7 +216,7 @@ time_dump
/* Remove last space */
if(real_dump_len) *real_dump_len -= 1;
- if(dump) {
+ if(max_dump_len > 0) {
size_t dump_len = strlen(dump);
if(!dump_len && flag) {
if(flag & TIME_NSEC) { DUMP(0, "nsec");
@@ -225,6 +225,7 @@ time_dump
} else if(flag & TIME_SEC) { DUMP(0, "sec");
} else if(flag & TIME_MIN) { DUMP(0, "min");
} else if(flag & TIME_HOUR) { DUMP(0, "hour");
+ } else if(flag & TIME_DAY) { DUMP(0, "day");
}
dump_len = strlen(dump);
}
diff --git a/src/clock_time.h b/src/clock_time.h
@@ -72,9 +72,9 @@ RSYS_API void
time_dump
(const struct time* time,
int flag, /* Combination of time_unit or TIME_ALL */
- size_t* real_dump_len, /* May be NULL */
+ size_t* real_dump_len, /* May be NULL (wo '\0') */
char* dump, /* May be NULL */
- size_t max_dump_len);
+ size_t max_dump_len); /* With '\0' */
END_DECLS
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
@@ -17,12 +17,36 @@
#include <stdlib.h>
#include <string.h>
+static struct time
+build_time
+ (const int64_t days,
+ const int64_t hours,
+ const int64_t mins,
+ const int64_t secs,
+ const int64_t msecs,
+ const int64_t usecs,
+ const int64_t nsecs)
+{
+ struct time t;
+
+ t.sec = days * 3600 * 24;
+ t.sec += hours * 3600;
+ t.sec += mins * 60;
+ t.sec += secs;
+
+ t.nsec = msecs * 1000000;
+ t.nsec += usecs * 1000;
+ t.nsec += nsecs;
+
+ return t;
+}
+
int
main(int argc, char** argv)
{
struct time start, end, res;
char dump[512];
- char buf[32];
+ char* tk;
int64_t time = 0;
int64_t i = 0;
size_t dump_len;
@@ -42,14 +66,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);
@@ -63,20 +87,74 @@ main(int argc, char** argv)
CHK(time_sub(&res, &end, &end) == &res);
CHK(time_val(&res, TIME_NSEC) == 0);
+
+ res = build_time(1, 10, 55, 30, 998, 763, 314);
+ dump[0] = '?';
+ time_dump(&res, TIME_ALL, &dump_len, dump, 0);
+ CHK(dump[0] = '?');
time_dump(&res, TIME_ALL, NULL, dump, sizeof(dump));
- printf(">>> %s.\n", dump);
- time_dump(&res, 0, NULL, dump, sizeof(dump));
- printf(">>> %s.\n", dump);
+ CHK(dump_len == strlen(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", dump);
- time_dump(&res, TIME_ALL, &dump_len, dump, sizeof(dump));
- CHK(dump_len >= strlen(dump));
- printf(">>> %s.\n", dump);
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "1"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "day"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "10"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "hours"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "55"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "mins"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "30"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "secs"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "998"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "msecs"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "763"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "usecs"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "314"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "nsecs"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+ /* Check string truncation */
+ time_dump(&res, TIME_ALL, NULL, dump, dump_len - 27 + 1/*null char*/);
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "1"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "day"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "10"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "hours"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "55"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "mins"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "30"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "secs"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "99"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ time_dump(&res, TIME_MIN|TIME_MSEC, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "2095"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "mins"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "30998"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "msecs"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ time_dump(&res, 0, &dump_len, dump, sizeof(dump));
+ CHK(dump_len == 0 && dump[0] == '\0');
+
+ res = build_time(0, 0, 0, 0, 0, 0, 0);
+ time_dump(&res, TIME_ALL, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "0"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "nsec"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ time_dump(&res, TIME_DAY, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "0"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "day"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
+
+ res = build_time(0, 0, 1, 0, 235, 10, 0);
+ time_dump(&res, TIME_ALL, NULL, dump, sizeof(dump));
+ CHK((tk = strtok(dump, " ")) && !strcmp(tk, "1"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "min"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "235"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "msecs"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "10"));
+ CHK((tk = strtok(NULL, " ")) && !strcmp(tk, "usecs"));
+ CHK((tk = strtok(NULL, " ")) == NULL);
return 0;
}