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.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 (®s, 0, sizeof (regs));
|
---|
166 | int match = re_search (&rpbuf, string, len, 0, len,
|
---|
167 | ®s);
|
---|
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 TIMEOUT 20
|
---|
248 | #define TEST_FUNCTION do_test ()
|
---|
249 | #include "../test-skeleton.c"
|
---|