(root)/
glibc-2.38/
posix/
tst-regex2.c
       1  #include <fcntl.h>
       2  #include <locale.h>
       3  #include <regex.h>
       4  #include <stdio.h>
       5  #include <stdlib.h>
       6  #include <string.h>
       7  #include <sys/stat.h>
       8  #include <time.h>
       9  #include <unistd.h>
      10  
      11  #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
      12  static clockid_t cl;
      13  static int use_clock;
      14  #endif
      15  
      16  static int
      17  do_test (void)
      18  {
      19  #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
      20  # if _POSIX_CPUTIME == 0
      21    if (sysconf (_SC_CPUTIME) < 0)
      22      use_clock = 0;
      23    else
      24  # endif
      25      /* See whether we can use the CPU clock.  */
      26      use_clock = clock_getcpuclockid (0, &cl) == 0;
      27  #endif
      28  
      29    static const char *pat[] = {
      30      ".?.?.?.?.?.?.?Log\\.13",
      31      "(.?)(.?)(.?)(.?)(.?)(.?)(.?)Log\\.13",
      32      "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))"
      33      "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))"
      34      "((((((((((.?))))))))))Log\\.13" };
      35  
      36    int fd = open ("../ChangeLog.old/ChangeLog.14", O_RDONLY);
      37    if (fd < 0)
      38      {
      39        printf ("Couldn't open ChangeLog.14: %m\n");
      40        return 1;
      41      }
      42  
      43    struct stat64 st;
      44    if (fstat64 (fd, &st) < 0)
      45      {
      46        printf ("Couldn't fstat ChangeLog.14: %m\n");
      47        return 1;
      48      }
      49  
      50    char *buf = malloc (st.st_size + 1);
      51    if (buf == NULL)
      52      {
      53        printf ("Couldn't allocate buffer: %m\n");
      54        return 1;
      55      }
      56  
      57    if (read (fd, buf, st.st_size) != (ssize_t) st.st_size)
      58      {
      59        puts ("Couldn't read ChangeLog.14");
      60        return 1;
      61      }
      62  
      63    close (fd);
      64    buf[st.st_size] = '\0';
      65  
      66    setlocale (LC_ALL, "de_DE.UTF-8");
      67  
      68    char *string = buf;
      69    size_t len = st.st_size;
      70  
      71  #ifndef WHOLE_FILE_TIMING
      72    /* Don't search the whole file normally, it takes too long.  */
      73    if (len > 500000 + 64)
      74      {
      75        string += 500000;
      76        len -= 500000;
      77      }
      78  #endif
      79  
      80    for (int testno = 0; testno < 4; ++testno)
      81      for (int i = 0; i < sizeof (pat) / sizeof (pat[0]); ++i)
      82        {
      83  	printf ("test %d pattern %d", testno, i);
      84  
      85  	regex_t rbuf;
      86  	struct re_pattern_buffer rpbuf;
      87  	int err;
      88  	if (testno < 2)
      89  	  {
      90  	    err = regcomp (&rbuf, pat[i],
      91  			   REG_EXTENDED | (testno ? REG_NOSUB : 0));
      92  	    if (err != 0)
      93  	      {
      94  		putchar ('\n');
      95  		char errstr[300];
      96  		regerror (err, &rbuf, errstr, sizeof (errstr));
      97  		puts (errstr);
      98  		return err;
      99  	      }
     100  	  }
     101  	else
     102  	  {
     103  	    re_set_syntax (RE_SYNTAX_POSIX_EGREP
     104  			   | (testno == 3 ? RE_NO_SUB : 0));
     105  
     106  	    memset (&rpbuf, 0, sizeof (rpbuf));
     107  	    const char *s = re_compile_pattern (pat[i], strlen (pat[i]),
     108  						&rpbuf);
     109  	    if (s != NULL)
     110  	      {
     111  		printf ("\n%s\n", s);
     112  		return 1;
     113  	      }
     114  
     115  	    /* Just so that this can be tested with earlier glibc as well.  */
     116  	    if (testno == 3)
     117  	      rpbuf.no_sub = 1;
     118  	  }
     119  
     120  #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
     121        struct timespec start, stop;
     122        if (use_clock)
     123  	use_clock = clock_gettime (cl, &start) == 0;
     124  #endif
     125  
     126        if (testno < 2)
     127  	{
     128  	  regmatch_t pmatch[71];
     129  	  err = regexec (&rbuf, string, 71, pmatch, 0);
     130  	  if (err == REG_NOMATCH)
     131  	    {
     132  	      puts ("\nregexec failed");
     133  	      return 1;
     134  	    }
     135  
     136  	  if (testno == 0)
     137  	    {
     138  	      if (pmatch[0].rm_eo != pmatch[0].rm_so + 13
     139  		  || pmatch[0].rm_eo > len
     140  		  || pmatch[0].rm_so < len - 100
     141  		  || strncmp (string + pmatch[0].rm_so,
     142  			      " ChangeLog.13 for earlier changes",
     143  			      sizeof " ChangeLog.13 for earlier changes" - 1)
     144  		     != 0)
     145  		{
     146  		  puts ("\nregexec without REG_NOSUB did not find the correct match");
     147  		  return 1;
     148  		}
     149  
     150  	      if (i > 0)
     151  		for (int j = 0, l = 1; j < 7; ++j)
     152  		  for (int k = 0; k < (i == 1 ? 1 : 10); ++k, ++l)
     153  		    if (pmatch[l].rm_so != pmatch[0].rm_so + j
     154  			|| pmatch[l].rm_eo != pmatch[l].rm_so + 1)
     155  		      {
     156  			printf ("\npmatch[%d] incorrect\n", l);
     157  			return 1;
     158  		      }
     159  	    }
     160  	}
     161        else
     162  	{
     163  	  struct re_registers regs;
     164  
     165  	  memset (&regs, 0, sizeof (regs));
     166  	  int match = re_search (&rpbuf, string, len, 0, len,
     167  				 &regs);
     168  	  if (match < 0)
     169  	    {
     170  	      puts ("\nre_search failed");
     171  	      return 1;
     172  	    }
     173  
     174  	  if (match + 13 > len
     175  	      || match < len - 100
     176  	      || strncmp (string + match,
     177  			  " ChangeLog.13 for earlier changes",
     178  			  sizeof " ChangeLog.13 for earlier changes" - 1)
     179  		  != 0)
     180  	    {
     181  	      puts ("\nre_search did not find the correct match");
     182  	      return 1;
     183  	    }
     184  
     185  	  if (testno == 2)
     186  	    {
     187  	      if (regs.num_regs != 2 + (i == 0 ? 0 : i == 1 ? 7 : 70))
     188  		{
     189  		  printf ("\nincorrect num_regs %d\n", regs.num_regs);
     190  		  return 1;
     191  		}
     192  
     193  	      if (regs.start[0] != match || regs.end[0] != match + 13)
     194  		{
     195  		  printf ("\nincorrect regs.{start,end}[0] = { %d, %d}\n",
     196  			  regs.start[0], regs.end[0]);
     197  		  return 1;
     198  		}
     199  
     200  	      if (regs.start[regs.num_regs - 1] != -1
     201  		  || regs.end[regs.num_regs - 1] != -1)
     202  		{
     203  		  puts ("\nincorrect regs.{start,end}[num_regs - 1]");
     204  		  return 1;
     205  		}
     206  
     207  	      if (i > 0)
     208  		for (int j = 0, l = 1; j < 7; ++j)
     209  		  for (int k = 0; k < (i == 1 ? 1 : 10); ++k, ++l)
     210  		    if (regs.start[l] != match + j
     211  			|| regs.end[l] != regs.start[l] + 1)
     212  		      {
     213  			printf ("\nregs.{start,end}[%d] incorrect\n", l);
     214  			return 1;
     215  		      }
     216  	    }
     217  	}
     218  
     219  #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0
     220        if (use_clock)
     221  	use_clock = clock_gettime (cl, &stop) == 0;
     222        if (use_clock)
     223  	{
     224  	  stop.tv_sec -= start.tv_sec;
     225  	  if (stop.tv_nsec < start.tv_nsec)
     226  	    {
     227  	      stop.tv_sec--;
     228  	      stop.tv_nsec += 1000000000 - start.tv_nsec;
     229  	    }
     230  	  else
     231  	    stop.tv_nsec -= start.tv_nsec;
     232  	  printf (": %ld.%09lds\n", (long) stop.tv_sec, (long) stop.tv_nsec);
     233  	}
     234        else
     235  #endif
     236  	putchar ('\n');
     237  
     238        if (testno < 2)
     239  	regfree (&rbuf);
     240        else
     241  	regfree (&rpbuf);
     242      }
     243  
     244    return 0;
     245  }
     246  
     247  #define TEST_FUNCTION do_test ()
     248  #include "../test-skeleton.c"