LCOV - code coverage report
Current view: top level - libs/testitall/src - match_pattern.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.5 % 44 31
Test Date: 2026-01-12 05:34:38 Functions: 100.0 % 1 1

            Line data    Source code
       1              : #include "testitall.h"
       2              : 
       3              : /**
       4              :  * @brief Match managed memory buffers against a PCRE2 pattern.
       5              :  *
       6              :  * @param text Text descriptor that stores subject data.
       7              :  * @param pattern Pattern descriptor interpreted as PCRE2 expression.
       8              :  * @return SUCCESS on match, FAILURE otherwise.
       9              :  */
      10          142 : Return match_pattern(
      11              :         const memory *text,
      12              :         const memory *pattern,
      13              :         ...)
      14              : {
      15          142 :         Return status = SUCCESS;
      16          142 :         const char *text_view = NULL;
      17          142 :         const char *pattern_view = NULL;
      18          142 :         const char *filename = NULL;
      19              : #if 0
      20              :         char *diff = NULL;
      21              : #endif
      22              : 
      23          142 :         if((text == NULL) || (pattern == NULL))
      24              :         {
      25            0 :                 status = FAILURE;
      26              :         }
      27              : 
      28          142 :         if(SUCCESS == status)
      29              :         {
      30              :                 /* Acquire null-terminated views guarded by libmem */
      31          142 :                 text_view = getcstring(text);
      32          142 :                 pattern_view = getcstring(pattern);
      33              : 
      34          142 :                 if((text_view == NULL) || (pattern_view == NULL))
      35              :                 {
      36            0 :                         status = FAILURE;
      37              :                 }
      38              :         }
      39              : 
      40              :         va_list args;
      41          142 :         va_start(args,pattern);
      42              : 
      43              :         /* Optional third argument carries template filename for diagnostics */
      44          142 :         filename = va_arg(args,const char *);
      45          142 :         va_end(args);
      46              : 
      47              :         /* Compile the regular expression */
      48          142 :         pcre2_code *compiled_pattern = NULL;
      49          142 :         pcre2_match_data *match_data = NULL;
      50              : 
      51          142 :         if(SUCCESS == status)
      52              :         {
      53          142 :                 int errornumber = 0;
      54          142 :                 PCRE2_SIZE erroroffset = 0;
      55              : 
      56              :                 /* Compile the regular expression with multiline and dot-all flags */
      57          142 :                 compiled_pattern = pcre2_compile(
      58              :                         (PCRE2_SPTR)pattern_view,
      59              :                         PCRE2_ZERO_TERMINATED,
      60              :                         PCRE2_MULTILINE | PCRE2_DOTALL, /* Enable multiline, extended mode and dot matching newline */
      61              :                         &errornumber,
      62              :                         &erroroffset,
      63              :                         NULL);
      64              : 
      65          142 :                 if(compiled_pattern == NULL)
      66              :                 {
      67              :                         PCRE2_UCHAR buffer[MAX_CHARACTERS];
      68            0 :                         pcre2_get_error_message(errornumber,buffer,sizeof(buffer));
      69            0 :                         echo(STDERR,"ERROR: Regex compilation error at offset %d: %s\n",
      70              :                                 (int)erroroffset,buffer);
      71            0 :                         status = FAILURE;
      72              :                 }
      73              :         }
      74              : 
      75          142 :         if(SUCCESS == status)
      76              :         {
      77              :                 /* Allocate memory for match data */
      78          142 :                 match_data = pcre2_match_data_create_from_pattern(compiled_pattern,NULL);
      79              : 
      80          142 :                 if(match_data == NULL)
      81              :                 {
      82            0 :                         echo(STDERR,"ERROR: Failed to allocate PCRE2 match data\n");
      83            0 :                         status = FAILURE;
      84              :                 }
      85              :         }
      86              : 
      87          142 :         if(SUCCESS == status)
      88              :         {
      89              :                 /* Attempt to match */
      90          142 :                 int match_result = pcre2_match(
      91              :                         compiled_pattern,
      92              :                         (PCRE2_SPTR)text_view,
      93              :                         PCRE2_ZERO_TERMINATED,
      94              :                         0,
      95              :                         0,
      96              :                         match_data,
      97              :                         NULL);
      98              : 
      99          142 :                 if(match_result < 0)
     100              :                 {
     101              :                         /* Surface mismatch context or raw PCRE error */
     102            0 :                         if(match_result == PCRE2_ERROR_NOMATCH)
     103              :                         {
     104              : #if 0
     105              :                                 /* Get diff */
     106              :                                 status = compare_strings(&diff,text_view,pattern_view);
     107              : #endif
     108              : 
     109              : #if 0
     110              :                                 {
     111              :                                         // Sequentially match increasing portions of the subject string
     112              :                                         size_t mismatch_offset = 0;
     113              :                                         size_t subject_length = strlen(text_view);
     114              : 
     115              :                                         for(size_t i = 1; i <= subject_length; i++)
     116              :                                         {
     117              :                                                 match_result = pcre2_match(
     118              :                                                         compiled_pattern,
     119              :                                                         (PCRE2_SPTR)text_view,
     120              :                                                         i,
     121              :                                                         0,
     122              :                                                         0,
     123              :                                                         match_data,
     124              :                                                         NULL);
     125              : 
     126              :                                                 if(match_result < 0)
     127              :                                                 {
     128              :                                                         mismatch_offset = i - 1; // Last valid match position
     129              :                                                         break;
     130              :                                                 }
     131              :                                         }
     132              : 
     133              :                                         if(mismatch_offset < subject_length)
     134              :                                         {
     135              :                                                 echo(STDERR,"Mismatch starts at offset %zu.\n",mismatch_offset);
     136              :                                         }
     137              :                                 }
     138              : #endif
     139              : 
     140            0 :                                 if(filename != NULL)
     141              :                                 {
     142            0 :                                         echo(STDERR,YELLOW "ERROR: The pattern not match!" RESET "\n"
     143              : #if 0
     144              :                                                 YELLOW "Diff:\n>>" RESET "%s" YELLOW "<<" RESET "\n"
     145              : #endif
     146              :                                                 YELLOW "Output:\n>>" RESET "%s" YELLOW "<<" RESET "\n"
     147              :                                                 YELLOW "Compared to a pattern from the file %s:\n>>" RESET "%s" YELLOW "<<" RESET "\n",
     148              : #if 0
     149              :                                                 diff,
     150              : #endif
     151              :                                                 text_view,filename,pattern_view);
     152              :                                 } else {
     153            0 :                                         echo(STDERR,YELLOW "ERROR: The pattern not match!" RESET "\n"
     154              : #if 0
     155              :                                                 YELLOW "Diff:\n>>" RESET "%s" YELLOW "<<" RESET "\n"
     156              : #endif
     157              :                                                 YELLOW "Output:\n>>" RESET "%s" YELLOW "<<" RESET "\n"
     158              :                                                 YELLOW "Compared to a pattern:\n>>" RESET "%s" YELLOW "<<" RESET "\n",
     159              : #if 0
     160              :                                                 diff,
     161              : #endif
     162              :                                                 text_view,pattern_view);
     163              :                                 }
     164              :                         } else {
     165            0 :                                 echo(STDERR,YELLOW "ERROR: pcre2_match error: %d" RESET "\n",match_result);
     166              :                         }
     167              : 
     168            0 :                         status = FAILURE;
     169              :                 }
     170              :         }
     171              : 
     172          142 :         if(match_data != NULL)
     173              :         {
     174          142 :                 pcre2_match_data_free(match_data);
     175              :         }
     176              : 
     177          142 :         if(compiled_pattern != NULL)
     178              :         {
     179          142 :                 pcre2_code_free(compiled_pattern);
     180              :         }
     181              : 
     182              : #if 0
     183              :         /* Release diff buffer produced by optional comparison helpers */
     184              :         free(diff);
     185              : #endif
     186              : 
     187          142 :         return(status);
     188              : }
        

Generated by: LCOV version 2.0-1