static int diff_grep(mmfile_t *one, mmfile_t *two, struct diff_options *o, regex_t *regexp, kwset_t kws) { regmatch_t regmatch; struct diffgrep_cb ecbdata; xpparam_t xpp; xdemitconf_t xecfg; if (!one) return !regexec_buf(regexp, two->ptr, two->size, 1, ®match, 0); if (!two) return !regexec_buf(regexp, one->ptr, one->size, 1, ®match, 0); /* * We have both sides; need to run textual diff and see if * the pattern appears on added/deleted lines. */ memset(&xpp, 0, sizeof(xpp)); memset(&xecfg, 0, sizeof(xecfg)); ecbdata.regexp = regexp; ecbdata.hit = 0; xecfg.ctxlen = o->context; xecfg.interhunkctxlen = o->interhunkcontext; if (xdi_diff_outf(one, two, diffgrep_consume, &ecbdata, &xpp, &xecfg)) return 0; return ecbdata.hit; }
static int patmatch(struct grep_pat *p, char *line, char *eol, regmatch_t *match, int eflags) { int hit; if (p->fixed) hit = !fixmatch(p, line, eol, match); else if (p->pcre_regexp) hit = !pcrematch(p, line, eol, match, eflags); else hit = !regexec_buf(&p->regexp, line, eol - line, 1, match, eflags); return hit; }
static void diffgrep_consume(void *priv, char *line, unsigned long len) { struct diffgrep_cb *data = priv; regmatch_t regmatch; if (line[0] != '+' && line[0] != '-') return; if (data->hit) /* * NEEDSWORK: we should have a way to terminate the * caller early. */ return; data->hit = !regexec_buf(data->regexp, line + 1, len - 1, 1, ®match, 0); }
static unsigned int contains(mmfile_t *mf, regex_t *regexp, kwset_t kws) { unsigned int cnt; unsigned long sz; const char *data; sz = mf->size; data = mf->ptr; cnt = 0; if (regexp) { regmatch_t regmatch; int flags = 0; while (sz && *data && !regexec_buf(regexp, data, sz, 1, ®match, flags)) { flags |= REG_NOTBOL; data += regmatch.rm_eo; sz -= regmatch.rm_eo; if (sz && *data && regmatch.rm_so == regmatch.rm_eo) { data++; sz--; } cnt++; } } else { /* Classic exact string match */ while (sz) { struct kwsmatch kwsm; size_t offset = kwsexec(kws, data, sz, &kwsm); if (offset == -1) break; sz -= offset + kwsm.size[0]; data += offset + kwsm.size[0]; cnt++; } } return cnt; }
static long ff_regexp(const char *line, long len, char *buffer, long buffer_size, void *priv) { struct ff_regs *regs = priv; regmatch_t pmatch[2]; int i; int result; /* Exclude terminating newline (and cr) from matching */ if (len > 0 && line[len-1] == '\n') { if (len > 1 && line[len-2] == '\r') len -= 2; else len--; } for (i = 0; i < regs->nr; i++) { struct ff_reg *reg = regs->array + i; if (!regexec_buf(®->re, line, len, 2, pmatch, 0)) { if (reg->negate) return -1; break; } } if (regs->nr <= i) return -1; i = pmatch[1].rm_so >= 0 ? 1 : 0; line += pmatch[i].rm_so; result = pmatch[i].rm_eo - pmatch[i].rm_so; if (result > buffer_size) result = buffer_size; while (result > 0 && (isspace(line[result - 1]))) result--; memcpy(buffer, line, result); return result; }