LCOV - code coverage report
Current view: top level - tests/src - test0032.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.0 % 210 189
Test Date: 2026-03-01 04:31:48 Functions: 100.0 % 9 9
Branches: 52.4 % 418 219

             Branch data     Line data    Source code
       1                 :             : #include "sute.h"
       2                 :             : 
       3                 :             : #include <float.h>
       4                 :             : 
       5                 :          11 : static void strip_commas(
       6                 :             :         const char *src,
       7                 :             :         char       *dst,
       8                 :             :         size_t      dst_size)
       9                 :             : {
      10   [ +  -  -  + ]:          11 :         if(dst == NULL || dst_size == 0U)
      11                 :             :         {
      12                 :           0 :                 return;
      13                 :             :         }
      14                 :             : 
      15         [ -  + ]:          11 :         if(src == NULL)
      16                 :             :         {
      17                 :           0 :                 dst[0] = '\0';
      18                 :           0 :                 return;
      19                 :             :         }
      20                 :             : 
      21                 :          11 :         size_t write = 0U;
      22         [ +  + ]:         166 :         for(size_t read = 0U; src[read] != '\0'; read++)
      23                 :             :         {
      24         [ +  + ]:         155 :                 if(src[read] == ',')
      25                 :             :                 {
      26                 :          28 :                         continue;
      27                 :             :                 }
      28                 :             : 
      29         [ -  + ]:         127 :                 if(write + 1U >= dst_size)
      30                 :             :                 {
      31                 :           0 :                         dst[0] = '\0';
      32                 :           0 :                         return;
      33                 :             :                 }
      34                 :             : 
      35                 :         127 :                 dst[write++] = src[read];
      36                 :             :         }
      37                 :             : 
      38                 :          11 :         dst[write] = '\0';
      39                 :             : }
      40                 :             : 
      41                 :           5 : static bool valid_comma_grouping(
      42                 :             :         const char *val)
      43                 :             : {
      44   [ +  -  -  + ]:           5 :         if(val == NULL || val[0] == '\0')
      45                 :             :         {
      46                 :           0 :                 return false;
      47                 :             :         }
      48                 :             : 
      49                 :           5 :         size_t start = 0U;
      50         [ +  + ]:           5 :         if(val[0] == '-')
      51                 :             :         {
      52                 :           2 :                 start = 1U;
      53                 :             :         }
      54                 :             : 
      55                 :           5 :         size_t len = strlen(val);
      56         [ -  + ]:           5 :         if(len <= start)
      57                 :             :         {
      58                 :           0 :                 return false;
      59                 :             :         }
      60                 :             : 
      61                 :           5 :         size_t digits_since_comma = 0U;
      62         [ +  + ]:          99 :         for(size_t i = len; i > start; i--)
      63                 :             :         {
      64                 :          94 :                 const char ch = val[i - 1U];
      65   [ +  +  +  - ]:          94 :                 if(ch >= '0' && ch <= '9')
      66                 :             :                 {
      67                 :          72 :                         digits_since_comma++;
      68                 :          72 :                         continue;
      69                 :             :                 }
      70                 :             : 
      71         [ +  - ]:          22 :                 if(ch == ',')
      72                 :             :                 {
      73         [ -  + ]:          22 :                         if(digits_since_comma != 3U)
      74                 :             :                         {
      75                 :           0 :                                 return false;
      76                 :             :                         }
      77                 :             : 
      78                 :          22 :                         digits_since_comma = 0U;
      79                 :          22 :                         continue;
      80                 :             :                 }
      81                 :             : 
      82                 :           0 :                 return false;
      83                 :             :         }
      84                 :             : 
      85   [ +  -  +  - ]:           5 :         return digits_since_comma >= 1U && digits_since_comma <= 3U;
      86                 :             : }
      87                 :             : 
      88                 :           4 : static bool form_intmax_matches_standard(
      89                 :             :         intmax_t    val,
      90                 :             :         const char *formatted)
      91                 :             : {
      92                 :             :         char expected[MAX_CHARACTERS];
      93                 :             :         char stripped[MAX_CHARACTERS];
      94                 :             : 
      95         [ -  + ]:           4 :         if(snprintf(expected,sizeof(expected),"%" PRIdMAX,val) < 0)
      96                 :             :         {
      97                 :           0 :                 return false;
      98                 :             :         }
      99                 :             : 
     100                 :           4 :         strip_commas(formatted,stripped,sizeof(stripped));
     101                 :             : 
     102   [ +  -  +  - ]:           4 :         return valid_comma_grouping(formatted) && (0 == strcmp(stripped,expected));
     103                 :             : }
     104                 :             : 
     105                 :           1 : static bool form_uintmax_matches_standard(
     106                 :             :         uintmax_t   val,
     107                 :             :         const char *formatted)
     108                 :             : {
     109                 :             :         char expected[MAX_CHARACTERS];
     110                 :             :         char stripped[MAX_CHARACTERS];
     111                 :             : 
     112         [ -  + ]:           1 :         if(snprintf(expected,sizeof(expected),"%" PRIuMAX,val) < 0)
     113                 :             :         {
     114                 :           0 :                 return false;
     115                 :             :         }
     116                 :             : 
     117                 :           1 :         strip_commas(formatted,stripped,sizeof(stripped));
     118                 :             : 
     119   [ +  -  +  - ]:           1 :         return valid_comma_grouping(formatted) && (0 == strcmp(stripped,expected));
     120                 :             : }
     121                 :             : 
     122                 :           6 : static bool valid_grouped_integer_part(
     123                 :             :         const char *val,
     124                 :             :         size_t     start,
     125                 :             :         size_t     end)
     126                 :             : {
     127   [ +  -  -  + ]:           6 :         if(val == NULL || end <= start)
     128                 :             :         {
     129                 :           0 :                 return false;
     130                 :             :         }
     131                 :             : 
     132                 :           6 :         size_t digits_since_comma = 0U;
     133         [ +  + ]:          42 :         for(size_t i = end; i > start; i--)
     134                 :             :         {
     135                 :          36 :                 const char ch = val[i - 1U];
     136   [ +  +  +  - ]:          36 :                 if(ch >= '0' && ch <= '9')
     137                 :             :                 {
     138                 :          30 :                         digits_since_comma++;
     139                 :          30 :                         continue;
     140                 :             :                 }
     141                 :             : 
     142         [ +  - ]:           6 :                 if(ch == ',')
     143                 :             :                 {
     144         [ -  + ]:           6 :                         if(digits_since_comma != 3U)
     145                 :             :                         {
     146                 :           0 :                                 return false;
     147                 :             :                         }
     148                 :             : 
     149                 :           6 :                         digits_since_comma = 0U;
     150                 :           6 :                         continue;
     151                 :             :                 }
     152                 :             : 
     153                 :           0 :                 return false;
     154                 :             :         }
     155                 :             : 
     156   [ +  -  +  - ]:           6 :         return digits_since_comma >= 1U && digits_since_comma <= 3U;
     157                 :             : }
     158                 :             : 
     159                 :           6 : static bool valid_grouped_real(
     160                 :             :         const char *val)
     161                 :             : {
     162   [ +  -  -  + ]:           6 :         if(val == NULL || val[0] == '\0')
     163                 :             :         {
     164                 :           0 :                 return false;
     165                 :             :         }
     166                 :             : 
     167                 :           6 :         size_t start = 0U;
     168         [ +  + ]:           6 :         if(val[0] == '-')
     169                 :             :         {
     170                 :           1 :                 start = 1U;
     171                 :             :         }
     172                 :             : 
     173         [ -  + ]:           6 :         if(val[start] == '\0')
     174                 :             :         {
     175                 :           0 :                 return false;
     176                 :             :         }
     177                 :             : 
     178                 :           6 :         const char *dot = strchr(val + start,'.');
     179                 :           6 :         const size_t total_len = strlen(val);
     180         [ +  + ]:           6 :         const size_t integer_end = dot == NULL ? total_len : (size_t)(dot - val);
     181                 :             : 
     182         [ -  + ]:           6 :         if(valid_grouped_integer_part(val,start,integer_end) == false)
     183                 :             :         {
     184                 :           0 :                 return false;
     185                 :             :         }
     186                 :             : 
     187         [ +  + ]:           6 :         if(dot == NULL)
     188                 :             :         {
     189                 :           3 :                 return true;
     190                 :             :         }
     191                 :             : 
     192                 :           3 :         const char *fraction = dot + 1U;
     193         [ -  + ]:           3 :         if(*fraction == '\0')
     194                 :             :         {
     195                 :           0 :                 return false;
     196                 :             :         }
     197                 :             : 
     198         [ +  + ]:          22 :         for(size_t i = 0U; fraction[i] != '\0'; i++)
     199                 :             :         {
     200   [ +  -  -  + ]:          19 :                 if(fraction[i] < '0' || fraction[i] > '9')
     201                 :             :                 {
     202                 :           0 :                         return false;
     203                 :             :                 }
     204                 :             :         }
     205                 :             : 
     206                 :           3 :         return fraction[strlen(fraction) - 1U] != '0';
     207                 :             : }
     208                 :             : 
     209                 :           6 : static bool form_real_matches_portable(
     210                 :             :         long double expected,
     211                 :             :         const char  *formatted)
     212                 :             : {
     213         [ -  + ]:           6 :         if(valid_grouped_real(formatted) == false)
     214                 :             :         {
     215                 :           0 :                 return false;
     216                 :             :         }
     217                 :             : 
     218                 :             :         char stripped[MAX_CHARACTERS];
     219                 :           6 :         strip_commas(formatted,stripped,sizeof(stripped));
     220                 :             : 
     221                 :           6 :         errno = 0;
     222                 :           6 :         char *end = NULL;
     223                 :           6 :         const long double parsed = strtold(stripped,&end);
     224   [ +  -  +  -  :           6 :         if(errno != 0 || end == stripped || *end != '\0')
                   -  + ]
     225                 :             :         {
     226                 :           0 :                 return false;
     227                 :             :         }
     228                 :             : 
     229                 :           6 :         long double tolerance = fabsl(expected) * LDBL_EPSILON * 4.0L;
     230         [ +  + ]:           6 :         if(tolerance < 0.000000001L)
     231                 :             :         {
     232                 :           5 :                 tolerance = 0.000000001L;
     233                 :             :         }
     234                 :           6 :         return fabsl(parsed - expected) <= tolerance;
     235                 :             : }
     236                 :             : 
     237                 :           1 : static Return test0032_1(void)
     238                 :             : {
     239                 :           1 :         INITTEST;
     240                 :             : 
     241                 :             :         // Shared destination for most formatter calls in this test.
     242                 :             :         // We pass this buffer into form()/form_*_r() and compare the produced text.
     243                 :             :         char formatted[MAX_CHARACTERS];
     244                 :             :         // Separate destinations to verify independent writes between two calls.
     245                 :             :         char first[FORM_OUTPUT_BUFFER_SIZE];
     246                 :             :         char second[FORM_OUTPUT_BUFFER_SIZE];
     247                 :             : 
     248                 :             :         // Intentionally tiny buffers prefilled with sentinels.
     249                 :             :         // They are used to validate truncation and NUL-termination behavior.
     250                 :           1 :         char tiny_real_1[1] = {'X'};
     251                 :           1 :         char tiny_real_2[2] = {'X','Y'};
     252                 :           1 :         char tiny_real_2_nonzero[2] = {'X','Y'};
     253                 :           1 :         char tiny_real_group_fail[5] = {'X','X','X','X','X'};
     254                 :           1 :         char tiny_real_group_ok[6] = {'X','X','X','X','X','X'};
     255                 :           1 :         char tiny_real_frac_fail[7] = {'X','X','X','X','X','X','X'};
     256                 :           1 :         char tiny_real_frac_ok[8] = {'X','X','X','X','X','X','X','X'};
     257                 :           1 :         char tiny_uint_1[1] = {'X'};
     258                 :           1 :         char tiny_uint_2[2] = {'X','Y'};
     259                 :           1 :         char tiny_uint_3[3] = {'X','Y','Z'};
     260                 :           1 :         char tiny_uint_7[7] = {'X','Y','Z','Q','W','E','R'};
     261                 :             :         char bkb_r_a[MAX_CHARACTERS];
     262                 :             :         char bkb_r_b[MAX_CHARACTERS];
     263                 :           1 :         char bkb_r_tiny_1[1] = {'X'};
     264                 :           1 :         char bkb_r_tiny_2[2] = {'X','Y'};
     265                 :           1 :         char bkb_r_tiny_3[3] = {'X','Y','Z'};
     266                 :           1 :         char bkb_r_tiny_6[6] = {'X','X','X','X','X','X'};
     267                 :           1 :         char bkb_r_tiny_9[9] = {'X','X','X','X','X','X','X','X','X'};
     268                 :           1 :         char bkb_r_tiny_10[10] = {'X','X','X','X','X','X','X','X','X','X'};
     269                 :             :         char date_r_a[MAX_CHARACTERS];
     270                 :           1 :         char date_r_tiny_1[1] = {'X'};
     271                 :           1 :         char date_r_tiny_2[2] = {'X','Y'};
     272                 :           1 :         char date_r_tiny_3[3] = {'X','Y','Z'};
     273                 :             : 
     274                 :             :         // Series 1: generic form() formatting into caller-provided buffer `formatted`.
     275                 :             :         // Pattern: call form(value,formatted,sizeof(formatted)), then compare with exact text.
     276   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(0.0L,formatted,sizeof(formatted)),"0"));
     277                 :             :         // Same path, near-zero negative rounds to textual zero.
     278   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(-0.0000000004L,formatted,sizeof(formatted)),"0"));
     279                 :             :         // Same path, rounding at 9th decimal place.
     280   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(0.0000000006L,formatted,sizeof(formatted)),"0.000000001"));
     281                 :             :         // Same behavior for negative rounding.
     282   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(-0.0000000006L,formatted,sizeof(formatted)),"-0.000000001"));
     283                 :             :         // Grouping separators in integer part.
     284   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(1234567.0L,formatted,sizeof(formatted)),"1,234,567"));
     285   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(1234567890123456.0L,formatted,sizeof(formatted)),"1,234,567,890,123,456"));
     286   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(1234567.125L,formatted,sizeof(formatted)),"1,234,567.125"));
     287   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form(-9876.5L,formatted,sizeof(formatted)),"-9,876.5"));
     288                 :             :         // For long double cases, compare parsed numeric value with tolerance.
     289                 :             :         // The formatted string still comes from the same `formatted` buffer.
     290   [ +  -  +  - ]:           1 :         ASSERT(form_real_matches_portable(123456789.123456780L,form(123456789.123456780L,formatted,sizeof(formatted))));
     291   [ +  -  +  - ]:           1 :         ASSERT(form_real_matches_portable(987654321098.123456789L,form(987654321098.123456789L,formatted,sizeof(formatted))));
     292   [ +  -  +  - ]:           1 :         ASSERT(form_real_matches_portable(1.23L,form(1.23L,formatted,sizeof(formatted))));
     293   [ +  -  +  - ]:           1 :         ASSERT(form_real_matches_portable(9.9999999995L,form(9.9999999995L,formatted,sizeof(formatted))));
     294   [ +  -  +  - ]:           1 :         ASSERT(form_real_matches_portable(-9.9999999995L,form(-9.9999999995L,formatted,sizeof(formatted))));
     295   [ +  -  +  - ]:           1 :         ASSERT(form_real_matches_portable(999.9999999995L,form(999.9999999995L,formatted,sizeof(formatted))));
     296                 :             : 
     297                 :             :         // Series 2: boolean/integer overloads still write to `formatted`.
     298   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form((_Bool)0,formatted,sizeof(formatted)),"0"));
     299   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form((_Bool)1,formatted,sizeof(formatted)),"1"));
     300   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form((int)-12345,formatted,sizeof(formatted)),"-12,345"));
     301   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form((short)-12345,formatted,sizeof(formatted)),"-12,345"));
     302                 :             : 
     303                 :             :         // Series 3: form_intmax_r writes to `formatted`, then helper validates comma placement
     304                 :             :         // and numeric equivalence against standard conversion for the same input value.
     305                 :           1 :         const char *intmin_formatted = form_intmax_r(INTMAX_MIN,formatted,sizeof(formatted));
     306   [ +  -  +  - ]:           1 :         ASSERT(form_intmax_matches_standard(INTMAX_MIN,intmin_formatted));
     307                 :             :         // Same comparison strategy for other intmax values.
     308                 :           1 :         const char *intmax_formatted = form_intmax_r(INTMAX_MAX,formatted,sizeof(formatted));
     309   [ +  -  +  - ]:           1 :         ASSERT(form_intmax_matches_standard(INTMAX_MAX,intmax_formatted));
     310                 :           1 :         const char *intneg_formatted = form_intmax_r(-1234567,formatted,sizeof(formatted));
     311   [ +  -  +  - ]:           1 :         ASSERT(form_intmax_matches_standard(-1234567,intneg_formatted));
     312                 :           1 :         const char *intpos_formatted = form_intmax_r(1234567,formatted,sizeof(formatted));
     313   [ +  -  +  - ]:           1 :         ASSERT(form_intmax_matches_standard(1234567,intpos_formatted));
     314                 :             : 
     315                 :             :         // Same idea for unsigned max conversion.
     316                 :           1 :         const char *uintmax_formatted = form_uintmax_r(UINTMAX_MAX,formatted,sizeof(formatted));
     317   [ +  -  +  - ]:           1 :         ASSERT(form_uintmax_matches_standard(UINTMAX_MAX,uintmax_formatted));
     318                 :             : 
     319                 :             :         // Series 4: independent output buffers (`first`, `second`) for two calls.
     320                 :             :         // Then ensure `first` keeps its value after writing into `second`.
     321   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form((size_t)1234,first,sizeof(first)),"1,234"));
     322   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form((size_t)5678,second,sizeof(second)),"5,678"));
     323   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(first,"1,234"));
     324                 :             : 
     325                 :             :         // Series 5: tiny-buffer behavior for form_real_r.
     326                 :             :         // Buffer too small => empty string.
     327                 :           1 :         (void)form_real_r(1234.5L,tiny_real_1,sizeof(tiny_real_1));
     328   [ +  -  +  - ]:           1 :         ASSERT(tiny_real_1[0] == '\0');
     329                 :             :         // Still using tiny destinations, now checking reduced output variants.
     330   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(1.25L,tiny_real_2_nonzero,sizeof(tiny_real_2_nonzero)),"1"));
     331   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(0.0L,tiny_real_2,sizeof(tiny_real_2)),"0"));
     332                 :           1 :         (void)form_real_r(1234.0L,tiny_real_group_fail,sizeof(tiny_real_group_fail));
     333   [ +  -  +  - ]:           1 :         ASSERT(tiny_real_group_fail[0] == '\0');
     334   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(1234.0L,tiny_real_group_ok,sizeof(tiny_real_group_ok)),"1,234"));
     335   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(1234.5L,tiny_real_frac_fail,sizeof(tiny_real_frac_fail)),"1,235"));
     336   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(1234.5L,tiny_real_frac_ok,sizeof(tiny_real_frac_ok)),"1,234.5"));
     337   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(NAN,formatted,sizeof(formatted)),""));
     338   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(INFINITY,formatted,sizeof(formatted)),""));
     339   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_real_r(-INFINITY,formatted,sizeof(formatted)),""));
     340                 :             : 
     341                 :             :         // Series 6: tiny-buffer behavior for form_uintmax_r (same pattern).
     342                 :           1 :         (void)form_uintmax_r(UINTMAX_MAX,tiny_uint_1,sizeof(tiny_uint_1));
     343   [ +  -  +  - ]:           1 :         ASSERT(tiny_uint_1[0] == '\0');
     344   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_uintmax_r(12345U,tiny_uint_2,sizeof(tiny_uint_2)),""));
     345   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_uintmax_r(12345U,tiny_uint_3,sizeof(tiny_uint_3)),""));
     346   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_uintmax_r(12345U,tiny_uint_7,sizeof(tiny_uint_7)),"12,345"));
     347                 :             : 
     348                 :             :         // Series 7: bkbmbgbtbpbeb returns static text; compare FULL_VIEW outputs directly.
     349   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb(0,FULL_VIEW),"0B"));
     350   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb(1024,FULL_VIEW),"1KiB"));
     351   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb(1536,FULL_VIEW),"1KiB 512B"));
     352                 :             : 
     353                 :             :         // Same for MAJOR_VIEW (only the largest non-zero unit).
     354   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb(0,MAJOR_VIEW),"0B"));
     355   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb(1536,MAJOR_VIEW),"1KiB"));
     356   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb(1291845632ULL,MAJOR_VIEW),"1GiB"));
     357                 :             : 
     358                 :             :         // Series 8: bkbmbgbtbpbeb_r writes into caller buffer (`bkb_r_a`), check invalid args first.
     359   [ +  -  +  - ]:           1 :         ASSERT(NULL == bkbmbgbtbpbeb_r(1U,FULL_VIEW,NULL,sizeof(bkb_r_a)));
     360   [ +  -  +  - ]:           1 :         ASSERT(NULL == bkbmbgbtbpbeb_r(1U,FULL_VIEW,bkb_r_a,0U));
     361                 :             : 
     362                 :             :         // Valid writes into the same destination buffer, then strcmp with expected literals.
     363   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(0U,FULL_VIEW,bkb_r_a,sizeof(bkb_r_a)),"0B"));
     364   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1024U,FULL_VIEW,bkb_r_a,sizeof(bkb_r_a)),"1KiB"));
     365   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1536U,FULL_VIEW,bkb_r_a,sizeof(bkb_r_a)),"1KiB 512B"));
     366   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1536U,MAJOR_VIEW,bkb_r_a,sizeof(bkb_r_a)),"1KiB"));
     367   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1291845632ULL,MAJOR_VIEW,bkb_r_a,sizeof(bkb_r_a)),"1GiB"));
     368                 :             : 
     369                 :             :         // Cross-buffer isolation check: writing into bkb_r_b must not modify bkb_r_a.
     370   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1024U,FULL_VIEW,bkb_r_a,sizeof(bkb_r_a)),"1KiB"));
     371   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(2048U,FULL_VIEW,bkb_r_b,sizeof(bkb_r_b)),"2KiB"));
     372   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkb_r_a,"1KiB"));
     373                 :             : 
     374                 :             :         // Tiny destination checks for bkbmbgbtbpbeb_r.
     375                 :           1 :         (void)bkbmbgbtbpbeb_r(1536U,FULL_VIEW,bkb_r_tiny_1,sizeof(bkb_r_tiny_1));
     376   [ +  -  +  - ]:           1 :         ASSERT('\0' == bkb_r_tiny_1[0]);
     377   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(0U,FULL_VIEW,bkb_r_tiny_2,sizeof(bkb_r_tiny_2)),"0"));
     378   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(0U,FULL_VIEW,bkb_r_tiny_3,sizeof(bkb_r_tiny_3)),"0B"));
     379   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1536U,FULL_VIEW,bkb_r_tiny_6,sizeof(bkb_r_tiny_6)),"1KiB"));
     380   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1536U,FULL_VIEW,bkb_r_tiny_9,sizeof(bkb_r_tiny_9)),"1KiB 512"));
     381   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(bkbmbgbtbpbeb_r(1536U,FULL_VIEW,bkb_r_tiny_10,sizeof(bkb_r_tiny_10)),"1KiB 512B"));
     382                 :             : 
     383                 :             :         // Series 9: form_date (static output) in FULL_VIEW and MAJOR_VIEW.
     384   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date(0LL,FULL_VIEW),"0ns"));
     385   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date(0LL,MAJOR_VIEW),"0ns"));
     386   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date(273000528LL,FULL_VIEW),"273ms 528ns"));
     387   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date(273000528LL,MAJOR_VIEW),"273ms"));
     388   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date(3600000000001LL,FULL_VIEW),"1h 1ns"));
     389   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date(3600000000001LL,MAJOR_VIEW),"1h"));
     390                 :             : 
     391                 :             :         // form_date_r with explicit destination buffer and invalid-argument checks.
     392   [ +  -  +  - ]:           1 :         ASSERT(NULL == form_date_r(1LL,FULL_VIEW,NULL,sizeof(date_r_a)));
     393   [ +  -  +  - ]:           1 :         ASSERT(NULL == form_date_r(1LL,FULL_VIEW,date_r_a,0U));
     394                 :             :         // Then normal writes and compact-buffer edge cases.
     395   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date_r(273000528LL,FULL_VIEW,date_r_a,sizeof(date_r_a)),"273ms 528ns"));
     396   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date_r(273000528LL,MAJOR_VIEW,date_r_a,sizeof(date_r_a)),"273ms"));
     397                 :           1 :         (void)form_date_r(273000528LL,FULL_VIEW,date_r_tiny_1,sizeof(date_r_tiny_1));
     398   [ +  -  +  - ]:           1 :         ASSERT('\0' == date_r_tiny_1[0]);
     399   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date_r(0LL,FULL_VIEW,date_r_tiny_2,sizeof(date_r_tiny_2)),"0"));
     400   [ +  -  +  - ]:           1 :         ASSERT(0 == strcmp(form_date_r(0LL,FULL_VIEW,date_r_tiny_3,sizeof(date_r_tiny_3)),"0n"));
     401                 :             : 
     402   [ +  -  -  +  :           1 :         RETURN_STATUS;
          -  -  -  +  +  
                      - ]
     403                 :             : }
     404                 :             : 
     405                 :           1 : Return test0032(void)
     406                 :             : {
     407                 :           1 :         INITTEST;
     408                 :             : 
     409         [ +  - ]:           1 :         TEST(test0032_1,"rational formatting helpers…");
     410                 :             : 
     411   [ +  -  -  +  :           1 :         RETURN_STATUS;
          -  -  -  +  +  
                      - ]
     412                 :             : }
        

Generated by: LCOV version 2.0-1