Home | History | Annotate | Download | only in testsuite
      1 /* Regular expression tests.
      2    Copyright (C) 2003 Free Software Foundation, Inc.
      3    This file is part of the GNU C Library.
      4    Contributed by Jakub Jelinek <jakub (at) redhat.com>, 2003.
      5 
      6    The GNU C Library is free software; you can redistribute it and/or
      7    modify it under the terms of the GNU Lesser General Public
      8    License as published by the Free Software Foundation; either
      9    version 2.1 of the License, or (at your option) any later version.
     10 
     11    The GNU C Library is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14    Lesser General Public License for more details.
     15 
     16    You should have received a copy of the GNU Lesser General Public
     17    License along with the GNU C Library; if not, write to the Free
     18    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     19    02110-1301 USA.  */
     20 
     21 #ifdef HAVE_CONFIG_H
     22 #include "config.h"
     23 #endif
     24 
     25 #include <sys/types.h>
     26 #ifdef HAVE_MCHECK_H
     27 #include <mcheck.h>
     28 #endif
     29 #include <regex.h>
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 
     34 void
     35 frob_escapes (char *src, int pattern)
     36 {
     37   char *dst;
     38 
     39   for (dst = src; *src != '\0'; dst++, src++)
     40     {
     41       if (*src == '\\')
     42 	{
     43 	  switch (src[1])
     44 	    {
     45 	    case 't':
     46 	      src++;
     47 	      *dst = '\t';
     48 	      continue;
     49 	    case 'n':
     50 	      src++;
     51 	      *dst = '\n';
     52 	      continue;
     53 	    case 'r':
     54 	      src++;
     55 	      *dst = '\r';
     56 	      continue;
     57 	    case '\\':
     58 	    case '^':
     59 	    case '{':
     60 	    case '|':
     61 	    case '}':
     62 	      if (!pattern)
     63 		{
     64 		  src++;
     65 		  *dst = *src;
     66 		  continue;
     67 		}
     68 	      break;
     69 	    }
     70 	}
     71       if (src != dst)
     72 	*dst = *src;
     73     }
     74   *dst = '\0';
     75 }
     76 
     77 int
     78 main (int argc, char **argv)
     79 {
     80   int ret = 0, n;
     81   char *line = NULL;
     82   size_t line_len = 0;
     83   ssize_t len;
     84   FILE *f;
     85   char *pattern, *string;
     86   int flags = REG_EXTENDED;
     87   int eflags = 0;
     88   regex_t re;
     89   regmatch_t rm[20];
     90 
     91 #ifdef HAVE_MCHECK_H
     92   mtrace ();
     93 #endif
     94 
     95   if (argc < 2)
     96     {
     97       fprintf (stderr, "Missing test filename\n");
     98       return 1;
     99     }
    100 
    101   f = fopen (argv[1], "r");
    102   if (f == NULL)
    103     {
    104       fprintf (stderr, "Couldn't open %s\n", argv[1]);
    105       return 1;
    106     }
    107 
    108   while ((len = getline (&line, &line_len, f)) > 0)
    109     {
    110       char *p, *q;
    111       int i;
    112 
    113       if (line[len - 1] == '\n')
    114 	line[--len] = '\0';
    115 
    116       puts (line);
    117 
    118       if (line[0] == ';')
    119 	continue;
    120 
    121       if (line[0] == '\0')
    122 	continue;
    123 
    124       if (line[0] == '-')
    125 	{
    126 	  if (strstr (line, "REG_BASIC"))
    127 	    flags = 0;
    128 	  else
    129 	    flags = REG_EXTENDED;
    130 	  if (strstr (line, "REG_ICASE"))
    131 	    flags |= REG_ICASE;
    132 	  if (strstr (line, "REG_NEWLINE"))
    133 	    flags |= REG_NEWLINE;
    134 	  eflags = 0;
    135 	  if (strstr (line, "REG_NOTBOL"))
    136 	    eflags |= REG_NOTBOL;
    137 	  if (strstr (line, "REG_NOTEOL"))
    138 	    eflags |= REG_NOTEOL;
    139 	  continue;
    140 	}
    141 
    142       pattern = line + strspn (line, " \t");
    143       if (*pattern == '\0')
    144 	continue;
    145       p = pattern + strcspn (pattern, " \t");
    146       if (*p == '\0')
    147 	continue;
    148       *p++ = '\0';
    149 
    150       string = p + strspn (p, " \t");
    151       if (*string == '\0')
    152 	continue;
    153       if (*string == '"')
    154 	{
    155 	  string++;
    156 	  p = strchr (string, '"');
    157 	  if (p == NULL)
    158 	    continue;
    159 	  *p++ = '\0';
    160 	}
    161       else
    162 	{
    163 	  p = string + strcspn (string, " \t");
    164 	  if (*string == '!')
    165 	    string = NULL;
    166 	  else if (*p == '\0')
    167 	    continue;
    168 	  else
    169 	    *p++ = '\0';
    170 	}
    171 
    172       frob_escapes (pattern, 1);
    173       if (string != NULL)
    174 	frob_escapes (string, 0);
    175 
    176       n = regcomp (&re, pattern, flags);
    177       if (n != 0)
    178 	{
    179 	  if (string != NULL)
    180 	    {
    181 	      char buf[500];
    182 	      regerror (n, &re, buf, sizeof (buf));
    183 	      printf ("FAIL regcomp unexpectedly failed: %s\n",
    184 		      buf);
    185 	      ret = 1;
    186 	    }
    187 	  continue;
    188 	}
    189       else if (string == NULL)
    190 	{
    191 	  regfree (&re);
    192 	  puts ("FAIL regcomp unpexpectedly succeeded");
    193 	  ret = 1;
    194 	  continue;
    195 	}
    196 
    197       if (regexec (&re, string, 20, rm, eflags))
    198 	{
    199 	  for (i = 0; i < 20; ++i)
    200 	    {
    201 	      rm[i].rm_so = -1;
    202 	      rm[i].rm_eo = -1;
    203 	    }
    204 	}
    205 
    206       regfree (&re);
    207 
    208       for (i = 0; i < 20 && *p != '\0'; ++i)
    209 	{
    210 	  int rm_so, rm_eo;
    211 
    212 	  rm_so = strtol (p, &q, 10);
    213 	  if (p == q)
    214 	    break;
    215 	  p = q;
    216 
    217 	  rm_eo = strtol (p, &q, 10);
    218 	  if (p == q)
    219 	    break;
    220 	  p = q;
    221 
    222 	  if (rm[i].rm_so != rm_so || rm[i].rm_eo != rm_eo)
    223 	    {
    224 	      printf ("FAIL rm[%d] %d..%d != expected %d..%d\n",
    225 		      i, rm[i].rm_so, rm[i].rm_eo, rm_so, rm_eo);
    226 	      ret = 1;
    227 	      break;
    228 	    }
    229 	}
    230     }
    231 
    232   free (line);
    233   fclose (f);
    234   return ret;
    235 }
    236