LCOV - code coverage report
Current view: top level - src - path_build_relative.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 68.9 % 61 42
Test Date: 2026-07-12 01:01:34 Functions: 100.0 % 1 1
Branches: 64.3 % 42 27

             Branch data     Line data    Source code
       1                 :             : #include "precizer.h"
       2                 :             : 
       3                 :             : /**
       4                 :             :  * @brief Build a root-relative path for an FTS entry
       5                 :             :  *
       6                 :             :  * @details
       7                 :             :  * Builds a path from the FTS parent chain instead of trimming a textual root
       8                 :             :  * prefix from `FTSENT::fts_path`. This keeps the stored file path independent
       9                 :             :  * from how the traversal root was written by the user, while preserving that
      10                 :             :  * original root spelling in the database `paths` table
      11                 :             :  *
      12                 :             :  * The root entry itself is represented as ".". Child entries are assembled
      13                 :             :  * from their component names, for example `dir/subdir/file.txt`
      14                 :             :  *
      15                 :             :  * @param[out] relative_path String descriptor that receives the relative path
      16                 :             :  * @param[in] entry FTS entry whose path should be built
      17                 :             :  * @return SUCCESS when the path is built, otherwise FAILURE
      18                 :             :  */
      19                 :       23658 : Return path_build_relative(
      20                 :             :         memory       *relative_path,
      21                 :             :         const FTSENT *entry)
      22                 :             : {
      23                 :             :         /* Status returned by this function through provide()
      24                 :             :            Default value assumes successful completion */
      25                 :       23658 :         Return status = SUCCESS;
      26                 :             : 
      27         [ -  + ]:       23658 :         if(entry == NULL)
      28                 :             :         {
      29                 :           0 :                 report("Relative path building; FTS entry must be non-NULL");
      30                 :           0 :                 provide(FAILURE);
      31                 :             :         }
      32                 :             : 
      33         [ -  + ]:       23658 :         if(entry->fts_level < FTS_ROOTLEVEL)
      34                 :             :         {
      35                 :           0 :                 report("Relative path building; FTS entry is above the traversal root");
      36                 :           0 :                 provide(FAILURE);
      37                 :             :         }
      38                 :             : 
      39         [ +  + ]:       23658 :         if(entry->fts_level == FTS_ROOTLEVEL)
      40                 :             :         {
      41                 :         447 :                 run(m_copy_literal(relative_path,"."));
      42                 :         447 :                 provide(status);
      43                 :             :         }
      44                 :             : 
      45                 :       23211 :         size_t relative_path_length = 0U;
      46                 :       23211 :         size_t component_count = 0U;
      47                 :             : 
      48                 :       23211 :         for(const FTSENT *node = entry;
      49   [ +  -  +  + ]:      117827 :                 node != NULL && node->fts_level > FTS_ROOTLEVEL;
      50                 :       94616 :                 node = node->fts_parent)
      51                 :             :         {
      52         [ -  + ]:       94616 :                 if(node->fts_namelen == 0U)
      53                 :             :                 {
      54                 :           0 :                         report("Relative path building; FTS entry has an invalid component name");
      55                 :           0 :                         provide(FAILURE);
      56                 :             :                 }
      57                 :             : 
      58         [ -  + ]:       94616 :                 if(relative_path_length > SIZE_MAX - (size_t)node->fts_namelen)
      59                 :             :                 {
      60                 :           0 :                         report("Relative path building; Path length overflow");
      61                 :           0 :                         provide(FAILURE);
      62                 :             :                 }
      63                 :             : 
      64                 :       94616 :                 relative_path_length += (size_t)node->fts_namelen;
      65                 :             : 
      66         [ +  + ]:       94616 :                 if(component_count > 0U)
      67                 :             :                 {
      68         [ -  + ]:       71405 :                         if(relative_path_length == SIZE_MAX)
      69                 :             :                         {
      70                 :           0 :                                 report("Relative path building; Path separator overflow");
      71                 :           0 :                                 provide(FAILURE);
      72                 :             :                         }
      73                 :             : 
      74                 :       71405 :                         relative_path_length++;
      75                 :             :                 }
      76                 :             : 
      77                 :       94616 :                 component_count++;
      78                 :             :         }
      79                 :             : 
      80                 :       23211 :         const FTSENT *root_entry = entry;
      81                 :             : 
      82   [ +  -  +  + ]:      117827 :         while(root_entry != NULL && root_entry->fts_level > FTS_ROOTLEVEL)
      83                 :             :         {
      84                 :       94616 :                 root_entry = root_entry->fts_parent;
      85                 :             :         }
      86                 :             : 
      87   [ +  -  -  + ]:       23211 :         if(root_entry == NULL || root_entry->fts_level != FTS_ROOTLEVEL)
      88                 :             :         {
      89                 :           0 :                 report("Relative path building; FTS parent chain does not reach the traversal root");
      90                 :           0 :                 provide(FAILURE);
      91                 :             :         }
      92                 :             : 
      93         [ -  + ]:       23211 :         if(relative_path_length == SIZE_MAX)
      94                 :             :         {
      95                 :           0 :                 report("Relative path building; Path terminator overflow");
      96                 :           0 :                 provide(FAILURE);
      97                 :             :         }
      98                 :             : 
      99                 :       23211 :         run(m_resize(relative_path,relative_path_length + 1U));
     100                 :             : 
     101         [ -  + ]:       23211 :         if(SUCCESS != status)
     102                 :             :         {
     103                 :           0 :                 provide(status);
     104                 :             :         }
     105                 :             : 
     106                 :       23211 :         char *relative_path_data = m_data(char,relative_path);
     107                 :             : 
     108         [ -  + ]:       23211 :         if(relative_path_data == NULL)
     109                 :             :         {
     110                 :           0 :                 report("Relative path building; Destination buffer is unavailable");
     111                 :           0 :                 provide(FAILURE);
     112                 :             :         }
     113                 :             : 
     114                 :       23211 :         char *write_cursor = relative_path_data + relative_path_length;
     115                 :       23211 :         *write_cursor = '\0';
     116                 :             : 
     117                 :       23211 :         for(const FTSENT *node = entry;
     118   [ +  -  +  + ]:      117827 :                 node != NULL && node->fts_level > FTS_ROOTLEVEL;
     119                 :       94616 :                 node = node->fts_parent)
     120                 :             :         {
     121                 :       94616 :                 const size_t component_length = (size_t)node->fts_namelen;
     122                 :             : 
     123                 :       94616 :                 write_cursor -= component_length;
     124                 :       94616 :                 memcpy(write_cursor,node->fts_name,component_length);
     125                 :             : 
     126   [ +  -  +  + ]:       94616 :                 if(node->fts_parent != NULL && node->fts_parent->fts_level > FTS_ROOTLEVEL)
     127                 :             :                 {
     128                 :       71405 :                         write_cursor--;
     129                 :       71405 :                         *write_cursor = '/';
     130                 :             :                 }
     131                 :             :         }
     132                 :             : 
     133         [ -  + ]:       23211 :         if(write_cursor != relative_path_data)
     134                 :             :         {
     135                 :           0 :                 report("Relative path building; Internal path assembly size mismatch");
     136                 :           0 :                 provide(FAILURE);
     137                 :             :         }
     138                 :             : 
     139                 :       23211 :         run(m_finalize_string(relative_path,relative_path_length));
     140                 :             : 
     141                 :       23211 :         provide(status);
     142                 :             : }
        

Generated by: LCOV version 2.0-1