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