aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2018-04-20 03:08:46 +0000
committerKyle Evans <kevans@FreeBSD.org>2018-04-20 03:08:46 +0000
commit81c634e8d5a7af19642396fcf91c3194ee857180 (patch)
tree79928201260a51eda07621faf1c2c7789b12c4e2
parent0873080489e8dca06c4f26b2d9f0345eccbd5d75 (diff)
downloadsrc-81c634e8d5a7af19642396fcf91c3194ee857180.tar.gz
src-81c634e8d5a7af19642396fcf91c3194ee857180.zip
Notes
-rw-r--r--usr.bin/grep/util.c152
1 files changed, 87 insertions, 65 deletions
diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c
index 6fd841c34607..0bb6d1c71588 100644
--- a/usr.bin/grep/util.c
+++ b/usr.bin/grep/util.c
@@ -72,6 +72,18 @@ struct parsec {
bool binary; /* Binary file? */
};
+/*
+ * Match printing context
+ */
+struct mprintc {
+ long long tail; /* Number of trailing lines to record */
+ int last_outed; /* Number of lines since last output */
+ bool doctx; /* Printing context? */
+ bool printmatch; /* Printing matches? */
+ bool same_file; /* Same file as previously printed? */
+};
+
+static bool procmatches(struct mprintc *mc, struct parsec *pc, bool matched);
#ifdef WITH_INTERNAL_NOSPEC
static int litexec(const struct pat *pat, const char *string,
size_t nmatch, regmatch_t pmatch[]);
@@ -197,6 +209,71 @@ grep_tree(char **argv)
}
/*
+ * Process any matches in the current parsing context, return a boolean
+ * indicating whether we should halt any further processing or not. 'true' to
+ * continue processing, 'false' to halt.
+ */
+static bool
+procmatches(struct mprintc *mc, struct parsec *pc, bool matched)
+{
+
+ /* Deal with any -B context or context separators */
+ if (matched && mc->doctx) {
+ if (!first_match && (!mc->same_file || mc->last_outed > 0))
+ printf("--\n");
+ if (Bflag > 0)
+ printqueue();
+ mc->tail = Aflag;
+ }
+
+ /* Print the matching line, but only if not quiet/binary */
+ if (matched && mc->printmatch) {
+ printline(pc, ':');
+ while (pc->matchidx >= MAX_MATCHES) {
+ /* Reset matchidx and try again */
+ pc->matchidx = 0;
+ if (procline(pc) == 0)
+ printline(pc, ':');
+ else
+ break;
+ }
+ first_match = false;
+ mc->same_file = true;
+ mc->last_outed = 0;
+ }
+
+ if (!matched && mc->doctx) {
+ /* Deal with any -A context */
+ if (mc->tail > 0) {
+ grep_printline(&pc->ln, '-');
+ mc->tail--;
+ if (Bflag > 0)
+ clearqueue();
+ } else {
+ /*
+ * Enqueue non-matching lines for -B context.
+ * If we're not actually doing -B context or if
+ * the enqueue resulted in a line being rotated
+ * out, then go ahead and increment last_outed
+ * to signify a gap between context/match.
+ */
+ if (Bflag == 0 || (Bflag > 0 && enqueue(&pc->ln)))
+ ++mc->last_outed;
+ }
+ }
+
+ /* Count the matches if we have a match limit */
+ if (matched && mflag) {
+ /* XXX TODO: Decrement by number of matched lines */
+ mcount -= 1;
+ if (mflag && mcount <= 0)
+ return (false);
+ }
+
+ return (true);
+}
+
+/*
* Opens a file and processes it. Each file is processed line-by-line
* passing the lines to procline().
*/
@@ -204,13 +281,11 @@ int
procfile(const char *fn)
{
struct parsec pc;
- long long tail;
+ struct mprintc mc;
struct file *f;
struct stat sb;
- struct str *ln;
mode_t s;
- int c, last_outed, t;
- bool doctx, printmatch, same_file;
+ int c, t;
if (strcmp(fn, "-") == 0) {
fn = label != NULL ? label : getstr(1);
@@ -234,8 +309,6 @@ procfile(const char *fn)
return (0);
}
- /* Convenience */
- ln = &pc.ln;
pc.ln.file = grep_malloc(strlen(fn) + 1);
strcpy(pc.ln.file, fn);
pc.ln.line_no = 0;
@@ -243,17 +316,13 @@ procfile(const char *fn)
pc.ln.boff = 0;
pc.ln.off = -1;
pc.binary = f->binary;
- pc.printed = 0;
- tail = 0;
- last_outed = 0;
- same_file = false;
- doctx = false;
- printmatch = true;
+ memset(&mc, 0, sizeof(mc));
+ mc.printmatch = true;
if ((pc.binary && binbehave == BINFILE_BIN) || cflag || qflag ||
lflag || Lflag)
- printmatch = false;
- if (printmatch && (Aflag != 0 || Bflag != 0))
- doctx = true;
+ mc.printmatch = false;
+ if (mc.printmatch && (Aflag != 0 || Bflag != 0))
+ mc.doctx = true;
mcount = mlimit;
for (c = 0; c == 0 || !(lflag || qflag); ) {
@@ -282,56 +351,9 @@ procfile(const char *fn)
if ((t = procline(&pc)) == 0)
++c;
- /* Deal with any -B context or context separators */
- if (t == 0 && doctx) {
- if (!first_match && (!same_file || last_outed > 0))
- printf("--\n");
- if (Bflag > 0)
- printqueue();
- tail = Aflag;
- }
- /* Print the matching line, but only if not quiet/binary */
- if (t == 0 && printmatch) {
- printline(&pc, ':');
- while (pc.matchidx >= MAX_MATCHES) {
- /* Reset matchidx and try again */
- pc.matchidx = 0;
- if (procline(&pc) == 0)
- printline(&pc, ':');
- else
- break;
- }
- first_match = false;
- same_file = true;
- last_outed = 0;
- }
- if (t != 0 && doctx) {
- /* Deal with any -A context */
- if (tail > 0) {
- grep_printline(&pc.ln, '-');
- tail--;
- if (Bflag > 0)
- clearqueue();
- } else {
- /*
- * Enqueue non-matching lines for -B context.
- * If we're not actually doing -B context or if
- * the enqueue resulted in a line being rotated
- * out, then go ahead and increment last_outed
- * to signify a gap between context/match.
- */
- if (Bflag == 0 || (Bflag > 0 && enqueue(ln)))
- ++last_outed;
- }
- }
-
- /* Count the matches if we have a match limit */
- if (t == 0 && mflag) {
- --mcount;
- if (mflag && mcount <= 0)
- break;
- }
-
+ /* Halt processing if we hit our match limit */
+ if (!procmatches(&mc, &pc, t == 0))
+ break;
}
if (Bflag > 0)
clearqueue();