bsdgrep(1): Slooowly peel away the chunky onion

(or peel off the band-aid, whatever floats your boat)

This addresses two separate issues:

1.) Nothing within bsdgrep actually knew whether it cared about line numbers
  or not.

2.) The file layer knew nothing about the context in which it was being
  called.

#1 is only important when we're *not* processing line-by-line. #2 is
debatably a good idea; the parsing context is only handy because that's
where we store current offset information and, as of this commit, whether or
not it needs to be line-aware.
This commit is contained in:
Kyle Evans 2018-06-08 01:25:07 +00:00
parent c9ca1a70cc
commit bd60b9b499
3 changed files with 27 additions and 23 deletions

View File

@ -95,7 +95,7 @@ grep_lnbufgrow(size_t newlen)
} }
char * char *
grep_fgetln(struct file *f, size_t *lenp) grep_fgetln(struct file *f, struct parsec *pc)
{ {
unsigned char *p; unsigned char *p;
char *ret; char *ret;
@ -109,18 +109,18 @@ grep_fgetln(struct file *f, size_t *lenp)
if (bufrem == 0) { if (bufrem == 0) {
/* Return zero length to indicate EOF */ /* Return zero length to indicate EOF */
*lenp = 0; pc->ln.len= 0;
return (bufpos); return (bufpos);
} }
/* Look for a newline in the remaining part of the buffer */ /* Look for a newline in the remaining part of the [6rbuffer */
if ((p = memchr(bufpos, fileeol, bufrem)) != NULL) { if ((p = memchr(bufpos, fileeol, bufrem)) != NULL) {
++p; /* advance over newline */ ++p; /* advance over newline */
ret = bufpos; ret = bufpos;
len = p - bufpos; len = p - bufpos;
bufrem -= len; bufrem -= len;
bufpos = p; bufpos = p;
*lenp = len; pc->ln.len = len;
return (ret); return (ret);
} }
@ -155,11 +155,11 @@ grep_fgetln(struct file *f, size_t *lenp)
bufpos = p; bufpos = p;
break; break;
} }
*lenp = len; pc->ln.len = len;
return (lnbuf); return (lnbuf);
error: error:
*lenp = 0; pc->ln.len = 0;
return (NULL); return (NULL);
} }

View File

@ -97,6 +97,21 @@ struct epat {
int mode; int mode;
}; };
/*
* Parsing context; used to hold things like matches made and
* other useful bits
*/
struct parsec {
regmatch_t matches[MAX_MATCHES]; /* Matches made */
/* XXX TODO: This should be a chunk, not a line */
struct str ln; /* Current line */
size_t lnstart; /* Position in line */
size_t matchidx; /* Latest match index */
int printed; /* Metadata printed? */
bool binary; /* Binary file? */
bool cntlines; /* Count lines? */
};
/* Flags passed to regcomp() and regexec() */ /* Flags passed to regcomp() and regexec() */
extern int cflags, eflags; extern int cflags, eflags;
@ -141,4 +156,4 @@ void clearqueue(void);
/* file.c */ /* file.c */
void grep_close(struct file *f); void grep_close(struct file *f);
struct file *grep_open(const char *path); struct file *grep_open(const char *path);
char *grep_fgetln(struct file *f, size_t *len); char *grep_fgetln(struct file *f, struct parsec *pc);

View File

@ -56,20 +56,6 @@ __FBSDID("$FreeBSD$");
static bool first_match = true; static bool first_match = true;
/*
* Parsing context; used to hold things like matches made and
* other useful bits
*/
struct parsec {
regmatch_t matches[MAX_MATCHES]; /* Matches made */
/* XXX TODO: This should be a chunk, not a line */
struct str ln; /* Current line */
size_t lnstart; /* Position in line */
size_t matchidx; /* Latest match index */
int printed; /* Metadata printed? */
bool binary; /* Binary file? */
};
/* /*
* Match printing context * Match printing context
*/ */
@ -276,7 +262,7 @@ procmatches(struct mprintc *mc, struct parsec *pc, bool matched)
if (mflag) { if (mflag) {
/* XXX TODO: Decrement by number of matched lines */ /* XXX TODO: Decrement by number of matched lines */
mcount -= 1; mcount -= 1;
if (mflag && mcount <= 0) if (mcount <= 0)
return (false); return (false);
} }
} else if (mc->doctx) } else if (mc->doctx)
@ -327,6 +313,7 @@ procfile(const char *fn)
pc.ln.boff = 0; pc.ln.boff = 0;
pc.ln.off = -1; pc.ln.off = -1;
pc.binary = f->binary; pc.binary = f->binary;
pc.cntlines = false;
memset(&mc, 0, sizeof(mc)); memset(&mc, 0, sizeof(mc));
mc.printmatch = true; mc.printmatch = true;
if ((pc.binary && binbehave == BINFILE_BIN) || cflag || qflag || if ((pc.binary && binbehave == BINFILE_BIN) || cflag || qflag ||
@ -334,6 +321,8 @@ procfile(const char *fn)
mc.printmatch = false; mc.printmatch = false;
if (mc.printmatch && (Aflag != 0 || Bflag != 0)) if (mc.printmatch && (Aflag != 0 || Bflag != 0))
mc.doctx = true; mc.doctx = true;
if (mc.printmatch && (Aflag != 0 || Bflag != 0 || mflag || nflag))
pc.cntlines = true;
mcount = mlimit; mcount = mlimit;
for (lines = 0; lines == 0 || !(lflag || qflag); ) { for (lines = 0; lines == 0 || !(lflag || qflag); ) {
@ -349,7 +338,7 @@ procfile(const char *fn)
pc.ln.boff = 0; pc.ln.boff = 0;
pc.ln.off += pc.ln.len + 1; pc.ln.off += pc.ln.len + 1;
/* XXX TODO: Grab a chunk */ /* XXX TODO: Grab a chunk */
if ((pc.ln.dat = grep_fgetln(f, &pc.ln.len)) == NULL || if ((pc.ln.dat = grep_fgetln(f, &pc)) == NULL ||
pc.ln.len == 0) pc.ln.len == 0)
break; break;