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