]>
Commit | Line | Data |
---|---|---|
c06a6956 UD |
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 | ||
bf7c04cd | 11 | #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 |
c06a6956 UD |
12 | static clockid_t cl; |
13 | static int use_clock; | |
14 | #endif | |
15 | ||
16 | static int | |
17 | do_test (void) | |
18 | { | |
bf7c04cd UD |
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; | |
c06a6956 UD |
27 | #endif |
28 | ||
29 | static const char *pat[] = { | |
30 | ".?.?.?.?.?.?.?Log\\.13", | |
31 | "(.?)(.?)(.?)(.?)(.?)(.?)(.?)Log\\.13", | |
32 | "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))" | |
33 | "((((((((((.?))))))))))((((((((((.?))))))))))((((((((((.?))))))))))" | |
34 | "((((((((((.?))))))))))Log\\.13" }; | |
35 | ||
b3008279 | 36 | int fd = open ("../ChangeLog.old/ChangeLog.14", O_RDONLY); |
c06a6956 UD |
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 | ||
bf7c04cd | 120 | #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 |
c06a6956 UD |
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 | ||
bf7c04cd | 219 | #if defined _POSIX_CPUTIME && _POSIX_CPUTIME >= 0 |
c06a6956 UD |
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" |