| 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@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., 59 Temple Place, Suite 330, Boston, MA
 | 
|---|
| 19 |    02111-1307 USA.  */
 | 
|---|
| 20 | 
 | 
|---|
| 21 | #include <sys/types.h>
 | 
|---|
| 22 | #include <mcheck.h>
 | 
|---|
| 23 | #include <regex.h>
 | 
|---|
| 24 | #include <stdio.h>
 | 
|---|
| 25 | #include <stdlib.h>
 | 
|---|
| 26 | #include <string.h>
 | 
|---|
| 27 | 
 | 
|---|
| 28 | void
 | 
|---|
| 29 | frob_escapes (char *src, int pattern)
 | 
|---|
| 30 | {
 | 
|---|
| 31 |   char *dst;
 | 
|---|
| 32 | 
 | 
|---|
| 33 |   for (dst = src; *src != '\0'; dst++, src++)
 | 
|---|
| 34 |     {
 | 
|---|
| 35 |       if (*src == '\\')
 | 
|---|
| 36 |         {
 | 
|---|
| 37 |           switch (src[1])
 | 
|---|
| 38 |             {
 | 
|---|
| 39 |             case 't':
 | 
|---|
| 40 |               src++;
 | 
|---|
| 41 |               *dst = '\t';
 | 
|---|
| 42 |               continue;
 | 
|---|
| 43 |             case 'n':
 | 
|---|
| 44 |               src++;
 | 
|---|
| 45 |               *dst = '\n';
 | 
|---|
| 46 |               continue;
 | 
|---|
| 47 |             case 'r':
 | 
|---|
| 48 |               src++;
 | 
|---|
| 49 |               *dst = '\r';
 | 
|---|
| 50 |               continue;
 | 
|---|
| 51 |             case '\\':
 | 
|---|
| 52 |             case '^':
 | 
|---|
| 53 |             case '{':
 | 
|---|
| 54 |             case '|':
 | 
|---|
| 55 |             case '}':
 | 
|---|
| 56 |               if (!pattern)
 | 
|---|
| 57 |                 {
 | 
|---|
| 58 |                   src++;
 | 
|---|
| 59 |                   *dst = *src;
 | 
|---|
| 60 |                   continue;
 | 
|---|
| 61 |                 }
 | 
|---|
| 62 |               break;
 | 
|---|
| 63 |             }
 | 
|---|
| 64 |         }
 | 
|---|
| 65 |       if (src != dst)
 | 
|---|
| 66 |         *dst = *src;
 | 
|---|
| 67 |     }
 | 
|---|
| 68 |   *dst = '\0';
 | 
|---|
| 69 | }
 | 
|---|
| 70 | 
 | 
|---|
| 71 | int
 | 
|---|
| 72 | main (int argc, char **argv)
 | 
|---|
| 73 | {
 | 
|---|
| 74 |   int ret = 0, n;
 | 
|---|
| 75 |   char *line = NULL;
 | 
|---|
| 76 |   size_t line_len = 0;
 | 
|---|
| 77 |   ssize_t len;
 | 
|---|
| 78 |   FILE *f;
 | 
|---|
| 79 |   char *pattern, *string;
 | 
|---|
| 80 |   int flags = REG_EXTENDED;
 | 
|---|
| 81 |   int eflags = 0;
 | 
|---|
| 82 |   regex_t re;
 | 
|---|
| 83 |   regmatch_t rm[20];
 | 
|---|
| 84 | 
 | 
|---|
| 85 |   mtrace ();
 | 
|---|
| 86 | 
 | 
|---|
| 87 |   if (argc < 2)
 | 
|---|
| 88 |     {
 | 
|---|
| 89 |       fprintf (stderr, "Missing test filename\n");
 | 
|---|
| 90 |       return 1;
 | 
|---|
| 91 |     }
 | 
|---|
| 92 | 
 | 
|---|
| 93 |   f = fopen (argv[1], "r");
 | 
|---|
| 94 |   if (f == NULL)
 | 
|---|
| 95 |     {
 | 
|---|
| 96 |       fprintf (stderr, "Couldn't open %s\n", argv[1]);
 | 
|---|
| 97 |       return 1;
 | 
|---|
| 98 |     }
 | 
|---|
| 99 | 
 | 
|---|
| 100 |   while ((len = getline (&line, &line_len, f)) > 0)
 | 
|---|
| 101 |     {
 | 
|---|
| 102 |       char *p, *q;
 | 
|---|
| 103 |       int i;
 | 
|---|
| 104 | 
 | 
|---|
| 105 |       if (line[len - 1] == '\n')
 | 
|---|
| 106 |         line[--len] = '\0';
 | 
|---|
| 107 | 
 | 
|---|
| 108 |       puts (line);
 | 
|---|
| 109 | 
 | 
|---|
| 110 |       if (line[0] == ';')
 | 
|---|
| 111 |         continue;
 | 
|---|
| 112 | 
 | 
|---|
| 113 |       if (line[0] == '\0')
 | 
|---|
| 114 |         continue;
 | 
|---|
| 115 | 
 | 
|---|
| 116 |       if (line[0] == '-')
 | 
|---|
| 117 |         {
 | 
|---|
| 118 |           if (strstr (line, "REG_BASIC"))
 | 
|---|
| 119 |             flags = 0;
 | 
|---|
| 120 |           else
 | 
|---|
| 121 |             flags = REG_EXTENDED;
 | 
|---|
| 122 |           if (strstr (line, "REG_ICASE"))
 | 
|---|
| 123 |             flags |= REG_ICASE;
 | 
|---|
| 124 |           if (strstr (line, "REG_NEWLINE"))
 | 
|---|
| 125 |             flags |= REG_NEWLINE;
 | 
|---|
| 126 |           eflags = 0;
 | 
|---|
| 127 |           if (strstr (line, "REG_NOTBOL"))
 | 
|---|
| 128 |             eflags |= REG_NOTBOL;
 | 
|---|
| 129 |           if (strstr (line, "REG_NOTEOL"))
 | 
|---|
| 130 |             eflags |= REG_NOTEOL;
 | 
|---|
| 131 |           continue;
 | 
|---|
| 132 |         }
 | 
|---|
| 133 | 
 | 
|---|
| 134 |       pattern = line + strspn (line, " \t");
 | 
|---|
| 135 |       if (*pattern == '\0')
 | 
|---|
| 136 |         continue;
 | 
|---|
| 137 |       p = pattern + strcspn (pattern, " \t");
 | 
|---|
| 138 |       if (*p == '\0')
 | 
|---|
| 139 |         continue;
 | 
|---|
| 140 |       *p++ = '\0';
 | 
|---|
| 141 | 
 | 
|---|
| 142 |       string = p + strspn (p, " \t");
 | 
|---|
| 143 |       if (*string == '\0')
 | 
|---|
| 144 |         continue;
 | 
|---|
| 145 |       if (*string == '"')
 | 
|---|
| 146 |         {
 | 
|---|
| 147 |           string++;
 | 
|---|
| 148 |           p = strchr (string, '"');
 | 
|---|
| 149 |           if (p == NULL)
 | 
|---|
| 150 |             continue;
 | 
|---|
| 151 |           *p++ = '\0';
 | 
|---|
| 152 |         }
 | 
|---|
| 153 |       else
 | 
|---|
| 154 |         {
 | 
|---|
| 155 |           p = string + strcspn (string, " \t");
 | 
|---|
| 156 |           if (*string == '!')
 | 
|---|
| 157 |             string = NULL;
 | 
|---|
| 158 |           else if (*p == '\0')
 | 
|---|
| 159 |             continue;
 | 
|---|
| 160 |           else
 | 
|---|
| 161 |             *p++ = '\0';
 | 
|---|
| 162 |         }
 | 
|---|
| 163 | 
 | 
|---|
| 164 |       frob_escapes (pattern, 1);
 | 
|---|
| 165 |       if (string != NULL)
 | 
|---|
| 166 |         frob_escapes (string, 0);
 | 
|---|
| 167 | 
 | 
|---|
| 168 |       n = regcomp (&re, pattern, flags);
 | 
|---|
| 169 |       if (n != 0)
 | 
|---|
| 170 |         {
 | 
|---|
| 171 |           if (string != NULL)
 | 
|---|
| 172 |             {
 | 
|---|
| 173 |               char buf[500];
 | 
|---|
| 174 |               regerror (n, &re, buf, sizeof (buf));
 | 
|---|
| 175 |               printf ("FAIL regcomp unexpectedly failed: %s\n",
 | 
|---|
| 176 |                       buf);
 | 
|---|
| 177 |               ret = 1;
 | 
|---|
| 178 |             }
 | 
|---|
| 179 |           continue;
 | 
|---|
| 180 |         }
 | 
|---|
| 181 |       else if (string == NULL)
 | 
|---|
| 182 |         {
 | 
|---|
| 183 |           regfree (&re);
 | 
|---|
| 184 |           puts ("FAIL regcomp unpexpectedly succeeded");
 | 
|---|
| 185 |           ret = 1;
 | 
|---|
| 186 |           continue;
 | 
|---|
| 187 |         }
 | 
|---|
| 188 | 
 | 
|---|
| 189 |       if (regexec (&re, string, 20, rm, eflags))
 | 
|---|
| 190 |         {
 | 
|---|
| 191 |           for (i = 0; i < 20; ++i)
 | 
|---|
| 192 |             {
 | 
|---|
| 193 |               rm[i].rm_so = -1;
 | 
|---|
| 194 |               rm[i].rm_eo = -1;
 | 
|---|
| 195 |             }
 | 
|---|
| 196 |         }
 | 
|---|
| 197 | 
 | 
|---|
| 198 |       regfree (&re);
 | 
|---|
| 199 | 
 | 
|---|
| 200 |       for (i = 0; i < 20 && *p != '\0'; ++i)
 | 
|---|
| 201 |         {
 | 
|---|
| 202 |           int rm_so, rm_eo;
 | 
|---|
| 203 | 
 | 
|---|
| 204 |           rm_so = strtol (p, &q, 10);
 | 
|---|
| 205 |           if (p == q)
 | 
|---|
| 206 |             break;
 | 
|---|
| 207 |           p = q;
 | 
|---|
| 208 | 
 | 
|---|
| 209 |           rm_eo = strtol (p, &q, 10);
 | 
|---|
| 210 |           if (p == q)
 | 
|---|
| 211 |             break;
 | 
|---|
| 212 |           p = q;
 | 
|---|
| 213 | 
 | 
|---|
| 214 |           if (rm[i].rm_so != rm_so || rm[i].rm_eo != rm_eo)
 | 
|---|
| 215 |             {
 | 
|---|
| 216 |               printf ("FAIL rm[%d] %d..%d != expected %d..%d\n",
 | 
|---|
| 217 |                       i, rm[i].rm_so, rm[i].rm_eo, rm_so, rm_eo);
 | 
|---|
| 218 |               ret = 1;
 | 
|---|
| 219 |               break;
 | 
|---|
| 220 |             }
 | 
|---|
| 221 |         }
 | 
|---|
| 222 |     }
 | 
|---|
| 223 | 
 | 
|---|
| 224 |   free (line);
 | 
|---|
| 225 |   fclose (f);
 | 
|---|
| 226 |   return ret;
 | 
|---|
| 227 | }
 | 
|---|