LCOV - code coverage report
Current view: top level - libs/xdiff/src - compare_strings.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.8 % 99 82
Test Date: 2026-01-12 05:34:38 Functions: 100.0 % 4 4

            Line data    Source code
       1              : #include "xdiff.h"
       2              : 
       3              : /**
       4              :  * @brief Structure for storing output buffer
       5              :  */
       6              : typedef struct {
       7              :         char *buffer;   /**< Pointer to data buffer */
       8              :         size_t size;    /**< Current size of data in buffer */
       9              :         size_t capacity;        /**< Total buffer capacity */
      10              : } output_buffer_t;
      11              : 
      12              : /**
      13              :  * @brief Initializes output buffer for storing comparison results
      14              :  *
      15              :  * @return output_buffer_t* Pointer to created buffer or NULL on error
      16              :  */
      17            8 : static output_buffer_t *init_output_buffer(void)
      18              : {
      19            8 :         Return status = SUCCESS;
      20            8 :         output_buffer_t *buf = NULL;
      21              : 
      22              :         /* Allocate memory for buffer structure */
      23            8 :         buf = (output_buffer_t *)malloc(sizeof(output_buffer_t));
      24              : 
      25            8 :         if(NULL == buf)
      26              :         {
      27            0 :                 status = FAILURE;
      28              :         }
      29              : 
      30            8 :         if(SUCCESS == status)
      31              :         {
      32              :                 /* Set initial size */
      33            8 :                 buf->capacity = 1024;
      34            8 :                 buf->buffer = (char *)malloc(buf->capacity);
      35              : 
      36            8 :                 if(NULL == buf->buffer)
      37              :                 {
      38            0 :                         free(buf);
      39            0 :                         buf = NULL;
      40            0 :                         status = FAILURE;
      41              :                 }
      42              :         }
      43              : 
      44            8 :         if(SUCCESS == status)
      45              :         {
      46            8 :                 buf->size = 0;
      47            8 :                 buf->buffer[0] = '\0';
      48              :         }
      49              : 
      50            8 :         return buf;
      51              : }
      52              : 
      53              : /**
      54              :  * @brief Appends data to output buffer
      55              :  *
      56              :  * @param priv Pointer to buffer (output_buffer_t*)
      57              :  * @param mb Array of buffers with data
      58              :  * @param nbuf Number of buffers
      59              :  * @return Return Operation status
      60              :  */
      61          114 : static int append_to_buffer(
      62              :         void       *priv,
      63              :         mmbuffer_t *mb,
      64              :         int        nbuf)
      65              : {
      66          114 :         int status = SUCCESS;
      67          114 :         output_buffer_t *buf = (output_buffer_t *)priv;
      68          114 :         size_t total_size = 0;
      69          114 :         size_t new_capacity = 0;
      70          114 :         char *new_buffer = NULL;
      71              : 
      72              :         /* Check input parameters */
      73          114 :         if(NULL == buf || NULL == mb)
      74              :         {
      75            0 :                 return(1);
      76              :         }
      77              : 
      78              :         /* Calculate total size to append */
      79          114 :         if(SUCCESS == status)
      80              :         {
      81          342 :                 for(int i = 0; i < nbuf; i++)
      82              :                 {
      83          228 :                         total_size += mb[i].size;
      84              :                 }
      85              :         }
      86              : 
      87              :         /* Check if buffer needs to be enlarged */
      88          114 :         if(SUCCESS == status)
      89              :         {
      90          114 :                 if(buf->size + total_size + 1 > buf->capacity)
      91              :                 {
      92            4 :                         new_capacity = buf->capacity;
      93              : 
      94            8 :                         while(new_capacity < buf->size + total_size + 1)
      95              :                         {
      96            4 :                                 new_capacity *= 2;
      97              :                         }
      98              : 
      99            4 :                         new_buffer = (char *)realloc(buf->buffer,new_capacity);
     100              : 
     101            4 :                         if(NULL == new_buffer)
     102              :                         {
     103            0 :                                 status = FAILURE;
     104              :                         } else {
     105            4 :                                 buf->buffer = new_buffer;
     106            4 :                                 buf->capacity = new_capacity;
     107              :                         }
     108              :                 }
     109              :         }
     110              : 
     111              :         /* Copy data */
     112          114 :         if(SUCCESS == status)
     113              :         {
     114          342 :                 for(int i = 0; i < nbuf; i++)
     115              :                 {
     116          228 :                         memcpy(buf->buffer + buf->size,mb[i].ptr,mb[i].size);
     117          228 :                         buf->size += mb[i].size;
     118              :                 }
     119          114 :                 buf->buffer[buf->size] = '\0';
     120              :         }
     121              : 
     122          114 :         return(status);
     123              : }
     124              : 
     125              : /**
     126              :  * @brief Creates mmfile from string
     127              :  *
     128              :  * @param mmf Pointer to mmfile_t structure to fill
     129              :  * @param content Source string
     130              :  * @return Return Operation status
     131              :  */
     132           16 : static Return create_mmfile(
     133              :         mmfile_t   *mmf,
     134              :         const char *content)
     135              : {
     136           16 :         Return status = SUCCESS;
     137           16 :         size_t size = 0;
     138           16 :         void *data = NULL;
     139              : 
     140           16 :         if(NULL == mmf || NULL == content)
     141              :         {
     142            0 :                 return(FAILURE);
     143              :         }
     144              : 
     145           16 :         size = strlen(content);
     146              : 
     147              :         /* Initialize mmfile */
     148           16 :         if(SUCCESS == status)
     149              :         {
     150           16 :                 if(xdl_init_mmfile(mmf,size + 1,XDL_MMF_ATOMIC) < 0)
     151              :                 {
     152            0 :                         status = FAILURE;
     153              :                 }
     154              :         }
     155              : 
     156              :         /* Allocate memory and copy data */
     157           16 :         if(SUCCESS == status)
     158              :         {
     159           16 :                 data = xdl_mmfile_writeallocate(mmf,size);
     160              : 
     161           16 :                 if(NULL == data)
     162              :                 {
     163            0 :                         xdl_free_mmfile(mmf);
     164            0 :                         status = FAILURE;
     165              :                 }
     166              :         }
     167              : 
     168           16 :         if(SUCCESS == status)
     169              :         {
     170           16 :                 memcpy(data,content,size);
     171              :         }
     172              : 
     173           16 :         if(SUCCESS != status)
     174              :         {
     175            0 :                 serp("Failed to create mmfile");
     176              :         }
     177              : 
     178           16 :         return(status);
     179              : }
     180              : 
     181              : /**
     182              :  * @brief Compares two strings and generates diff in unified format
     183              :  *
     184              :  * @param[out] diff Pointer to string with comparison result
     185              :  * @param[in] string1 First string to compare
     186              :  * @param[in] string2 Second string to compare
     187              :  * @return Return Operation status
     188              :  */
     189            8 : Return compare_strings(
     190              :         char       **diff,
     191              :         const char *string1,
     192              :         const char *string2)
     193              : {
     194            8 :         Return status = SUCCESS;
     195              :         mmfile_t mf1,mf2;
     196              :         xpparam_t xpp;
     197              :         xdemitconf_t xecfg;
     198              :         xdemitcb_t ecb;
     199            8 :         output_buffer_t *output = NULL;
     200              : 
     201              :         /* Validate input parameters */
     202            8 :         if(NULL == diff || NULL == string1 || NULL == string2)
     203              :         {
     204            0 :                 return(FAILURE);
     205              :         }
     206              : 
     207              :         /* Create output buffer */
     208            8 :         output = init_output_buffer();
     209              : 
     210            8 :         if(NULL == output || output->buffer == NULL)
     211              :         {
     212            0 :                 serp("Failed to initialize output buffer");
     213            0 :                 status = FAILURE;
     214              :         }
     215              : 
     216              :         /* Initialize parameters */
     217            8 :         if(SUCCESS == status)
     218              :         {
     219            8 :                 memset(&xpp,0,sizeof(xpp));
     220            8 :                 xpp.flags |= XDF_NEED_MINIMAL;
     221            8 :                 xecfg.ctxlen = 0;
     222            8 :                 xecfg.str_meta = 0;
     223            8 :                 ecb.priv = output;
     224            8 :                 ecb.outf = append_to_buffer;
     225              :         }
     226              : 
     227              :         /* Create mmfile structures from input strings */
     228            8 :         if(SUCCESS == status)
     229              :         {
     230            8 :                 status = create_mmfile(&mf1,string1);
     231              :         }
     232              : 
     233            8 :         if(SUCCESS == status)
     234              :         {
     235            8 :                 status = create_mmfile(&mf2,string2);
     236              :         }
     237              : 
     238              :         /* Perform comparison */
     239            8 :         if(SUCCESS == status)
     240              :         {
     241            8 :                 if(xdl_diff(&mf1,&mf2,&xpp,&xecfg,&ecb) < 0)
     242              :                 {
     243            0 :                         serp("Diff failed");
     244            0 :                         status = FAILURE;
     245              :                 }
     246              :         }
     247              : 
     248              :         /* Save result */
     249            8 :         if(SUCCESS == status)
     250              :         {
     251            8 :                 *diff = strdup(output->buffer);
     252              : 
     253            8 :                 if(NULL == *diff)
     254              :                 {
     255            0 :                         status = FAILURE;
     256              :                 }
     257              :         }
     258              : 
     259              :         /* Free resources */
     260            8 :         xdl_free_mmfile(&mf1);
     261            8 :         xdl_free_mmfile(&mf2);
     262              : 
     263            8 :         if(output != NULL)
     264              :         {
     265            8 :                 if(output->buffer != NULL)
     266              :                 {
     267            8 :                         free(output->buffer);
     268              :                 }
     269              : 
     270            8 :                 free(output);
     271              :         }
     272              : 
     273            8 :         return(status);
     274              : }
        

Generated by: LCOV version 2.0-1