LCOV - code coverage report
Current view: top level - libs/mem/tests/src - test_libmem_0070.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 78 78
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 2 2
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : #include "test_libmem_all.h"
       2                 :             : #include <wchar.h>
       3                 :             : 
       4                 :             : /**
       5                 :             :  * @brief Capture noisy typed formatted-string frame-error cases
       6                 :             :  *
       7                 :             :  * These cases intentionally exercise report() paths. match_function_output()
       8                 :             :  * keeps the expected diagnostics out of the common test output
       9                 :             :  *
      10                 :             :  * @return Return describing success or failure
      11                 :             :  */
      12                 :           1 : static Return capture_libmem_formatted_string_frame_errors(void)
      13                 :             : {
      14                 :           1 :         INITTEST;
      15                 :             : 
      16                 :             :         /* Frame error: a data-mode destination is rejected by the narrow formatter */
      17                 :             :         {
      18                 :           1 :                 m_create(char,not_a_string);
      19                 :           1 :                 ASSERT(not_a_string->is_string == false);
      20                 :           1 :                 ASSERT(FAILURE == m_formatted_string(not_a_string,"anything"));
      21                 :           1 :                 ASSERT(not_a_string->is_string == false);
      22                 :           1 :                 call(m_del(not_a_string));
      23                 :             :         }
      24                 :             : 
      25                 :             :         /* Frame error: a narrow format may only write a char descriptor.
      26                 :             :            uint16_t remains unsupported even when it is a string descriptor */
      27                 :             :         {
      28                 :           1 :                 m_create(uint16_t,unsupported_width,MEMORY_STRING);
      29                 :           1 :                 ASSERT(unsupported_width->is_string == true);
      30                 :           1 :                 ASSERT(unsupported_width->single_element_size == sizeof(uint16_t));
      31                 :           1 :                 ASSERT(unsupported_width->single_element_size != sizeof(char));
      32                 :           1 :                 ASSERT(FAILURE == m_formatted_string(unsupported_width,"anything"));
      33                 :           1 :                 call(m_del(unsupported_width));
      34                 :             :         }
      35                 :             : 
      36                 :             :         /* Frame error: macro dispatch follows the format type, so a narrow
      37                 :             :            format cannot silently write into a wide-character descriptor */
      38                 :             :         {
      39                 :           1 :                 m_create(wchar_t,wrong_format_width,MEMORY_STRING);
      40                 :           1 :                 ASSERT(wrong_format_width->single_element_size == sizeof(wchar_t));
      41                 :           1 :                 ASSERT(FAILURE == m_formatted_string(wrong_format_width,"anything"));
      42                 :           1 :                 call(m_del(wrong_format_width));
      43                 :             :         }
      44                 :             : 
      45                 :             :         /* Frame error: a typed NULL narrow format is not a formatting request,
      46                 :             :            and rejecting it must leave already rendered text untouched */
      47                 :             :         {
      48                 :           1 :                 m_create(char,null_narrow_format,MEMORY_STRING);
      49                 :             : 
      50                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(null_narrow_format,"seed"));
      51                 :             :                 /* Use a typed NULL pointer so the public macro selects the narrow
      52                 :             :                    formatter and the runtime contract is exercised */
      53                 :           1 :                 ASSERT(FAILURE == m_formatted_string(null_narrow_format,(const char *)NULL));
      54                 :           1 :                 ASSERT(strcmp(m_text(null_narrow_format),"seed") == 0);
      55                 :           1 :                 ASSERT(null_narrow_format->string_length == strlen("seed"));
      56                 :           1 :                 call(m_del(null_narrow_format));
      57                 :             :         }
      58                 :             : 
      59                 :             :         /* Frame error: the wide formatter rejects a typed NULL format by the
      60                 :             :            same public contract and also preserves the existing text */
      61                 :             :         {
      62                 :           1 :                 m_create(wchar_t,null_wide_format,MEMORY_STRING);
      63                 :           1 :                 const wchar_t *null_format = NULL;
      64                 :             : 
      65                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(null_wide_format,L"seed"));
      66                 :           1 :                 ASSERT(FAILURE == m_formatted_string(null_wide_format,null_format));
      67                 :           1 :                 ASSERT(wcscmp((const wchar_t *)null_wide_format->data,L"seed") == 0);
      68                 :           1 :                 ASSERT(null_wide_format->string_length == wcslen(L"seed"));
      69                 :           1 :                 call(m_del(null_wide_format));
      70                 :             :         }
      71                 :             : 
      72                 :           1 :         deliver(status);
      73                 :             : }
      74                 :             : 
      75                 :             : /**
      76                 :             :  * @brief Verify typed formatted-string dispatch for char and wchar_t descriptors
      77                 :             :  * @details Exercises the public m_formatted_string macro for both supported
      78                 :             :  *          element widths. The
      79                 :             :  *          coverage includes:
      80                 :             :  *           - byte (char) destinations: basic formatting with mixed
      81                 :             :  *             conversions, replacement of an existing payload with both
      82                 :             :  *             shorter and longer rendered text, an empty rendered result
      83                 :             :  *             that keeps the descriptor in string mode, and direct use of
      84                 :             :  *             the narrow typed helper
      85                 :             :  *           - wide (wchar_t) destinations: basic formatting plus a long
      86                 :             :  *             format that intentionally exceeds the iterative-growth
      87                 :             :  *             starting capacity so the doubling loop in the wide path is
      88                 :             :  *             actually exercised
      89                 :             :  *           - frame-error rejections: non-string destination, mismatched
      90                 :             :  *             descriptor width, and typed NULL narrow and wide formats
      91                 :             :  *
      92                 :             :  * @return Return enum indicating success or failure of the test
      93                 :             :  * @retval SUCCESS if test passed
      94                 :             :  * @retval FAILURE if test failed
      95                 :             :  */
      96                 :           1 : Return test_libmem_0070(void)
      97                 :             : {
      98                 :           1 :         INITTEST;
      99                 :             : 
     100                 :             :         /* 1. Byte: basic format with mixed conversions writes the expected text */
     101                 :             :         {
     102                 :           1 :                 m_create(char,byte_basic,MEMORY_STRING);
     103                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(byte_basic,"Hello %s %d!","world",42));
     104                 :           1 :                 ASSERT(byte_basic->is_string == true);
     105                 :           1 :                 ASSERT(byte_basic->single_element_size == sizeof(char));
     106                 :           1 :                 ASSERT(byte_basic->string_length == strlen("Hello world 42!"));
     107                 :           1 :                 ASSERT(strcmp(m_text(byte_basic),"Hello world 42!") == 0);
     108                 :           1 :                 call(m_del(byte_basic));
     109                 :             :         }
     110                 :             : 
     111                 :             :         /* 2. Byte: each call fully replaces the previous content (longer then shorter) */
     112                 :             :         {
     113                 :           1 :                 m_create(char,byte_replace,MEMORY_STRING);
     114                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(byte_replace,"first"));
     115                 :           1 :                 ASSERT(strcmp(m_text(byte_replace),"first") == 0);
     116                 :             : 
     117                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(byte_replace,"second %d goes here",100));
     118                 :           1 :                 ASSERT(strcmp(m_text(byte_replace),"second 100 goes here") == 0);
     119                 :           1 :                 ASSERT(byte_replace->string_length == strlen("second 100 goes here"));
     120                 :             : 
     121                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(byte_replace,"x"));
     122                 :           1 :                 ASSERT(strcmp(m_text(byte_replace),"x") == 0);
     123                 :           1 :                 ASSERT(byte_replace->string_length == 1U);
     124                 :             : 
     125                 :           1 :                 call(m_del(byte_replace));
     126                 :             :         }
     127                 :             : 
     128                 :             :         /* 3. Byte: an empty rendered result still leaves a valid empty string */
     129                 :             :         {
     130                 :           1 :                 m_create(char,byte_empty,MEMORY_STRING);
     131                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(byte_empty,"%s",""));
     132                 :           1 :                 ASSERT(byte_empty->is_string == true);
     133                 :           1 :                 ASSERT(byte_empty->string_length == 0U);
     134                 :           1 :                 ASSERT(m_text(byte_empty)[0] == '\0');
     135                 :           1 :                 call(m_del(byte_empty));
     136                 :             :         }
     137                 :             : 
     138                 :             :         /* 4. Byte: another narrow formatted call exposes the same public contract */
     139                 :             :         {
     140                 :           1 :                 m_create(char,byte_direct,MEMORY_STRING);
     141                 :             : 
     142                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(byte_direct,"%s-%u","item",3U));
     143                 :           1 :                 ASSERT(strcmp(m_text(byte_direct),"item-3") == 0);
     144                 :           1 :                 ASSERT(byte_direct->string_length == strlen("item-3"));
     145                 :             : 
     146                 :           1 :                 call(m_del(byte_direct));
     147                 :             :         }
     148                 :             : 
     149                 :             :         /* 5. Wide: basic format with mixed conversions writes the expected wide text */
     150                 :             :         {
     151                 :           1 :                 m_create(wchar_t,wide_basic,MEMORY_STRING);
     152                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(wide_basic,L"Wide %ls %d",L"text",7));
     153                 :           1 :                 ASSERT(wide_basic->is_string == true);
     154                 :           1 :                 ASSERT(wide_basic->single_element_size == sizeof(wchar_t));
     155                 :           1 :                 ASSERT(wide_basic->string_length == wcslen(L"Wide text 7"));
     156                 :           1 :                 ASSERT(wcscmp((const wchar_t *)wide_basic->data,L"Wide text 7") == 0);
     157                 :           1 :                 call(m_del(wide_basic));
     158                 :             :         }
     159                 :             : 
     160                 :             :         /* 6. Wide: long format exercises the iterative-growth path past the
     161                 :             :            initial 128-element capacity guess inside the wide branch */
     162                 :             :         {
     163                 :           1 :                 m_create(wchar_t,wide_long,MEMORY_STRING);
     164                 :             : 
     165                 :             :                 /* This source is intentionally longer than 128 wchar_t elements so the
     166                 :             :                    initial speculative render fails and the doubling loop runs */
     167                 :           1 :                 const wchar_t *long_source =
     168                 :             :                         L"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
     169                 :             :                         L"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
     170                 :             :                         L"Ut enim ad minim veniam, quis nostrud exercitation ullamco.";
     171                 :             : 
     172                 :           1 :                 ASSERT(wcslen(long_source) > 128U);
     173                 :           1 :                 ASSERT(SUCCESS == m_formatted_string(wide_long,L"%ls",long_source));
     174                 :           1 :                 ASSERT(wide_long->is_string == true);
     175                 :           1 :                 ASSERT(wide_long->string_length == wcslen(long_source));
     176                 :           1 :                 ASSERT(wcscmp((const wchar_t *)wide_long->data,long_source) == 0);
     177                 :           1 :                 call(m_del(wide_long));
     178                 :             :         }
     179                 :             : 
     180                 :             :         /* Expected stderr layout for frame errors rejected by typed formatters.
     181                 :             :            Source line numbers and errno wording are intentionally flexible because
     182                 :             :            they are build- and platform-dependent */
     183                 :             :         static const char expected_stderr_pattern_libmem_0070[] =
     184                 :             :                 "\\A"
     185                 :             :                 "ERROR: src/mem_formatted_string\\.c:mem_formatted_string_char:\\d+ Memory management; Destination must be a string descriptor Errno: [^\\n]+ \\(errno: [0-9]+\\)\n"
     186                 :             :                 "ERROR: src/mem_formatted_string\\.c:mem_formatted_string_char:\\d+ Memory management; Narrow formatted destination requires char elements Errno: [^\\n]+ \\(errno: [0-9]+\\)\n"
     187                 :             :                 "ERROR: src/mem_formatted_string\\.c:mem_formatted_string_char:\\d+ Memory management; Narrow formatted destination requires char elements Errno: [^\\n]+ \\(errno: [0-9]+\\)\n"
     188                 :             :                 "ERROR: src/mem_formatted_string\\.c:mem_formatted_string_char:\\d+ Memory management; Format string must be non-NULL Errno: [^\\n]+ \\(errno: [0-9]+\\)\n"
     189                 :             :                 "ERROR: src/mem_formatted_string\\.c:mem_formatted_string_wchar:\\d+ Memory management; Format string must be non-NULL Errno: [^\\n]+ \\(errno: [0-9]+\\)\n"
     190                 :             :                 "\\Z";
     191                 :             : 
     192                 :           1 :         ASSERT(SUCCESS == match_function_output(NULL,expected_stderr_pattern_libmem_0070,capture_libmem_formatted_string_frame_errors));
     193                 :             : 
     194                 :           1 :         RETURN_STATUS;
     195                 :             : }
        

Generated by: LCOV version 2.0-1