grep.con commit Merge branch 'il/remote-updates' (16735ae)
   1#include "cache.h"
   2#include "grep.h"
   3#include "userdiff.h"
   4#include "xdiff-interface.h"
   5
   6void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
   7{
   8        struct grep_pat *p = xcalloc(1, sizeof(*p));
   9        p->pattern = pat;
  10        p->origin = "header";
  11        p->no = 0;
  12        p->token = GREP_PATTERN_HEAD;
  13        p->field = field;
  14        *opt->pattern_tail = p;
  15        opt->pattern_tail = &p->next;
  16        p->next = NULL;
  17}
  18
  19void append_grep_pattern(struct grep_opt *opt, const char *pat,
  20                         const char *origin, int no, enum grep_pat_token t)
  21{
  22        struct grep_pat *p = xcalloc(1, sizeof(*p));
  23        p->pattern = pat;
  24        p->origin = origin;
  25        p->no = no;
  26        p->token = t;
  27        *opt->pattern_tail = p;
  28        opt->pattern_tail = &p->next;
  29        p->next = NULL;
  30}
  31
  32static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
  33{
  34        int err;
  35
  36        p->word_regexp = opt->word_regexp;
  37        p->ignore_case = opt->ignore_case;
  38
  39        if (opt->fixed)
  40                p->fixed = 1;
  41        if (opt->regflags & REG_ICASE)
  42                p->fixed = 0;
  43        if (p->fixed)
  44                return;
  45
  46        err = regcomp(&p->regexp, p->pattern, opt->regflags);
  47        if (err) {
  48                char errbuf[1024];
  49                char where[1024];
  50                if (p->no)
  51                        sprintf(where, "In '%s' at %d, ",
  52                                p->origin, p->no);
  53                else if (p->origin)
  54                        sprintf(where, "%s, ", p->origin);
  55                else
  56                        where[0] = 0;
  57                regerror(err, &p->regexp, errbuf, 1024);
  58                regfree(&p->regexp);
  59                die("%s'%s': %s", where, p->pattern, errbuf);
  60        }
  61}
  62
  63static struct grep_expr *compile_pattern_or(struct grep_pat **);
  64static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
  65{
  66        struct grep_pat *p;
  67        struct grep_expr *x;
  68
  69        p = *list;
  70        if (!p)
  71                return NULL;
  72        switch (p->token) {
  73        case GREP_PATTERN: /* atom */
  74        case GREP_PATTERN_HEAD:
  75        case GREP_PATTERN_BODY:
  76                x = xcalloc(1, sizeof (struct grep_expr));
  77                x->node = GREP_NODE_ATOM;
  78                x->u.atom = p;
  79                *list = p->next;
  80                return x;
  81        case GREP_OPEN_PAREN:
  82                *list = p->next;
  83                x = compile_pattern_or(list);
  84                if (!*list || (*list)->token != GREP_CLOSE_PAREN)
  85                        die("unmatched parenthesis");
  86                *list = (*list)->next;
  87                return x;
  88        default:
  89                return NULL;
  90        }
  91}
  92
  93static struct grep_expr *compile_pattern_not(struct grep_pat **list)
  94{
  95        struct grep_pat *p;
  96        struct grep_expr *x;
  97
  98        p = *list;
  99        if (!p)
 100                return NULL;
 101        switch (p->token) {
 102        case GREP_NOT:
 103                if (!p->next)
 104                        die("--not not followed by pattern expression");
 105                *list = p->next;
 106                x = xcalloc(1, sizeof (struct grep_expr));
 107                x->node = GREP_NODE_NOT;
 108                x->u.unary = compile_pattern_not(list);
 109                if (!x->u.unary)
 110                        die("--not followed by non pattern expression");
 111                return x;
 112        default:
 113                return compile_pattern_atom(list);
 114        }
 115}
 116
 117static struct grep_expr *compile_pattern_and(struct grep_pat **list)
 118{
 119        struct grep_pat *p;
 120        struct grep_expr *x, *y, *z;
 121
 122        x = compile_pattern_not(list);
 123        p = *list;
 124        if (p && p->token == GREP_AND) {
 125                if (!p->next)
 126                        die("--and not followed by pattern expression");
 127                *list = p->next;
 128                y = compile_pattern_and(list);
 129                if (!y)
 130                        die("--and not followed by pattern expression");
 131                z = xcalloc(1, sizeof (struct grep_expr));
 132                z->node = GREP_NODE_AND;
 133                z->u.binary.left = x;
 134                z->u.binary.right = y;
 135                return z;
 136        }
 137        return x;
 138}
 139
 140static struct grep_expr *compile_pattern_or(struct grep_pat **list)
 141{
 142        struct grep_pat *p;
 143        struct grep_expr *x, *y, *z;
 144
 145        x = compile_pattern_and(list);
 146        p = *list;
 147        if (x && p && p->token != GREP_CLOSE_PAREN) {
 148                y = compile_pattern_or(list);
 149                if (!y)
 150                        die("not a pattern expression %s", p->pattern);
 151                z = xcalloc(1, sizeof (struct grep_expr));
 152                z->node = GREP_NODE_OR;
 153                z->u.binary.left = x;
 154                z->u.binary.right = y;
 155                return z;
 156        }
 157        return x;
 158}
 159
 160static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
 161{
 162        return compile_pattern_or(list);
 163}
 164
 165void compile_grep_patterns(struct grep_opt *opt)
 166{
 167        struct grep_pat *p;
 168
 169        if (opt->all_match)
 170                opt->extended = 1;
 171
 172        for (p = opt->pattern_list; p; p = p->next) {
 173                switch (p->token) {
 174                case GREP_PATTERN: /* atom */
 175                case GREP_PATTERN_HEAD:
 176                case GREP_PATTERN_BODY:
 177                        compile_regexp(p, opt);
 178                        break;
 179                default:
 180                        opt->extended = 1;
 181                        break;
 182                }
 183        }
 184
 185        if (!opt->extended)
 186                return;
 187
 188        /* Then bundle them up in an expression.
 189         * A classic recursive descent parser would do.
 190         */
 191        p = opt->pattern_list;
 192        if (p)
 193                opt->pattern_expression = compile_pattern_expr(&p);
 194        if (p)
 195                die("incomplete pattern expression: %s", p->pattern);
 196}
 197
 198static void free_pattern_expr(struct grep_expr *x)
 199{
 200        switch (x->node) {
 201        case GREP_NODE_ATOM:
 202                break;
 203        case GREP_NODE_NOT:
 204                free_pattern_expr(x->u.unary);
 205                break;
 206        case GREP_NODE_AND:
 207        case GREP_NODE_OR:
 208                free_pattern_expr(x->u.binary.left);
 209                free_pattern_expr(x->u.binary.right);
 210                break;
 211        }
 212        free(x);
 213}
 214
 215void free_grep_patterns(struct grep_opt *opt)
 216{
 217        struct grep_pat *p, *n;
 218
 219        for (p = opt->pattern_list; p; p = n) {
 220                n = p->next;
 221                switch (p->token) {
 222                case GREP_PATTERN: /* atom */
 223                case GREP_PATTERN_HEAD:
 224                case GREP_PATTERN_BODY:
 225                        regfree(&p->regexp);
 226                        break;
 227                default:
 228                        break;
 229                }
 230                free(p);
 231        }
 232
 233        if (!opt->extended)
 234                return;
 235        free_pattern_expr(opt->pattern_expression);
 236}
 237
 238static char *end_of_line(char *cp, unsigned long *left)
 239{
 240        unsigned long l = *left;
 241        while (l && *cp != '\n') {
 242                l--;
 243                cp++;
 244        }
 245        *left = l;
 246        return cp;
 247}
 248
 249static int word_char(char ch)
 250{
 251        return isalnum(ch) || ch == '_';
 252}
 253
 254static void show_name(struct grep_opt *opt, const char *name)
 255{
 256        printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
 257}
 258
 259
 260static int fixmatch(const char *pattern, char *line, int ignore_case, regmatch_t *match)
 261{
 262        char *hit;
 263        if (ignore_case)
 264                hit = strcasestr(line, pattern);
 265        else
 266                hit = strstr(line, pattern);
 267
 268        if (!hit) {
 269                match->rm_so = match->rm_eo = -1;
 270                return REG_NOMATCH;
 271        }
 272        else {
 273                match->rm_so = hit - line;
 274                match->rm_eo = match->rm_so + strlen(pattern);
 275                return 0;
 276        }
 277}
 278
 279static int strip_timestamp(char *bol, char **eol_p)
 280{
 281        char *eol = *eol_p;
 282        int ch;
 283
 284        while (bol < --eol) {
 285                if (*eol != '>')
 286                        continue;
 287                *eol_p = ++eol;
 288                ch = *eol;
 289                *eol = '\0';
 290                return ch;
 291        }
 292        return 0;
 293}
 294
 295static struct {
 296        const char *field;
 297        size_t len;
 298} header_field[] = {
 299        { "author ", 7 },
 300        { "committer ", 10 },
 301};
 302
 303static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
 304                             enum grep_context ctx,
 305                             regmatch_t *pmatch, int eflags)
 306{
 307        int hit = 0;
 308        int saved_ch = 0;
 309        const char *start = bol;
 310
 311        if ((p->token != GREP_PATTERN) &&
 312            ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
 313                return 0;
 314
 315        if (p->token == GREP_PATTERN_HEAD) {
 316                const char *field;
 317                size_t len;
 318                assert(p->field < ARRAY_SIZE(header_field));
 319                field = header_field[p->field].field;
 320                len = header_field[p->field].len;
 321                if (strncmp(bol, field, len))
 322                        return 0;
 323                bol += len;
 324                saved_ch = strip_timestamp(bol, &eol);
 325        }
 326
 327 again:
 328        if (p->fixed)
 329                hit = !fixmatch(p->pattern, bol, p->ignore_case, pmatch);
 330        else
 331                hit = !regexec(&p->regexp, bol, 1, pmatch, eflags);
 332
 333        if (hit && p->word_regexp) {
 334                if ((pmatch[0].rm_so < 0) ||
 335                    (eol - bol) < pmatch[0].rm_so ||
 336                    (pmatch[0].rm_eo < 0) ||
 337                    (eol - bol) < pmatch[0].rm_eo)
 338                        die("regexp returned nonsense");
 339
 340                /* Match beginning must be either beginning of the
 341                 * line, or at word boundary (i.e. the last char must
 342                 * not be a word char).  Similarly, match end must be
 343                 * either end of the line, or at word boundary
 344                 * (i.e. the next char must not be a word char).
 345                 */
 346                if ( ((pmatch[0].rm_so == 0) ||
 347                      !word_char(bol[pmatch[0].rm_so-1])) &&
 348                     ((pmatch[0].rm_eo == (eol-bol)) ||
 349                      !word_char(bol[pmatch[0].rm_eo])) )
 350                        ;
 351                else
 352                        hit = 0;
 353
 354                /* Words consist of at least one character. */
 355                if (pmatch->rm_so == pmatch->rm_eo)
 356                        hit = 0;
 357
 358                if (!hit && pmatch[0].rm_so + bol + 1 < eol) {
 359                        /* There could be more than one match on the
 360                         * line, and the first match might not be
 361                         * strict word match.  But later ones could be!
 362                         * Forward to the next possible start, i.e. the
 363                         * next position following a non-word char.
 364                         */
 365                        bol = pmatch[0].rm_so + bol + 1;
 366                        while (word_char(bol[-1]) && bol < eol)
 367                                bol++;
 368                        eflags |= REG_NOTBOL;
 369                        if (bol < eol)
 370                                goto again;
 371                }
 372        }
 373        if (p->token == GREP_PATTERN_HEAD && saved_ch)
 374                *eol = saved_ch;
 375        if (hit) {
 376                pmatch[0].rm_so += bol - start;
 377                pmatch[0].rm_eo += bol - start;
 378        }
 379        return hit;
 380}
 381
 382static int match_expr_eval(struct grep_expr *x, char *bol, char *eol,
 383                           enum grep_context ctx, int collect_hits)
 384{
 385        int h = 0;
 386        regmatch_t match;
 387
 388        if (!x)
 389                die("Not a valid grep expression");
 390        switch (x->node) {
 391        case GREP_NODE_ATOM:
 392                h = match_one_pattern(x->u.atom, bol, eol, ctx, &match, 0);
 393                break;
 394        case GREP_NODE_NOT:
 395                h = !match_expr_eval(x->u.unary, bol, eol, ctx, 0);
 396                break;
 397        case GREP_NODE_AND:
 398                if (!match_expr_eval(x->u.binary.left, bol, eol, ctx, 0))
 399                        return 0;
 400                h = match_expr_eval(x->u.binary.right, bol, eol, ctx, 0);
 401                break;
 402        case GREP_NODE_OR:
 403                if (!collect_hits)
 404                        return (match_expr_eval(x->u.binary.left,
 405                                                bol, eol, ctx, 0) ||
 406                                match_expr_eval(x->u.binary.right,
 407                                                bol, eol, ctx, 0));
 408                h = match_expr_eval(x->u.binary.left, bol, eol, ctx, 0);
 409                x->u.binary.left->hit |= h;
 410                h |= match_expr_eval(x->u.binary.right, bol, eol, ctx, 1);
 411                break;
 412        default:
 413                die("Unexpected node type (internal error) %d", x->node);
 414        }
 415        if (collect_hits)
 416                x->hit |= h;
 417        return h;
 418}
 419
 420static int match_expr(struct grep_opt *opt, char *bol, char *eol,
 421                      enum grep_context ctx, int collect_hits)
 422{
 423        struct grep_expr *x = opt->pattern_expression;
 424        return match_expr_eval(x, bol, eol, ctx, collect_hits);
 425}
 426
 427static int match_line(struct grep_opt *opt, char *bol, char *eol,
 428                      enum grep_context ctx, int collect_hits)
 429{
 430        struct grep_pat *p;
 431        regmatch_t match;
 432
 433        if (opt->extended)
 434                return match_expr(opt, bol, eol, ctx, collect_hits);
 435
 436        /* we do not call with collect_hits without being extended */
 437        for (p = opt->pattern_list; p; p = p->next) {
 438                if (match_one_pattern(p, bol, eol, ctx, &match, 0))
 439                        return 1;
 440        }
 441        return 0;
 442}
 443
 444static int match_next_pattern(struct grep_pat *p, char *bol, char *eol,
 445                              enum grep_context ctx,
 446                              regmatch_t *pmatch, int eflags)
 447{
 448        regmatch_t match;
 449
 450        if (!match_one_pattern(p, bol, eol, ctx, &match, eflags))
 451                return 0;
 452        if (match.rm_so < 0 || match.rm_eo < 0)
 453                return 0;
 454        if (pmatch->rm_so >= 0 && pmatch->rm_eo >= 0) {
 455                if (match.rm_so > pmatch->rm_so)
 456                        return 1;
 457                if (match.rm_so == pmatch->rm_so && match.rm_eo < pmatch->rm_eo)
 458                        return 1;
 459        }
 460        pmatch->rm_so = match.rm_so;
 461        pmatch->rm_eo = match.rm_eo;
 462        return 1;
 463}
 464
 465static int next_match(struct grep_opt *opt, char *bol, char *eol,
 466                      enum grep_context ctx, regmatch_t *pmatch, int eflags)
 467{
 468        struct grep_pat *p;
 469        int hit = 0;
 470
 471        pmatch->rm_so = pmatch->rm_eo = -1;
 472        if (bol < eol) {
 473                for (p = opt->pattern_list; p; p = p->next) {
 474                        switch (p->token) {
 475                        case GREP_PATTERN: /* atom */
 476                        case GREP_PATTERN_HEAD:
 477                        case GREP_PATTERN_BODY:
 478                                hit |= match_next_pattern(p, bol, eol, ctx,
 479                                                          pmatch, eflags);
 480                                break;
 481                        default:
 482                                break;
 483                        }
 484                }
 485        }
 486        return hit;
 487}
 488
 489static void show_line(struct grep_opt *opt, char *bol, char *eol,
 490                      const char *name, unsigned lno, char sign)
 491{
 492        int rest = eol - bol;
 493
 494        if (opt->pre_context || opt->post_context) {
 495                if (opt->last_shown == 0) {
 496                        if (opt->show_hunk_mark)
 497                                fputs("--\n", stdout);
 498                        else
 499                                opt->show_hunk_mark = 1;
 500                } else if (lno > opt->last_shown + 1)
 501                        fputs("--\n", stdout);
 502        }
 503        opt->last_shown = lno;
 504
 505        if (opt->null_following_name)
 506                sign = '\0';
 507        if (opt->pathname)
 508                printf("%s%c", name, sign);
 509        if (opt->linenum)
 510                printf("%d%c", lno, sign);
 511        if (opt->color) {
 512                regmatch_t match;
 513                enum grep_context ctx = GREP_CONTEXT_BODY;
 514                int ch = *eol;
 515                int eflags = 0;
 516
 517                *eol = '\0';
 518                while (next_match(opt, bol, eol, ctx, &match, eflags)) {
 519                        if (match.rm_so == match.rm_eo)
 520                                break;
 521                        printf("%.*s%s%.*s%s",
 522                               (int)match.rm_so, bol,
 523                               opt->color_match,
 524                               (int)(match.rm_eo - match.rm_so), bol + match.rm_so,
 525                               GIT_COLOR_RESET);
 526                        bol += match.rm_eo;
 527                        rest -= match.rm_eo;
 528                        eflags = REG_NOTBOL;
 529                }
 530                *eol = ch;
 531        }
 532        printf("%.*s\n", rest, bol);
 533}
 534
 535static int match_funcname(struct grep_opt *opt, char *bol, char *eol)
 536{
 537        xdemitconf_t *xecfg = opt->priv;
 538        if (xecfg && xecfg->find_func) {
 539                char buf[1];
 540                return xecfg->find_func(bol, eol - bol, buf, 1,
 541                                        xecfg->find_func_priv) >= 0;
 542        }
 543
 544        if (bol == eol)
 545                return 0;
 546        if (isalpha(*bol) || *bol == '_' || *bol == '$')
 547                return 1;
 548        return 0;
 549}
 550
 551static void show_funcname_line(struct grep_opt *opt, const char *name,
 552                               char *buf, char *bol, unsigned lno)
 553{
 554        while (bol > buf) {
 555                char *eol = --bol;
 556
 557                while (bol > buf && bol[-1] != '\n')
 558                        bol--;
 559                lno--;
 560
 561                if (lno <= opt->last_shown)
 562                        break;
 563
 564                if (match_funcname(opt, bol, eol)) {
 565                        show_line(opt, bol, eol, name, lno, '=');
 566                        break;
 567                }
 568        }
 569}
 570
 571static void show_pre_context(struct grep_opt *opt, const char *name, char *buf,
 572                             char *bol, unsigned lno)
 573{
 574        unsigned cur = lno, from = 1, funcname_lno = 0;
 575        int funcname_needed = opt->funcname;
 576
 577        if (opt->pre_context < lno)
 578                from = lno - opt->pre_context;
 579        if (from <= opt->last_shown)
 580                from = opt->last_shown + 1;
 581
 582        /* Rewind. */
 583        while (bol > buf && cur > from) {
 584                char *eol = --bol;
 585
 586                while (bol > buf && bol[-1] != '\n')
 587                        bol--;
 588                cur--;
 589                if (funcname_needed && match_funcname(opt, bol, eol)) {
 590                        funcname_lno = cur;
 591                        funcname_needed = 0;
 592                }
 593        }
 594
 595        /* We need to look even further back to find a function signature. */
 596        if (opt->funcname && funcname_needed)
 597                show_funcname_line(opt, name, buf, bol, cur);
 598
 599        /* Back forward. */
 600        while (cur < lno) {
 601                char *eol = bol, sign = (cur == funcname_lno) ? '=' : '-';
 602
 603                while (*eol != '\n')
 604                        eol++;
 605                show_line(opt, bol, eol, name, cur, sign);
 606                bol = eol + 1;
 607                cur++;
 608        }
 609}
 610
 611static int should_lookahead(struct grep_opt *opt)
 612{
 613        struct grep_pat *p;
 614
 615        if (opt->extended)
 616                return 0; /* punt for too complex stuff */
 617        if (opt->invert)
 618                return 0;
 619        for (p = opt->pattern_list; p; p = p->next) {
 620                if (p->token != GREP_PATTERN)
 621                        return 0; /* punt for "header only" and stuff */
 622        }
 623        return 1;
 624}
 625
 626static int look_ahead(struct grep_opt *opt,
 627                      unsigned long *left_p,
 628                      unsigned *lno_p,
 629                      char **bol_p)
 630{
 631        unsigned lno = *lno_p;
 632        char *bol = *bol_p;
 633        struct grep_pat *p;
 634        char *sp, *last_bol;
 635        regoff_t earliest = -1;
 636
 637        for (p = opt->pattern_list; p; p = p->next) {
 638                int hit;
 639                regmatch_t m;
 640
 641                if (p->fixed)
 642                        hit = !fixmatch(p->pattern, bol, p->ignore_case, &m);
 643                else
 644                        hit = !regexec(&p->regexp, bol, 1, &m, 0);
 645                if (!hit || m.rm_so < 0 || m.rm_eo < 0)
 646                        continue;
 647                if (earliest < 0 || m.rm_so < earliest)
 648                        earliest = m.rm_so;
 649        }
 650
 651        if (earliest < 0) {
 652                *bol_p = bol + *left_p;
 653                *left_p = 0;
 654                return 1;
 655        }
 656        for (sp = bol + earliest; bol < sp && sp[-1] != '\n'; sp--)
 657                ; /* find the beginning of the line */
 658        last_bol = sp;
 659
 660        for (sp = bol; sp < last_bol; sp++) {
 661                if (*sp == '\n')
 662                        lno++;
 663        }
 664        *left_p -= last_bol - bol;
 665        *bol_p = last_bol;
 666        *lno_p = lno;
 667        return 0;
 668}
 669
 670static int grep_buffer_1(struct grep_opt *opt, const char *name,
 671                         char *buf, unsigned long size, int collect_hits)
 672{
 673        char *bol = buf;
 674        unsigned long left = size;
 675        unsigned lno = 1;
 676        unsigned last_hit = 0;
 677        int binary_match_only = 0;
 678        unsigned count = 0;
 679        int try_lookahead = 0;
 680        enum grep_context ctx = GREP_CONTEXT_HEAD;
 681        xdemitconf_t xecfg;
 682
 683        opt->last_shown = 0;
 684
 685        if (buffer_is_binary(buf, size)) {
 686                switch (opt->binary) {
 687                case GREP_BINARY_DEFAULT:
 688                        binary_match_only = 1;
 689                        break;
 690                case GREP_BINARY_NOMATCH:
 691                        return 0; /* Assume unmatch */
 692                        break;
 693                default:
 694                        break;
 695                }
 696        }
 697
 698        memset(&xecfg, 0, sizeof(xecfg));
 699        if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
 700            !opt->name_only && !binary_match_only && !collect_hits) {
 701                struct userdiff_driver *drv = userdiff_find_by_path(name);
 702                if (drv && drv->funcname.pattern) {
 703                        const struct userdiff_funcname *pe = &drv->funcname;
 704                        xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
 705                        opt->priv = &xecfg;
 706                }
 707        }
 708        try_lookahead = should_lookahead(opt);
 709
 710        while (left) {
 711                char *eol, ch;
 712                int hit;
 713
 714                /*
 715                 * look_ahead() skips quicly to the line that possibly
 716                 * has the next hit; don't call it if we need to do
 717                 * something more than just skipping the current line
 718                 * in response to an unmatch for the current line.  E.g.
 719                 * inside a post-context window, we will show the current
 720                 * line as a context around the previous hit when it
 721                 * doesn't hit.
 722                 */
 723                if (try_lookahead
 724                    && !(last_hit
 725                         && lno <= last_hit + opt->post_context)
 726                    && look_ahead(opt, &left, &lno, &bol))
 727                        break;
 728                eol = end_of_line(bol, &left);
 729                ch = *eol;
 730                *eol = 0;
 731
 732                if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol))
 733                        ctx = GREP_CONTEXT_BODY;
 734
 735                hit = match_line(opt, bol, eol, ctx, collect_hits);
 736                *eol = ch;
 737
 738                if (collect_hits)
 739                        goto next_line;
 740
 741                /* "grep -v -e foo -e bla" should list lines
 742                 * that do not have either, so inversion should
 743                 * be done outside.
 744                 */
 745                if (opt->invert)
 746                        hit = !hit;
 747                if (opt->unmatch_name_only) {
 748                        if (hit)
 749                                return 0;
 750                        goto next_line;
 751                }
 752                if (hit) {
 753                        count++;
 754                        if (opt->status_only)
 755                                return 1;
 756                        if (binary_match_only) {
 757                                printf("Binary file %s matches\n", name);
 758                                return 1;
 759                        }
 760                        if (opt->name_only) {
 761                                show_name(opt, name);
 762                                return 1;
 763                        }
 764                        /* Hit at this line.  If we haven't shown the
 765                         * pre-context lines, we would need to show them.
 766                         * When asked to do "count", this still show
 767                         * the context which is nonsense, but the user
 768                         * deserves to get that ;-).
 769                         */
 770                        if (opt->pre_context)
 771                                show_pre_context(opt, name, buf, bol, lno);
 772                        else if (opt->funcname)
 773                                show_funcname_line(opt, name, buf, bol, lno);
 774                        if (!opt->count)
 775                                show_line(opt, bol, eol, name, lno, ':');
 776                        last_hit = lno;
 777                }
 778                else if (last_hit &&
 779                         lno <= last_hit + opt->post_context) {
 780                        /* If the last hit is within the post context,
 781                         * we need to show this line.
 782                         */
 783                        show_line(opt, bol, eol, name, lno, '-');
 784                }
 785
 786        next_line:
 787                bol = eol + 1;
 788                if (!left)
 789                        break;
 790                left--;
 791                lno++;
 792        }
 793
 794        if (collect_hits)
 795                return 0;
 796
 797        if (opt->status_only)
 798                return 0;
 799        if (opt->unmatch_name_only) {
 800                /* We did not see any hit, so we want to show this */
 801                show_name(opt, name);
 802                return 1;
 803        }
 804
 805        xdiff_clear_find_func(&xecfg);
 806        opt->priv = NULL;
 807
 808        /* NEEDSWORK:
 809         * The real "grep -c foo *.c" gives many "bar.c:0" lines,
 810         * which feels mostly useless but sometimes useful.  Maybe
 811         * make it another option?  For now suppress them.
 812         */
 813        if (opt->count && count)
 814                printf("%s%c%u\n", name,
 815                       opt->null_following_name ? '\0' : ':', count);
 816        return !!last_hit;
 817}
 818
 819static void clr_hit_marker(struct grep_expr *x)
 820{
 821        /* All-hit markers are meaningful only at the very top level
 822         * OR node.
 823         */
 824        while (1) {
 825                x->hit = 0;
 826                if (x->node != GREP_NODE_OR)
 827                        return;
 828                x->u.binary.left->hit = 0;
 829                x = x->u.binary.right;
 830        }
 831}
 832
 833static int chk_hit_marker(struct grep_expr *x)
 834{
 835        /* Top level nodes have hit markers.  See if they all are hits */
 836        while (1) {
 837                if (x->node != GREP_NODE_OR)
 838                        return x->hit;
 839                if (!x->u.binary.left->hit)
 840                        return 0;
 841                x = x->u.binary.right;
 842        }
 843}
 844
 845int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size)
 846{
 847        /*
 848         * we do not have to do the two-pass grep when we do not check
 849         * buffer-wide "all-match".
 850         */
 851        if (!opt->all_match)
 852                return grep_buffer_1(opt, name, buf, size, 0);
 853
 854        /* Otherwise the toplevel "or" terms hit a bit differently.
 855         * We first clear hit markers from them.
 856         */
 857        clr_hit_marker(opt->pattern_expression);
 858        grep_buffer_1(opt, name, buf, size, 1);
 859
 860        if (!chk_hit_marker(opt->pattern_expression))
 861                return 0;
 862
 863        return grep_buffer_1(opt, name, buf, size, 0);
 864}