Lines 52-57
__FBSDID("$FreeBSD$");
Link Here
|
52 |
#include "fastmatch.h" |
52 |
#include "fastmatch.h" |
53 |
#include "grep.h" |
53 |
#include "grep.h" |
54 |
|
54 |
|
|
|
55 |
#ifndef MAX |
56 |
#define MAX(a,b) ((a > b) ? (a) : (b)) |
57 |
#endif |
58 |
|
55 |
static int linesqueued; |
59 |
static int linesqueued; |
56 |
static int procline(struct str *l, int); |
60 |
static int procline(struct str *l, int); |
57 |
|
61 |
|
Lines 264-269
procfile(const char *fn)
Link Here
|
264 |
} |
283 |
} |
265 |
|
284 |
|
266 |
#define iswword(x) (iswalnum((x)) || (x) == L'_') |
285 |
#define iswword(x) (iswalnum((x)) || (x) == L'_') |
|
|
286 |
#define overlaps(a,b) ( \ |
287 |
((a.rm_so) >= (b.rm_so) && (a.rm_so) <= (b.rm_eo-1)) || \ |
288 |
((a.rm_eo-1) >= (b.rm_so) && (a.rm_eo) <= (b.rm_eo)) || \ |
289 |
((a.rm_so) < (b.rm_so) && (a.rm_eo-1) >= (b.rm_so)) || \ |
290 |
((a.rm_so) < (b.rm_eo-1) && (a.rm_eo) >= (b.rm_eo)) \ |
291 |
) |
267 |
|
292 |
|
268 |
/* |
293 |
/* |
269 |
* Processes a line comparing it with the specified patterns. Each pattern |
294 |
* Processes a line comparing it with the specified patterns. Each pattern |
Lines 276-303
static int
Link Here
|
276 |
procline(struct str *l, int nottext) |
301 |
procline(struct str *l, int nottext) |
277 |
{ |
302 |
{ |
278 |
regmatch_t matches[MAX_LINE_MATCHES]; |
303 |
regmatch_t matches[MAX_LINE_MATCHES]; |
279 |
regmatch_t pmatch; |
304 |
regmatch_t pmatch, lastmatch; |
280 |
size_t st = 0; |
305 |
size_t st = 0, nst = 0; |
281 |
unsigned int i; |
306 |
unsigned int i; |
282 |
int c = 0, m = 0, r = 0; |
307 |
int c = 0, m = 0, r = 0, lastmatches = 0, leflags = eflags; |
283 |
|
308 |
|
284 |
/* Loop to process the whole line */ |
309 |
/* Loop to process the whole line */ |
285 |
while (st <= l->len) { |
310 |
while (st <= l->len) { |
286 |
pmatch.rm_so = st; |
311 |
lastmatches = 0; |
287 |
pmatch.rm_eo = l->len; |
312 |
if (st > 0) |
288 |
|
313 |
leflags |= REG_NOTBOL; |
289 |
/* Loop to compare with all the patterns */ |
314 |
/* Loop to compare with all the patterns */ |
290 |
for (i = 0; i < patterns; i++) { |
315 |
for (i = 0; i < patterns; i++) { |
|
|
316 |
pmatch.rm_so = st; |
317 |
pmatch.rm_eo = l->len; |
291 |
if (fg_pattern[i].pattern) |
318 |
if (fg_pattern[i].pattern) |
292 |
r = fastexec(&fg_pattern[i], |
319 |
r = fastexec(&fg_pattern[i], |
293 |
l->dat, 1, &pmatch, eflags); |
320 |
l->dat, 1, &pmatch, leflags); |
294 |
else |
321 |
else |
295 |
r = regexec(&r_pattern[i], l->dat, 1, |
322 |
r = regexec(&r_pattern[i], l->dat, 1, |
296 |
&pmatch, eflags); |
323 |
&pmatch, leflags); |
297 |
r = (r == 0) ? 0 : REG_NOMATCH; |
324 |
r = (r == 0) ? 0 : REG_NOMATCH; |
298 |
st = (cflags & REG_NOSUB) |
|
|
299 |
? (size_t)l->len |
300 |
: (size_t)pmatch.rm_eo; |
301 |
if (r == REG_NOMATCH) |
325 |
if (r == REG_NOMATCH) |
302 |
continue; |
326 |
continue; |
303 |
/* Check for full match */ |
327 |
/* Check for full match */ |
Lines 324-333
procline(struct str *l, int nottext)
Link Here
|
324 |
r = REG_NOMATCH; |
348 |
r = REG_NOMATCH; |
325 |
} |
349 |
} |
326 |
if (r == 0) { |
350 |
if (r == 0) { |
|
|
351 |
lastmatches ++; |
352 |
lastmatch = pmatch; |
353 |
/* Skip over zero-length matches */ |
354 |
if (pmatch.rm_so == pmatch.rm_eo) |
355 |
continue; |
327 |
if (m == 0) |
356 |
if (m == 0) |
328 |
c++; |
357 |
c++; |
329 |
if (m < MAX_LINE_MATCHES) |
358 |
|
330 |
matches[m++] = pmatch; |
359 |
if (m < MAX_LINE_MATCHES) { |
|
|
360 |
/* Conflicting matches? */ |
361 |
if (m > 0 && overlaps(pmatch, matches[m-1])) { |
362 |
/* Replace previous match if the new one is earlier and/or longer */ |
363 |
if (pmatch.rm_so < matches[m-1].rm_so || |
364 |
(pmatch.rm_eo - pmatch.rm_so) >= (matches[m-1].rm_eo - matches[m-1].rm_so)) { |
365 |
matches[m-1] = pmatch; |
366 |
nst = pmatch.rm_eo; |
367 |
} |
368 |
} else { |
369 |
/* Advance as normal if not */ |
370 |
matches[m++] = pmatch; |
371 |
nst = pmatch.rm_eo; |
372 |
} |
373 |
} |
374 |
|
331 |
/* matches - skip further patterns */ |
375 |
/* matches - skip further patterns */ |
332 |
if ((color == NULL && !oflag) || |
376 |
if ((color == NULL && !oflag) || |
333 |
qflag || lflag) |
377 |
qflag || lflag) |
Lines 344-351
procline(struct str *l, int nottext)
Link Here
|
344 |
if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag)) |
388 |
if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag)) |
345 |
break; |
389 |
break; |
346 |
|
390 |
|
347 |
if (st == (size_t)pmatch.rm_so) |
391 |
/* If we didn't have any matches or REG_NOSUB set */ |
348 |
break; /* No matches */ |
392 |
if (lastmatches == 0 || (cflags & REG_NOSUB)) |
|
|
393 |
nst = l->len; |
394 |
|
395 |
if (lastmatches == 0) |
396 |
/* No matches */ |
397 |
break; |
398 |
else if (st == nst && lastmatch.rm_so == lastmatch.rm_eo) |
399 |
/* Zero-length match -- advance one more so we don't get stuck */ |
400 |
nst ++; |
401 |
|
402 |
/* Advance st based on previous matches */ |
403 |
st = nst; |
349 |
} |
404 |
} |
350 |
|
405 |
|
351 |
|
406 |
|
Lines 444-449
printline(struct str *line, int sep, regmatch_t *matches, int m)
Link Here
|
444 |
size_t a = 0; |
499 |
size_t a = 0; |
445 |
int i, n = 0; |
500 |
int i, n = 0; |
446 |
|
501 |
|
|
|
502 |
/* If matchall, everything matches but don't actually print for -o */ |
503 |
if (oflag && matchall) |
504 |
return; |
505 |
|
447 |
if (!hflag) { |
506 |
if (!hflag) { |
448 |
if (!nullflag) { |
507 |
if (!nullflag) { |
449 |
fputs(line->file, stdout); |
508 |
fputs(line->file, stdout); |