rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

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:
Msrc/cstr.c | 93++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/cstr.h | 17+++++++++++++++++
Msrc/test_cstr.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/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; }