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

Collapse All | Expand All

(-)b/usr.bin/grep/util.c (-13 / +55 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-293 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;
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;
288
289
		/* Loop to compare with all the patterns */
312
		/* Loop to compare with all the patterns */
290
		for (i = 0; i < patterns; i++) {
313
		for (i = 0; i < patterns; i++) {
314
			pmatch.rm_so = st;
315
			pmatch.rm_eo = l->len;
291
			if (fg_pattern[i].pattern)
316
			if (fg_pattern[i].pattern)
292
				r = fastexec(&fg_pattern[i],
317
				r = fastexec(&fg_pattern[i],
293
				    l->dat, 1, &pmatch, eflags);
318
				    l->dat, 1, &pmatch, eflags);
Lines 295-303 procline(struct str *l, int nottext) Link Here
295
				r = regexec(&r_pattern[i], l->dat, 1,
320
				r = regexec(&r_pattern[i], l->dat, 1,
296
				    &pmatch, eflags);
321
				    &pmatch, eflags);
297
			r = (r == 0) ? 0 : REG_NOMATCH;
322
			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)
323
			if (r == REG_NOMATCH)
302
				continue;
324
				continue;
303
			/* Check for full match */
325
			/* Check for full match */
Lines 324-333 procline(struct str *l, int nottext) Link Here
324
					r = REG_NOMATCH;
346
					r = REG_NOMATCH;
325
			}
347
			}
326
			if (r == 0) {
348
			if (r == 0) {
349
				lastmatches ++;
350
				lastmatch = pmatch;
351
				/* Skip over zero-length matches */
352
				if (pmatch.rm_so == pmatch.rm_eo)
353
					continue;
327
				if (m == 0)
354
				if (m == 0)
328
					c++;
355
					c++;
329
				if (m < MAX_LINE_MATCHES)
356
330
					matches[m++] = pmatch;
357
				if (m < MAX_LINE_MATCHES) {
358
						/* Conflicting matches? */
359
					if (m > 0 && overlaps(pmatch, matches[m-1])) {
360
						/* Replace previous match if the new one is earlier and/or longer */
361
						if (pmatch.rm_so < matches[m-1].rm_so ||
362
							(pmatch.rm_eo - pmatch.rm_so) >= (matches[m-1].rm_eo - matches[m-1].rm_so)) {
363
							matches[m-1] = pmatch;
364
							nst = pmatch.rm_eo;
365
						}
366
					} else {
367
						/* Advance as normal if not */
368
						matches[m++] = pmatch;
369
						nst = pmatch.rm_eo;
370
					}
371
				}
372
331
				/* matches - skip further patterns */
373
				/* matches - skip further patterns */
332
				if ((color == NULL && !oflag) ||
374
				if ((color == NULL && !oflag) ||
333
				    qflag || lflag)
375
				    qflag || lflag)
Lines 343-351 procline(struct str *l, int nottext) Link Here
343
		/* One pass if we are not recording matches */
385
		/* One pass if we are not recording matches */
344
		if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag))
386
		if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag))
345
			break;
387
			break;
388
		
389
		/* If we didn't have any matches or REG_NOSUB set */
390
		if (lastmatches == 0 || (cflags & REG_NOSUB))
391
			nst = l->len;
346
392
347
		if (st == (size_t)pmatch.rm_so)
393
		if (lastmatches == 0)
348
			break; 	/* No matches */
394
			/* No matches */
395
			break;
396
		else if (st == nst && lastmatch.rm_so == lastmatch.rm_eo)
397
			/* Zero-length match -- advance one more so we don't get stuck */
398
			nst ++;
399
400
		/* Advance st based on previous matches */
401
		st = nst;
349
	}
402
	}
350
403
351
404
Lines 444-449 printline(struct str *line, int sep, regmatch_t *matches, int m) Link Here
444
	size_t a = 0;
497
	size_t a = 0;
445
	int i, n = 0;
498
	int i, n = 0;
446
499
500
	/* If matchall, everything matches but don't actually print for -o */
501
	if (oflag && matchall)
502
		return;
503
447
	if (!hflag) {
504
	if (!hflag) {
448
		if (!nullflag) {
505
		if (!nullflag) {
449
			fputs(line->file, stdout);
506
			fputs(line->file, stdout);

Return to bug 195763