xref: /freebsd/usr.bin/grep/util.c (revision a74c77cc7bed8dba50e976a7be2aa0094ee27b61)
1 /*	$NetBSD: util.c,v 1.9 2011/02/27 17:33:37 joerg Exp $	*/
2 /*	$OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $	*/
3 
4 /*-
5  * SPDX-License-Identifier: BSD-2-Clause
6  *
7  * Copyright (c) 1999 James Howard and Dag-Erling Smørgrav
8  * Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
9  * Copyright (C) 2017 Kyle Evans <kevans@FreeBSD.org>
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 
38 #include <ctype.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <fnmatch.h>
42 #include <fts.h>
43 #include <libgen.h>
44 #include <stdbool.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h>
49 #include <unistd.h>
50 #include <wchar.h>
51 #include <wctype.h>
52 
53 #include "grep.h"
54 
55 static bool	 first_match = true;
56 
57 /*
58  * Match printing context
59  */
60 struct mprintc {
61 	long long	tail;		/* Number of trailing lines to record */
62 	int		last_outed;	/* Number of lines since last output */
63 	bool		doctx;		/* Printing context? */
64 	bool		printmatch;	/* Printing matches? */
65 	bool		same_file;	/* Same file as previously printed? */
66 };
67 
68 static void procmatch_match(struct mprintc *mc, struct parsec *pc);
69 static void procmatch_nomatch(struct mprintc *mc, struct parsec *pc);
70 static bool procmatches(struct mprintc *mc, struct parsec *pc, bool matched);
71 #ifdef WITH_INTERNAL_NOSPEC
72 static int litexec(const struct pat *pat, const char *string,
73     size_t nmatch, regmatch_t pmatch[]);
74 #endif
75 static bool procline(struct parsec *pc);
76 static bool printline(struct parsec *pc, int sep, size_t *last_out);
77 static void printline_metadata(struct str *line, int sep);
78 
79 bool
file_matching(const char * fname)80 file_matching(const char *fname)
81 {
82 	char *fname_base, *fname_buf;
83 	bool ret;
84 
85 	ret = finclude ? false : true;
86 	fname_buf = strdup(fname);
87 	if (fname_buf == NULL)
88 		err(2, "strdup");
89 	fname_base = basename(fname_buf);
90 
91 	for (unsigned int i = 0; i < fpatterns; ++i) {
92 		if (fnmatch(fpattern[i].pat, fname, 0) == 0 ||
93 		    fnmatch(fpattern[i].pat, fname_base, 0) == 0)
94 			/*
95 			 * The last pattern matched wins exclusion/inclusion
96 			 * rights, so we can't reasonably bail out early here.
97 			 */
98 			ret = (fpattern[i].mode != EXCL_PAT);
99 	}
100 	free(fname_buf);
101 	return (ret);
102 }
103 
104 static inline bool
dir_matching(const char * dname)105 dir_matching(const char *dname)
106 {
107 	bool ret;
108 
109 	ret = dinclude ? false : true;
110 
111 	for (unsigned int i = 0; i < dpatterns; ++i) {
112 		if (dname != NULL && fnmatch(dpattern[i].pat, dname, 0) == 0)
113 			/*
114 			 * The last pattern matched wins exclusion/inclusion
115 			 * rights, so we can't reasonably bail out early here.
116 			 */
117 			ret = (dpattern[i].mode != EXCL_PAT);
118 	}
119 	return (ret);
120 }
121 
122 /*
123  * Processes a directory when a recursive search is performed with
124  * the -R option.  Each appropriate file is passed to procfile().
125  */
126 bool
grep_tree(char ** argv)127 grep_tree(char **argv)
128 {
129 	FTS *fts;
130 	FTSENT *p;
131 	int fts_flags;
132 	bool matched, ok;
133 	const char *wd[] = { ".", NULL };
134 
135 	matched = false;
136 
137 	/* This switch effectively initializes 'fts_flags' */
138 	switch(linkbehave) {
139 	case LINK_EXPLICIT:
140 		fts_flags = FTS_COMFOLLOW | FTS_PHYSICAL;
141 		break;
142 	case LINK_SKIP:
143 		fts_flags = FTS_PHYSICAL;
144 		break;
145 	default:
146 		fts_flags = FTS_LOGICAL | FTS_NOSTAT;
147 	}
148 
149 	fts_flags |= FTS_NOCHDIR;
150 
151 	fts = fts_open((argv[0] == NULL) ?
152 	    __DECONST(char * const *, wd) : argv, fts_flags, NULL);
153 	if (fts == NULL)
154 		err(2, "fts_open");
155 	while (errno = 0, (p = fts_read(fts)) != NULL) {
156 		switch (p->fts_info) {
157 		case FTS_DNR:
158 		case FTS_ERR:
159 		case FTS_NS:
160 			file_err = true;
161 			if(!sflag)
162 				warnc(p->fts_errno, "%s", p->fts_path);
163 			break;
164 		case FTS_D:
165 			if (dexclude || dinclude)
166 				if (!dir_matching(p->fts_name) ||
167 				    !dir_matching(p->fts_path))
168 					fts_set(fts, p, FTS_SKIP);
169 			break;
170 		case FTS_DC:
171 			/* Print a warning for recursive directory loop */
172 			warnx("warning: %s: recursive directory loop",
173 			    p->fts_path);
174 			break;
175 		case FTS_DP:
176 			break;
177 		case FTS_SL:
178 			/*
179 			 * Skip symlinks for LINK_EXPLICIT and
180 			 * LINK_SKIP.  Note that due to FTS_COMFOLLOW,
181 			 * symlinks on the command line are followed
182 			 * for LINK_EXPLICIT and not reported as
183 			 * symlinks.
184 			 */
185 			break;
186 		default:
187 			/* Check for file exclusion/inclusion */
188 			ok = true;
189 			if (fexclude || finclude)
190 				ok &= file_matching(p->fts_path);
191 
192 			if (ok && procfile(p->fts_path))
193 				matched = true;
194 			break;
195 		}
196 	}
197 	if (errno != 0)
198 		err(2, "fts_read");
199 
200 	fts_close(fts);
201 	return (matched);
202 }
203 
204 static void
procmatch_match(struct mprintc * mc,struct parsec * pc)205 procmatch_match(struct mprintc *mc, struct parsec *pc)
206 {
207 
208 	if (mc->doctx) {
209 		if (!first_match && (!mc->same_file || mc->last_outed > 0))
210 			printf("--\n");
211 		if (Bflag > 0)
212 			printqueue();
213 		mc->tail = Aflag;
214 	}
215 
216 	/* Print the matching line, but only if not quiet/binary */
217 	if (mc->printmatch) {
218 		size_t last_out;
219 		bool terminated;
220 
221 		last_out = 0;
222 		terminated = printline(pc, ':', &last_out);
223 		while (pc->matchidx >= MAX_MATCHES) {
224 			/* Reset matchidx and try again */
225 			pc->matchidx = 0;
226 			if (procline(pc) == !vflag)
227 				terminated = printline(pc, ':', &last_out);
228 			else
229 				break;
230 		}
231 
232 		/*
233 		 * The above loop processes the entire line as long as we keep
234 		 * hitting the maximum match count.  At this point, we know
235 		 * that there's nothing left to be printed and can terminate the
236 		 * line.
237 		 */
238 		if (!terminated)
239 			printline(pc, ':', &last_out);
240 
241 		first_match = false;
242 		mc->same_file = true;
243 		mc->last_outed = 0;
244 	}
245 }
246 
247 static void
procmatch_nomatch(struct mprintc * mc,struct parsec * pc)248 procmatch_nomatch(struct mprintc *mc, struct parsec *pc)
249 {
250 
251 	/* Deal with any -A context as needed */
252 	if (mc->tail > 0) {
253 		grep_printline(&pc->ln, '-');
254 		mc->tail--;
255 		if (Bflag > 0)
256 			clearqueue();
257 	} else if (Bflag == 0 || (Bflag > 0 && enqueue(&pc->ln)))
258 		/*
259 		 * Enqueue non-matching lines for -B context. If we're not
260 		 * actually doing -B context or if the enqueue resulted in a
261 		 * line being rotated out, then go ahead and increment
262 		 * last_outed to signify a gap between context/match.
263 		 */
264 		++mc->last_outed;
265 }
266 
267 /*
268  * Process any matches in the current parsing context, return a boolean
269  * indicating whether we should halt any further processing or not. 'true' to
270  * continue processing, 'false' to halt.
271  */
272 static bool
procmatches(struct mprintc * mc,struct parsec * pc,bool matched)273 procmatches(struct mprintc *mc, struct parsec *pc, bool matched)
274 {
275 
276 	if (mflag && mcount <= 0) {
277 		/*
278 		 * We already hit our match count, but we need to keep dumping
279 		 * lines until we've lost our tail.
280 		 */
281 		grep_printline(&pc->ln, '-');
282 		mc->tail--;
283 		return (mc->tail != 0);
284 	}
285 
286 	/*
287 	 * XXX TODO: This should loop over pc->matches and handle things on a
288 	 * line-by-line basis, setting up a `struct str` as needed.
289 	 */
290 	/* Deal with any -B context or context separators */
291 	if (matched) {
292 		procmatch_match(mc, pc);
293 
294 		/* Count the matches if we have a match limit */
295 		if (mflag) {
296 			/* XXX TODO: Decrement by number of matched lines */
297 			mcount -= 1;
298 			if (mcount <= 0)
299 				return (mc->tail != 0);
300 		}
301 	} else if (mc->doctx)
302 		procmatch_nomatch(mc, pc);
303 
304 	return (true);
305 }
306 
307 /*
308  * Opens a file and processes it.  Each file is processed line-by-line
309  * passing the lines to procline().
310  */
311 bool
procfile(const char * fn)312 procfile(const char *fn)
313 {
314 	struct parsec pc;
315 	struct mprintc mc;
316 	struct file *f;
317 	struct stat sb;
318 	mode_t s;
319 	int lines;
320 	bool line_matched;
321 
322 	if (strcmp(fn, "-") == 0) {
323 		fn = label != NULL ? label : errstr[1];
324 		f = grep_open(NULL);
325 	} else {
326 		if (stat(fn, &sb) == 0) {
327 			/* Check if we need to process the file */
328 			s = sb.st_mode & S_IFMT;
329 			if (dirbehave == DIR_SKIP && s == S_IFDIR)
330 				return (false);
331 			if (devbehave == DEV_SKIP && (s == S_IFIFO ||
332 			    s == S_IFCHR || s == S_IFBLK || s == S_IFSOCK))
333 				return (false);
334 		}
335 		f = grep_open(fn);
336 	}
337 	if (f == NULL) {
338 		file_err = true;
339 		if (!sflag)
340 			warn("%s", fn);
341 		return (false);
342 	}
343 
344 	pc.ln.file = grep_strdup(fn);
345 	pc.ln.line_no = 0;
346 	pc.ln.len = 0;
347 	pc.ln.boff = 0;
348 	pc.ln.off = -1;
349 	pc.binary = f->binary;
350 	pc.cntlines = false;
351 	memset(&mc, 0, sizeof(mc));
352 	mc.printmatch = true;
353 	if ((pc.binary && binbehave == BINFILE_BIN) || cflag || qflag ||
354 	    lflag || Lflag)
355 		mc.printmatch = false;
356 	if (mc.printmatch && (Aflag != 0 || Bflag != 0))
357 		mc.doctx = true;
358 	if (mc.printmatch && (Aflag != 0 || Bflag != 0 || mflag || nflag))
359 		pc.cntlines = true;
360 	mcount = mlimit;
361 
362 	for (lines = 0; lines == 0 || !(lflag || qflag); ) {
363 		/*
364 		 * XXX TODO: We need to revisit this in a chunking world. We're
365 		 * not going to be doing per-line statistics because of the
366 		 * overhead involved. procmatches can figure that stuff out as
367 		 * needed. */
368 		/* Reset per-line statistics */
369 		pc.printed = 0;
370 		pc.matchidx = 0;
371 		pc.lnstart = 0;
372 		pc.ln.boff = 0;
373 		pc.ln.off += pc.ln.len + 1;
374 		/* XXX TODO: Grab a chunk */
375 		if ((pc.ln.dat = grep_fgetln(f, &pc)) == NULL ||
376 		    pc.ln.len == 0)
377 			break;
378 
379 		if (pc.ln.len > 0 && pc.ln.dat[pc.ln.len - 1] == fileeol)
380 			--pc.ln.len;
381 		pc.ln.line_no++;
382 
383 		/* Return if we need to skip a binary file */
384 		if (pc.binary && binbehave == BINFILE_SKIP) {
385 			grep_close(f);
386 			free(pc.ln.file);
387 			free(f);
388 			return (0);
389 		}
390 
391 		if (mflag && mcount <= 0) {
392 			/*
393 			 * Short-circuit, already hit match count and now we're
394 			 * just picking up any remaining pieces.
395 			 */
396 			if (!procmatches(&mc, &pc, false))
397 				break;
398 			continue;
399 		}
400 		line_matched = procline(&pc) == !vflag;
401 		if (line_matched)
402 			++lines;
403 
404 		/* Halt processing if we hit our match limit */
405 		if (!procmatches(&mc, &pc, line_matched))
406 			break;
407 	}
408 	if (Bflag > 0)
409 		clearqueue();
410 	grep_close(f);
411 
412 	if (cflag && !qflag) {
413 		if (!hflag)
414 			printf("%s:", pc.ln.file);
415 		printf("%u\n", lines);
416 	}
417 	if (lflag && !qflag && lines != 0)
418 		printf("%s%c", fn, nullflag ? 0 : '\n');
419 	if (Lflag && !qflag && lines == 0)
420 		printf("%s%c", fn, nullflag ? 0 : '\n');
421 	if (lines != 0 && !cflag && !lflag && !Lflag &&
422 	    binbehave == BINFILE_BIN && f->binary && !qflag)
423 		printf(errstr[7], fn);
424 
425 	free(pc.ln.file);
426 	free(f);
427 	return (lines != 0);
428 }
429 
430 #ifdef WITH_INTERNAL_NOSPEC
431 /*
432  * Internal implementation of literal string search within a string, modeled
433  * after regexec(3), for use when the regex(3) implementation doesn't offer
434  * either REG_NOSPEC or REG_LITERAL. This does not apply in the default FreeBSD
435  * config, but in other scenarios such as building against libgnuregex or on
436  * some non-FreeBSD OSes.
437  */
438 static int
litexec(const struct pat * pat,const char * string,size_t nmatch,regmatch_t pmatch[])439 litexec(const struct pat *pat, const char *string, size_t nmatch,
440     regmatch_t pmatch[])
441 {
442 	char *(*strstr_fn)(const char *, const char *);
443 	char *sub, *subject;
444 	const char *search;
445 	size_t idx, n, ofs, stringlen;
446 
447 	if (cflags & REG_ICASE)
448 		strstr_fn = strcasestr;
449 	else
450 		strstr_fn = strstr;
451 	idx = 0;
452 	ofs = pmatch[0].rm_so;
453 	stringlen = pmatch[0].rm_eo;
454 	if (ofs >= stringlen)
455 		return (REG_NOMATCH);
456 	subject = strndup(string, stringlen);
457 	if (subject == NULL)
458 		return (REG_ESPACE);
459 	for (n = 0; ofs < stringlen;) {
460 		search = (subject + ofs);
461 		if ((unsigned long)pat->len > strlen(search))
462 			break;
463 		sub = strstr_fn(search, pat->pat);
464 		/*
465 		 * Ignoring the empty string possibility due to context: grep optimizes
466 		 * for empty patterns and will never reach this point.
467 		 */
468 		if (sub == NULL)
469 			break;
470 		++n;
471 		/* Fill in pmatch if necessary */
472 		if (nmatch > 0) {
473 			pmatch[idx].rm_so = ofs + (sub - search);
474 			pmatch[idx].rm_eo = pmatch[idx].rm_so + pat->len;
475 			if (++idx == nmatch)
476 				break;
477 			ofs = pmatch[idx].rm_so + 1;
478 		} else
479 			/* We only needed to know if we match or not */
480 			break;
481 	}
482 	free(subject);
483 	if (n > 0 && nmatch > 0)
484 		for (n = idx; n < nmatch; ++n)
485 			pmatch[n].rm_so = pmatch[n].rm_eo = -1;
486 
487 	return (n > 0 ? 0 : REG_NOMATCH);
488 }
489 #endif /* WITH_INTERNAL_NOSPEC */
490 
491 #define iswword(x)	(iswalnum((x)) || (x) == L'_')
492 
493 /*
494  * Check if the byte at the given offset in the line is a word character
495  * (alphanumeric or _).  Handles ASCII fast path, UTF-8 continuation bytes,
496  * and multi-byte decoding via mbrtowc(3).
497  */
498 static bool
iswordchar(const char * dat,size_t len,size_t offset)499 iswordchar(const char *dat, size_t len, size_t offset)
500 {
501 	unsigned char ch;
502 	mbstate_t mbstate;
503 	wchar_t wc;
504 	size_t n;
505 
506 	if (offset >= len)
507 		return (false);
508 
509 	ch = (unsigned char)dat[offset];
510 	if (ch < 0x80)
511 		return (isalnum(ch) || ch == '_');
512 	if ((ch & 0xC0) == 0x80)
513 		/* Continuation byte: part of a word */
514 		return (true);
515 
516 	/* Multi-byte start byte: decode with mbrtowc */
517 	memset(&mbstate, 0, sizeof(mbstate));
518 	n = mbrtowc(&wc, &dat[offset], MB_CUR_MAX, &mbstate);
519 	return (n == (size_t)-1 || n == (size_t)-2 || iswword(wc));
520 }
521 
522 /*
523  * Processes a line comparing it with the specified patterns.  Each pattern
524  * is looped to be compared along with the full string, saving each and every
525  * match, which is necessary to colorize the output and to count the
526  * matches.  The matching lines are passed to printline() to display the
527  * appropriate output.
528  */
529 static bool
procline(struct parsec * pc)530 procline(struct parsec *pc)
531 {
532 	regmatch_t pmatch, lastmatch, chkmatch;
533 	size_t st, nst;
534 	unsigned int i;
535 	int r = 0, leflags = eflags;
536 	size_t startm = 0, matchidx;
537 	unsigned int retry;
538 	bool lastmatched, matched;
539 
540 	matchidx = pc->matchidx;
541 
542 	/* Null pattern shortcuts. */
543 	if (matchall) {
544 		if (xflag && pc->ln.len == 0) {
545 			/* Matches empty lines (-x). */
546 			return (true);
547 		} else if (!wflag && !xflag) {
548 			/* Matches every line (no -w or -x). */
549 			return (true);
550 		}
551 
552 		/*
553 		 * If we only have the NULL pattern, whether we match or not
554 		 * depends on if we got here with -w or -x.  If either is set,
555 		 * the answer is no.  If we have other patterns, we'll defer
556 		 * to them.
557 		 */
558 		if (patterns == 0) {
559 			return (!(wflag || xflag));
560 		}
561 	} else if (patterns == 0) {
562 		/* Pattern file with no patterns. */
563 		return (false);
564 	}
565 
566 	matched = false;
567 	st = pc->lnstart;
568 	nst = 0;
569 	/* Initialize to avoid a false positive warning from GCC. */
570 	lastmatch.rm_so = lastmatch.rm_eo = 0;
571 
572 	/* Loop to process the whole line */
573 	while (st <= pc->ln.len) {
574 		lastmatched = false;
575 		startm = matchidx;
576 		retry = 0;
577 		if (st > 0 && pc->ln.dat[st - 1] != fileeol)
578 			leflags |= REG_NOTBOL;
579 		/* Loop to compare with all the patterns */
580 		for (i = 0; i < patterns; i++) {
581 			pmatch.rm_so = st;
582 			pmatch.rm_eo = pc->ln.len;
583 #ifdef WITH_INTERNAL_NOSPEC
584 			if (grepbehave == GREP_FIXED)
585 				r = litexec(&pattern[i], pc->ln.dat, 1, &pmatch);
586 			else
587 #endif
588 			r = regexec(&r_pattern[i], pc->ln.dat, 1, &pmatch,
589 			    leflags);
590 			if (r != 0)
591 				continue;
592 			/* Check for full match */
593 			if (xflag && (pmatch.rm_so != 0 ||
594 			    (size_t)pmatch.rm_eo != pc->ln.len))
595 				continue;
596 			/* Check for whole word match */
597 			if (wflag) {
598 				if (pmatch.rm_so != 0 &&
599 				    iswordchar(pc->ln.dat, pc->ln.len,
600 				    pmatch.rm_so - 1))
601 					r = REG_NOMATCH;
602 				if (r == 0 && (size_t)pmatch.rm_eo !=
603 				    pc->ln.len &&
604 				    iswordchar(pc->ln.dat, pc->ln.len,
605 				    pmatch.rm_eo))
606 					r = REG_NOMATCH;
607 				/*
608 				 * If we're doing whole word matching and we
609 				 * matched once, then we should try the pattern
610 				 * again after advancing just past the start of
611 				 * the earliest match. This allows the pattern
612 				 * to  match later on in the line and possibly
613 				 * still match a whole word.
614 				 */
615 				if (r == REG_NOMATCH &&
616 				    (retry == pc->lnstart ||
617 				    (unsigned int)pmatch.rm_so + 1 < retry))
618 					retry = pmatch.rm_so + 1;
619 				if (r == REG_NOMATCH)
620 					continue;
621 			}
622 			lastmatched = true;
623 			lastmatch = pmatch;
624 
625 			if (matchidx == 0)
626 				matched = true;
627 
628 			/*
629 			 * Replace previous match if the new one is earlier
630 			 * and/or longer. This will lead to some amount of
631 			 * extra work if -o/--color are specified, but it's
632 			 * worth it from a correctness point of view.
633 			 */
634 			if (matchidx > startm) {
635 				chkmatch = pc->matches[matchidx - 1];
636 				if (pmatch.rm_so < chkmatch.rm_so ||
637 				    (pmatch.rm_so == chkmatch.rm_so &&
638 				    (pmatch.rm_eo - pmatch.rm_so) >
639 				    (chkmatch.rm_eo - chkmatch.rm_so))) {
640 					pc->matches[matchidx - 1] = pmatch;
641 					nst = pmatch.rm_eo;
642 				}
643 			} else {
644 				/* Advance as normal if not */
645 				pc->matches[matchidx++] = pmatch;
646 				nst = pmatch.rm_eo;
647 			}
648 			/* avoid excessive matching - skip further patterns */
649 			if ((color == NULL && !oflag) || qflag || lflag ||
650 			    matchidx >= MAX_MATCHES) {
651 				pc->lnstart = nst;
652 				lastmatched = false;
653 				break;
654 			}
655 		}
656 
657 		/*
658 		 * Advance to just past the start of the earliest match, try
659 		 * again just in case we still have a chance to match later in
660 		 * the string.
661 		 */
662 		if (!lastmatched && retry > pc->lnstart) {
663 			st = retry;
664 			continue;
665 		}
666 
667 		/* XXX TODO: We will need to keep going, since we're chunky */
668 		/* One pass if we are not recording matches */
669 		if (!wflag && ((color == NULL && !oflag) || qflag || lflag || Lflag))
670 			break;
671 
672 		/* If we didn't have any matches or REG_NOSUB set */
673 		if (!lastmatched || (cflags & REG_NOSUB))
674 			nst = pc->ln.len;
675 
676 		if (!lastmatched)
677 			/* No matches */
678 			break;
679 		else if (st == nst && lastmatch.rm_so == lastmatch.rm_eo)
680 			/* Zero-length match -- advance one more so we don't get stuck */
681 			nst++;
682 
683 		/* Advance st based on previous matches */
684 		st = nst;
685 		pc->lnstart = st;
686 	}
687 
688 	/* Reflect the new matchidx in the context */
689 	pc->matchidx = matchidx;
690 	return matched;
691 }
692 
693 /*
694  * Safe malloc() for internal use.
695  */
696 void *
grep_malloc(size_t size)697 grep_malloc(size_t size)
698 {
699 	void *ptr;
700 
701 	if (size == 0)
702 		return (NULL);
703 	if ((ptr = malloc(size)) == NULL)
704 		err(2, "malloc");
705 	return (ptr);
706 }
707 
708 /*
709  * Safe calloc() for internal use.
710  */
711 void *
grep_calloc(size_t nmemb,size_t size)712 grep_calloc(size_t nmemb, size_t size)
713 {
714 	void *ptr;
715 
716 	if (nmemb == 0 || size == 0)
717 		return (NULL);
718 	if ((ptr = calloc(nmemb, size)) == NULL)
719 		err(2, "calloc");
720 	return (ptr);
721 }
722 
723 /*
724  * Safe realloc() for internal use.
725  */
726 void *
grep_realloc(void * ptr,size_t size)727 grep_realloc(void *ptr, size_t size)
728 {
729 
730 	if ((ptr = realloc(ptr, size)) == NULL)
731 		err(2, "realloc");
732 	return (ptr);
733 }
734 
735 /*
736  * Safe strdup() for internal use.
737  */
738 char *
grep_strdup(const char * str)739 grep_strdup(const char *str)
740 {
741 	char *ret;
742 
743 	if ((ret = strdup(str)) == NULL)
744 		err(2, "strdup");
745 	return (ret);
746 }
747 
748 /*
749  * Print an entire line as-is, there are no inline matches to consider. This is
750  * used for printing context.
751  */
752 static struct timespec printline_last_flush = { 0, 0 };
753 
754 static void
flush_if_stalled(void)755 flush_if_stalled(void)
756 {
757 	struct timespec now;
758 
759 	if (lbflag && fileeol == '\n')
760 		return;
761 
762 	clock_gettime(CLOCK_MONOTONIC, &now);
763 	if (now.tv_sec > printline_last_flush.tv_sec ||
764 	    (now.tv_sec == printline_last_flush.tv_sec &&
765 	    now.tv_nsec - printline_last_flush.tv_nsec > 100000000)) {
766 		fflush(stdout);
767 		printline_last_flush = now;
768 	}
769 }
770 
771 void
grep_printline(struct str * line,int sep)772 grep_printline(struct str *line, int sep)
773 {
774 	printline_metadata(line, sep);
775 	fwrite(line->dat, line->len, 1, stdout);
776 	putchar(fileeol);
777 
778 	if (lbflag)
779 		fflush(stdout);
780 	else
781 		flush_if_stalled();
782 }
783 
784 static void
printline_metadata(struct str * line,int sep)785 printline_metadata(struct str *line, int sep)
786 {
787 	bool printsep;
788 
789 	printsep = false;
790 	if (!hflag) {
791 		if (!nullflag) {
792 			fputs(line->file, stdout);
793 			printsep = true;
794 		} else {
795 			printf("%s", line->file);
796 			putchar(0);
797 		}
798 	}
799 	if (nflag) {
800 		if (printsep)
801 			putchar(sep);
802 		printf("%d", line->line_no);
803 		printsep = true;
804 	}
805 	if (bflag) {
806 		if (printsep)
807 			putchar(sep);
808 		printf("%lld", (long long)(line->off + line->boff));
809 		printsep = true;
810 	}
811 	if (printsep)
812 		putchar(sep);
813 }
814 
815 /*
816  * Prints a matching line according to the command line options.  We need
817  * *last_out to be populated on entry in case this is just a continuation of
818  * matches within the same line.
819  *
820  * Returns true if the line was terminated, false if it was not.
821  */
822 static bool
printline(struct parsec * pc,int sep,size_t * last_out)823 printline(struct parsec *pc, int sep, size_t *last_out)
824 {
825 	size_t a = *last_out;
826 	size_t i, matchidx;
827 	regmatch_t match;
828 	bool terminated;
829 
830 	/*
831 	 * Nearly all paths below will terminate the line by default, but it is
832 	 * avoided in some circumstances in case we don't have the full context
833 	 * available here.
834 	 */
835 	terminated = true;
836 
837 	/* If matchall, everything matches but don't actually print for -o */
838 	if (oflag && matchall)
839 		return (terminated);
840 
841 	matchidx = pc->matchidx;
842 
843 	/* --color and -o */
844 	if ((oflag || color) && (pc->printed > 0 || matchidx > 0)) {
845 		/* Only print metadata once per line if --color */
846 		if (!oflag && pc->printed == 0) {
847 			printline_metadata(&pc->ln, sep);
848 		}
849 		for (i = 0; i < matchidx; i++) {
850 			match = pc->matches[i];
851 			/* Don't output zero length matches */
852 			if (match.rm_so == match.rm_eo)
853 				continue;
854 			/*
855 			 * Metadata is printed on a per-line basis, so every
856 			 * match gets file metadata with the -o flag.
857 			 */
858 			if (oflag) {
859 				pc->ln.boff = match.rm_so;
860 				printline_metadata(&pc->ln, sep);
861 			} else {
862 				fwrite(pc->ln.dat + a, match.rm_so - a, 1,
863 				    stdout);
864 			}
865 			if (color)
866 				fprintf(stdout, "\33[%sm\33[K", color);
867 			fwrite(pc->ln.dat + match.rm_so,
868 			    match.rm_eo - match.rm_so, 1, stdout);
869 			if (color)
870 				fprintf(stdout, "\33[m\33[K");
871 			a = match.rm_eo;
872 			if (oflag)
873 				putchar('\n');
874 		}
875 
876 		/*
877 		 * Don't terminate if we reached the match limit; we may have
878 		 * other matches on this line to process.
879 		 */
880 		*last_out = a;
881 		if (!oflag && matchidx != MAX_MATCHES) {
882 			if (pc->ln.len - a > 0) {
883 				fwrite(pc->ln.dat + a, pc->ln.len - a, 1,
884 				    stdout);
885 				*last_out = pc->ln.len;
886 			}
887 			putchar('\n');
888 			flush_if_stalled();
889 		} else if (!oflag) {
890 			/*
891 			 * -o is terminated on every match output, so this
892 			 * branch is only designed to capture MAX_MATCHES in a
893 			 * line which may be a signal to us for a lack of
894 			 * context.  The caller will know more and call us again
895 			 * to terminate if it needs to.
896 			 */
897 			terminated = false;
898 		} else {
899 			flush_if_stalled();
900 		}
901 	} else
902 		grep_printline(&pc->ln, sep);
903 	pc->printed++;
904 	return (terminated);
905 }
906