View | Details | Raw Unified | Return to bug 195763 | Differences between
and this patch

Collapse All | Expand All

(-)b/usr.bin/grep/util.c (-15 / +59 lines)
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);

Return to bug 195763