Coverage Report

Created: 2024-09-08 06:23

/src/git/grep.c
Line
Count
Source (jump to first uncovered line)
1
#include "git-compat-util.h"
2
#include "config.h"
3
#include "gettext.h"
4
#include "grep.h"
5
#include "hex.h"
6
#include "object-store-ll.h"
7
#include "pretty.h"
8
#include "userdiff.h"
9
#include "xdiff-interface.h"
10
#include "diff.h"
11
#include "diffcore.h"
12
#include "quote.h"
13
#include "help.h"
14
15
static int grep_source_load(struct grep_source *gs);
16
static int grep_source_is_binary(struct grep_source *gs,
17
         struct index_state *istate);
18
19
static void std_output(struct grep_opt *opt UNUSED, const void *buf, size_t size)
20
0
{
21
0
  fwrite(buf, size, 1, stdout);
22
0
}
23
24
static const char *color_grep_slots[] = {
25
  [GREP_COLOR_CONTEXT]      = "context",
26
  [GREP_COLOR_FILENAME]     = "filename",
27
  [GREP_COLOR_FUNCTION]     = "function",
28
  [GREP_COLOR_LINENO]     = "lineNumber",
29
  [GREP_COLOR_COLUMNNO]     = "column",
30
  [GREP_COLOR_MATCH_CONTEXT]  = "matchContext",
31
  [GREP_COLOR_MATCH_SELECTED] = "matchSelected",
32
  [GREP_COLOR_SELECTED]     = "selected",
33
  [GREP_COLOR_SEP]      = "separator",
34
};
35
36
static int parse_pattern_type_arg(const char *opt, const char *arg)
37
0
{
38
0
  if (!strcmp(arg, "default"))
39
0
    return GREP_PATTERN_TYPE_UNSPECIFIED;
40
0
  else if (!strcmp(arg, "basic"))
41
0
    return GREP_PATTERN_TYPE_BRE;
42
0
  else if (!strcmp(arg, "extended"))
43
0
    return GREP_PATTERN_TYPE_ERE;
44
0
  else if (!strcmp(arg, "fixed"))
45
0
    return GREP_PATTERN_TYPE_FIXED;
46
0
  else if (!strcmp(arg, "perl"))
47
0
    return GREP_PATTERN_TYPE_PCRE;
48
0
  die("bad %s argument: %s", opt, arg);
49
0
}
50
51
define_list_config_array_extra(color_grep_slots, {"match"});
52
53
/*
54
 * Read the configuration file once and store it in
55
 * the grep_defaults template.
56
 */
57
int grep_config(const char *var, const char *value,
58
    const struct config_context *ctx, void *cb)
59
0
{
60
0
  struct grep_opt *opt = cb;
61
0
  const char *slot;
62
63
0
  if (userdiff_config(var, value) < 0)
64
0
    return -1;
65
66
0
  if (!strcmp(var, "grep.extendedregexp")) {
67
0
    opt->extended_regexp_option = git_config_bool(var, value);
68
0
    return 0;
69
0
  }
70
71
0
  if (!strcmp(var, "grep.patterntype")) {
72
0
    opt->pattern_type_option = parse_pattern_type_arg(var, value);
73
0
    return 0;
74
0
  }
75
76
0
  if (!strcmp(var, "grep.linenumber")) {
77
0
    opt->linenum = git_config_bool(var, value);
78
0
    return 0;
79
0
  }
80
0
  if (!strcmp(var, "grep.column")) {
81
0
    opt->columnnum = git_config_bool(var, value);
82
0
    return 0;
83
0
  }
84
85
0
  if (!strcmp(var, "grep.fullname")) {
86
0
    opt->relative = !git_config_bool(var, value);
87
0
    return 0;
88
0
  }
89
90
0
  if (!strcmp(var, "color.grep"))
91
0
    opt->color = git_config_colorbool(var, value);
92
0
  if (!strcmp(var, "color.grep.match")) {
93
0
    if (grep_config("color.grep.matchcontext", value, ctx, cb) < 0)
94
0
      return -1;
95
0
    if (grep_config("color.grep.matchselected", value, ctx, cb) < 0)
96
0
      return -1;
97
0
  } else if (skip_prefix(var, "color.grep.", &slot)) {
98
0
    int i = LOOKUP_CONFIG(color_grep_slots, slot);
99
0
    char *color;
100
101
0
    if (i < 0)
102
0
      return -1;
103
0
    color = opt->colors[i];
104
0
    if (!value)
105
0
      return config_error_nonbool(var);
106
0
    return color_parse(value, color);
107
0
  }
108
0
  return 0;
109
0
}
110
111
void grep_init(struct grep_opt *opt, struct repository *repo)
112
0
{
113
0
  struct grep_opt blank = GREP_OPT_INIT;
114
0
  memcpy(opt, &blank, sizeof(*opt));
115
116
0
  opt->repo = repo;
117
0
  opt->pattern_tail = &opt->pattern_list;
118
0
  opt->header_tail = &opt->header_list;
119
0
}
120
121
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
122
          const char *origin, int no,
123
          enum grep_pat_token t,
124
          enum grep_header_field field)
125
0
{
126
0
  struct grep_pat *p = xcalloc(1, sizeof(*p));
127
0
  p->pattern = xmemdupz(pat, patlen);
128
0
  p->patternlen = patlen;
129
0
  p->origin = origin;
130
0
  p->no = no;
131
0
  p->token = t;
132
0
  p->field = field;
133
0
  return p;
134
0
}
135
136
static void do_append_grep_pat(struct grep_pat ***tail, struct grep_pat *p)
137
0
{
138
0
  **tail = p;
139
0
  *tail = &p->next;
140
0
  p->next = NULL;
141
142
0
  switch (p->token) {
143
0
  case GREP_PATTERN: /* atom */
144
0
  case GREP_PATTERN_HEAD:
145
0
  case GREP_PATTERN_BODY:
146
0
    for (;;) {
147
0
      struct grep_pat *new_pat;
148
0
      size_t len = 0;
149
0
      char *cp = p->pattern + p->patternlen, *nl = NULL;
150
0
      while (++len <= p->patternlen) {
151
0
        if (*(--cp) == '\n') {
152
0
          nl = cp;
153
0
          break;
154
0
        }
155
0
      }
156
0
      if (!nl)
157
0
        break;
158
0
      new_pat = create_grep_pat(nl + 1, len - 1, p->origin,
159
0
              p->no, p->token, p->field);
160
0
      new_pat->next = p->next;
161
0
      if (!p->next)
162
0
        *tail = &new_pat->next;
163
0
      p->next = new_pat;
164
0
      *nl = '\0';
165
0
      p->patternlen -= len;
166
0
    }
167
0
    break;
168
0
  default:
169
0
    break;
170
0
  }
171
0
}
172
173
void append_header_grep_pattern(struct grep_opt *opt,
174
        enum grep_header_field field, const char *pat)
175
0
{
176
0
  struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
177
0
               GREP_PATTERN_HEAD, field);
178
0
  if (field == GREP_HEADER_REFLOG)
179
0
    opt->use_reflog_filter = 1;
180
0
  do_append_grep_pat(&opt->header_tail, p);
181
0
}
182
183
void append_grep_pattern(struct grep_opt *opt, const char *pat,
184
       const char *origin, int no, enum grep_pat_token t)
185
0
{
186
0
  append_grep_pat(opt, pat, strlen(pat), origin, no, t);
187
0
}
188
189
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen,
190
         const char *origin, int no, enum grep_pat_token t)
191
0
{
192
0
  struct grep_pat *p = create_grep_pat(pat, patlen, origin, no, t, 0);
193
0
  do_append_grep_pat(&opt->pattern_tail, p);
194
0
}
195
196
struct grep_opt *grep_opt_dup(const struct grep_opt *opt)
197
0
{
198
0
  struct grep_pat *pat;
199
0
  struct grep_opt *ret = xmalloc(sizeof(struct grep_opt));
200
0
  *ret = *opt;
201
202
0
  ret->pattern_list = NULL;
203
0
  ret->pattern_tail = &ret->pattern_list;
204
205
0
  for(pat = opt->pattern_list; pat != NULL; pat = pat->next)
206
0
  {
207
0
    if(pat->token == GREP_PATTERN_HEAD)
208
0
      append_header_grep_pattern(ret, pat->field,
209
0
               pat->pattern);
210
0
    else
211
0
      append_grep_pat(ret, pat->pattern, pat->patternlen,
212
0
          pat->origin, pat->no, pat->token);
213
0
  }
214
215
0
  return ret;
216
0
}
217
218
static NORETURN void compile_regexp_failed(const struct grep_pat *p,
219
    const char *error)
220
0
{
221
0
  char where[1024];
222
223
0
  if (p->no)
224
0
    xsnprintf(where, sizeof(where), "In '%s' at %d, ", p->origin, p->no);
225
0
  else if (p->origin)
226
0
    xsnprintf(where, sizeof(where), "%s, ", p->origin);
227
0
  else
228
0
    where[0] = 0;
229
230
0
  die("%s'%s': %s", where, p->pattern, error);
231
0
}
232
233
static int is_fixed(const char *s, size_t len)
234
0
{
235
0
  size_t i;
236
237
0
  for (i = 0; i < len; i++) {
238
0
    if (is_regex_special(s[i]))
239
0
      return 0;
240
0
  }
241
242
0
  return 1;
243
0
}
244
245
#ifdef USE_LIBPCRE2
246
#define GREP_PCRE2_DEBUG_MALLOC 0
247
248
static void *pcre2_malloc(PCRE2_SIZE size, void *memory_data UNUSED)
249
{
250
  void *pointer = malloc(size);
251
#if GREP_PCRE2_DEBUG_MALLOC
252
  static int count = 1;
253
  fprintf(stderr, "PCRE2:%p -> #%02d: alloc(%lu)\n", pointer, count++, size);
254
#endif
255
  return pointer;
256
}
257
258
static void pcre2_free(void *pointer, void *memory_data UNUSED)
259
{
260
#if GREP_PCRE2_DEBUG_MALLOC
261
  static int count = 1;
262
  if (pointer)
263
    fprintf(stderr, "PCRE2:%p -> #%02d: free()\n", pointer, count++);
264
#endif
265
  free(pointer);
266
}
267
268
static int pcre2_jit_functional(void)
269
{
270
  static int jit_working = -1;
271
  pcre2_code *code;
272
  size_t off;
273
  int err;
274
275
  if (jit_working != -1)
276
    return jit_working;
277
278
  /*
279
   * Try to JIT compile a simple pattern to probe if the JIT is
280
   * working in general. It might fail for systems where creating
281
   * memory mappings for runtime code generation is restricted.
282
   */
283
  code = pcre2_compile((PCRE2_SPTR)".", 1, 0, &err, &off, NULL);
284
  if (!code)
285
    return 0;
286
287
  jit_working = pcre2_jit_compile(code, PCRE2_JIT_COMPLETE) == 0;
288
  pcre2_code_free(code);
289
290
  return jit_working;
291
}
292
293
static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
294
{
295
  int error;
296
  PCRE2_UCHAR errbuf[256];
297
  PCRE2_SIZE erroffset;
298
  int options = PCRE2_MULTILINE;
299
  int jitret;
300
  int patinforet;
301
  size_t jitsizearg;
302
  int literal = !opt->ignore_case && (p->fixed || p->is_fixed);
303
304
  /*
305
   * Call pcre2_general_context_create() before calling any
306
   * other pcre2_*(). It sets up our malloc()/free() functions
307
   * with which everything else is allocated.
308
   */
309
  p->pcre2_general_context = pcre2_general_context_create(
310
    pcre2_malloc, pcre2_free, NULL);
311
  if (!p->pcre2_general_context)
312
    die("Couldn't allocate PCRE2 general context");
313
314
  if (opt->ignore_case) {
315
    if (!opt->ignore_locale && has_non_ascii(p->pattern)) {
316
      p->pcre2_tables = pcre2_maketables(p->pcre2_general_context);
317
      p->pcre2_compile_context = pcre2_compile_context_create(p->pcre2_general_context);
318
      pcre2_set_character_tables(p->pcre2_compile_context,
319
              p->pcre2_tables);
320
    }
321
    options |= PCRE2_CASELESS;
322
  }
323
  if (!opt->ignore_locale && is_utf8_locale() && !literal)
324
    options |= (PCRE2_UTF | PCRE2_UCP | PCRE2_MATCH_INVALID_UTF);
325
326
#ifndef GIT_PCRE2_VERSION_10_35_OR_HIGHER
327
  /*
328
   * Work around a JIT bug related to invalid Unicode character handling
329
   * fixed in 10.35:
330
   * https://github.com/PCRE2Project/pcre2/commit/c21bd977547d
331
   */
332
  options &= ~PCRE2_UCP;
333
#endif
334
335
#ifndef GIT_PCRE2_VERSION_10_36_OR_HIGHER
336
  /* Work around https://bugs.exim.org/show_bug.cgi?id=2642 fixed in 10.36 */
337
  if (PCRE2_MATCH_INVALID_UTF && options & (PCRE2_UTF | PCRE2_CASELESS))
338
    options |= PCRE2_NO_START_OPTIMIZE;
339
#endif
340
341
  p->pcre2_pattern = pcre2_compile((PCRE2_SPTR)p->pattern,
342
           p->patternlen, options, &error, &erroffset,
343
           p->pcre2_compile_context);
344
345
  if (p->pcre2_pattern) {
346
    p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, p->pcre2_general_context);
347
    if (!p->pcre2_match_data)
348
      die("Couldn't allocate PCRE2 match data");
349
  } else {
350
    pcre2_get_error_message(error, errbuf, sizeof(errbuf));
351
    compile_regexp_failed(p, (const char *)&errbuf);
352
  }
353
354
  pcre2_config(PCRE2_CONFIG_JIT, &p->pcre2_jit_on);
355
  if (p->pcre2_jit_on) {
356
    jitret = pcre2_jit_compile(p->pcre2_pattern, PCRE2_JIT_COMPLETE);
357
    if (jitret == PCRE2_ERROR_NOMEMORY && !pcre2_jit_functional()) {
358
      /*
359
       * Even though pcre2_config(PCRE2_CONFIG_JIT, ...)
360
       * indicated JIT support, the library might still
361
       * fail to generate JIT code for various reasons,
362
       * e.g. when SELinux's 'deny_execmem' or PaX's
363
       * MPROTECT prevent creating W|X memory mappings.
364
       *
365
       * Instead of faling hard, fall back to interpreter
366
       * mode, just as if the pattern was prefixed with
367
       * '(*NO_JIT)'.
368
       */
369
      p->pcre2_jit_on = 0;
370
      return;
371
    } else if (jitret) {
372
      int need_clip = p->patternlen > 64;
373
      int clip_len = need_clip ? 64 : p->patternlen;
374
      die("Couldn't JIT the PCRE2 pattern '%.*s'%s, got '%d'%s",
375
          clip_len, p->pattern, need_clip ? "..." : "", jitret,
376
          pcre2_jit_functional()
377
          ? "\nPerhaps prefix (*NO_JIT) to your pattern?"
378
          : "");
379
    }
380
381
    /*
382
     * The pcre2_config(PCRE2_CONFIG_JIT, ...) call just
383
     * tells us whether the library itself supports JIT,
384
     * but to see whether we're going to be actually using
385
     * JIT we need to extract PCRE2_INFO_JITSIZE from the
386
     * pattern *after* we do pcre2_jit_compile() above.
387
     *
388
     * This is because if the pattern contains the
389
     * (*NO_JIT) verb (see pcre2syntax(3))
390
     * pcre2_jit_compile() will exit early with 0. If we
391
     * then proceed to call pcre2_jit_match() further down
392
     * the line instead of pcre2_match() we'll either
393
     * segfault (pre PCRE 10.31) or run into a fatal error
394
     * (post PCRE2 10.31)
395
     */
396
    patinforet = pcre2_pattern_info(p->pcre2_pattern, PCRE2_INFO_JITSIZE, &jitsizearg);
397
    if (patinforet)
398
      BUG("pcre2_pattern_info() failed: %d", patinforet);
399
    if (jitsizearg == 0) {
400
      p->pcre2_jit_on = 0;
401
      return;
402
    }
403
  }
404
}
405
406
static int pcre2match(struct grep_pat *p, const char *line, const char *eol,
407
    regmatch_t *match, int eflags)
408
{
409
  int ret, flags = 0;
410
  PCRE2_SIZE *ovector;
411
  PCRE2_UCHAR errbuf[256];
412
413
  if (eflags & REG_NOTBOL)
414
    flags |= PCRE2_NOTBOL;
415
416
  if (p->pcre2_jit_on)
417
    ret = pcre2_jit_match(p->pcre2_pattern, (unsigned char *)line,
418
              eol - line, 0, flags, p->pcre2_match_data,
419
              NULL);
420
  else
421
    ret = pcre2_match(p->pcre2_pattern, (unsigned char *)line,
422
          eol - line, 0, flags, p->pcre2_match_data,
423
          NULL);
424
425
  if (ret < 0 && ret != PCRE2_ERROR_NOMATCH) {
426
    pcre2_get_error_message(ret, errbuf, sizeof(errbuf));
427
    die("%s failed with error code %d: %s",
428
        (p->pcre2_jit_on ? "pcre2_jit_match" : "pcre2_match"), ret,
429
        errbuf);
430
  }
431
  if (ret > 0) {
432
    ovector = pcre2_get_ovector_pointer(p->pcre2_match_data);
433
    ret = 0;
434
    match->rm_so = (int)ovector[0];
435
    match->rm_eo = (int)ovector[1];
436
  }
437
438
  return ret;
439
}
440
441
static void free_pcre2_pattern(struct grep_pat *p)
442
{
443
  pcre2_compile_context_free(p->pcre2_compile_context);
444
  pcre2_code_free(p->pcre2_pattern);
445
  pcre2_match_data_free(p->pcre2_match_data);
446
#ifdef GIT_PCRE2_VERSION_10_34_OR_HIGHER
447
  pcre2_maketables_free(p->pcre2_general_context, p->pcre2_tables);
448
#else
449
  free((void *)p->pcre2_tables);
450
#endif
451
  pcre2_general_context_free(p->pcre2_general_context);
452
}
453
#else /* !USE_LIBPCRE2 */
454
static void compile_pcre2_pattern(struct grep_pat *p UNUSED,
455
          const struct grep_opt *opt UNUSED)
456
0
{
457
0
  die("cannot use Perl-compatible regexes when not compiled with USE_LIBPCRE");
458
0
}
459
460
static int pcre2match(struct grep_pat *p UNUSED, const char *line UNUSED,
461
          const char *eol UNUSED, regmatch_t *match UNUSED,
462
          int eflags UNUSED)
463
0
{
464
0
  return 1;
465
0
}
466
467
static void free_pcre2_pattern(struct grep_pat *p UNUSED)
468
0
{
469
0
}
470
471
static void compile_fixed_regexp(struct grep_pat *p, struct grep_opt *opt)
472
0
{
473
0
  struct strbuf sb = STRBUF_INIT;
474
0
  int err;
475
0
  int regflags = 0;
476
477
0
  basic_regex_quote_buf(&sb, p->pattern);
478
0
  if (opt->ignore_case)
479
0
    regflags |= REG_ICASE;
480
0
  err = regcomp(&p->regexp, sb.buf, regflags);
481
0
  strbuf_release(&sb);
482
0
  if (err) {
483
0
    char errbuf[1024];
484
0
    regerror(err, &p->regexp, errbuf, sizeof(errbuf));
485
0
    compile_regexp_failed(p, errbuf);
486
0
  }
487
0
}
488
#endif /* !USE_LIBPCRE2 */
489
490
static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
491
0
{
492
0
  int err;
493
0
  int regflags = REG_NEWLINE;
494
495
0
  if (opt->pattern_type_option == GREP_PATTERN_TYPE_UNSPECIFIED)
496
0
    opt->pattern_type_option = (opt->extended_regexp_option
497
0
              ? GREP_PATTERN_TYPE_ERE
498
0
              : GREP_PATTERN_TYPE_BRE);
499
500
0
  p->word_regexp = opt->word_regexp;
501
0
  p->ignore_case = opt->ignore_case;
502
0
  p->fixed = opt->pattern_type_option == GREP_PATTERN_TYPE_FIXED;
503
504
0
  if (opt->pattern_type_option != GREP_PATTERN_TYPE_PCRE &&
505
0
      memchr(p->pattern, 0, p->patternlen))
506
0
    die(_("given pattern contains NULL byte (via -f <file>). This is only supported with -P under PCRE v2"));
507
508
0
  p->is_fixed = is_fixed(p->pattern, p->patternlen);
509
#ifdef USE_LIBPCRE2
510
       if (!p->fixed && !p->is_fixed) {
511
         const char *no_jit = "(*NO_JIT)";
512
         const int no_jit_len = strlen(no_jit);
513
         if (starts_with(p->pattern, no_jit) &&
514
       is_fixed(p->pattern + no_jit_len,
515
          p->patternlen - no_jit_len))
516
           p->is_fixed = 1;
517
       }
518
#endif
519
0
  if (p->fixed || p->is_fixed) {
520
#ifdef USE_LIBPCRE2
521
    if (p->is_fixed) {
522
      compile_pcre2_pattern(p, opt);
523
    } else {
524
      /*
525
       * E.g. t7811-grep-open.sh relies on the
526
       * pattern being restored.
527
       */
528
      char *old_pattern = p->pattern;
529
      size_t old_patternlen = p->patternlen;
530
      struct strbuf sb = STRBUF_INIT;
531
532
      /*
533
       * There is the PCRE2_LITERAL flag, but it's
534
       * only in PCRE v2 10.30 and later. Needing to
535
       * ifdef our way around that and dealing with
536
       * it + PCRE2_MULTILINE being an error is more
537
       * complex than just quoting this ourselves.
538
      */
539
      strbuf_add(&sb, "\\Q", 2);
540
      strbuf_add(&sb, p->pattern, p->patternlen);
541
      strbuf_add(&sb, "\\E", 2);
542
543
      p->pattern = sb.buf;
544
      p->patternlen = sb.len;
545
      compile_pcre2_pattern(p, opt);
546
      p->pattern = old_pattern;
547
      p->patternlen = old_patternlen;
548
      strbuf_release(&sb);
549
    }
550
#else /* !USE_LIBPCRE2 */
551
0
    compile_fixed_regexp(p, opt);
552
0
#endif /* !USE_LIBPCRE2 */
553
0
    return;
554
0
  }
555
556
0
  if (opt->pattern_type_option == GREP_PATTERN_TYPE_PCRE) {
557
0
    compile_pcre2_pattern(p, opt);
558
0
    return;
559
0
  }
560
561
0
  if (p->ignore_case)
562
0
    regflags |= REG_ICASE;
563
0
  if (opt->pattern_type_option == GREP_PATTERN_TYPE_ERE)
564
0
    regflags |= REG_EXTENDED;
565
0
  err = regcomp(&p->regexp, p->pattern, regflags);
566
0
  if (err) {
567
0
    char errbuf[1024];
568
0
    regerror(err, &p->regexp, errbuf, 1024);
569
0
    compile_regexp_failed(p, errbuf);
570
0
  }
571
0
}
572
573
static struct grep_expr *grep_not_expr(struct grep_expr *expr)
574
0
{
575
0
  struct grep_expr *z = xcalloc(1, sizeof(*z));
576
0
  z->node = GREP_NODE_NOT;
577
0
  z->u.unary = expr;
578
0
  return z;
579
0
}
580
581
static struct grep_expr *grep_binexp(enum grep_expr_node kind,
582
             struct grep_expr *left,
583
             struct grep_expr *right)
584
0
{
585
0
  struct grep_expr *z = xcalloc(1, sizeof(*z));
586
0
  z->node = kind;
587
0
  z->u.binary.left = left;
588
0
  z->u.binary.right = right;
589
0
  return z;
590
0
}
591
592
static struct grep_expr *grep_or_expr(struct grep_expr *left, struct grep_expr *right)
593
0
{
594
0
  return grep_binexp(GREP_NODE_OR, left, right);
595
0
}
596
597
static struct grep_expr *grep_and_expr(struct grep_expr *left, struct grep_expr *right)
598
0
{
599
0
  return grep_binexp(GREP_NODE_AND, left, right);
600
0
}
601
602
static struct grep_expr *compile_pattern_or(struct grep_pat **);
603
static struct grep_expr *compile_pattern_atom(struct grep_pat **list)
604
0
{
605
0
  struct grep_pat *p;
606
0
  struct grep_expr *x;
607
608
0
  p = *list;
609
0
  if (!p)
610
0
    return NULL;
611
0
  switch (p->token) {
612
0
  case GREP_PATTERN: /* atom */
613
0
  case GREP_PATTERN_HEAD:
614
0
  case GREP_PATTERN_BODY:
615
0
    CALLOC_ARRAY(x, 1);
616
0
    x->node = GREP_NODE_ATOM;
617
0
    x->u.atom = p;
618
0
    *list = p->next;
619
0
    return x;
620
0
  case GREP_OPEN_PAREN:
621
0
    *list = p->next;
622
0
    x = compile_pattern_or(list);
623
0
    if (!*list || (*list)->token != GREP_CLOSE_PAREN)
624
0
      die("unmatched ( for expression group");
625
0
    *list = (*list)->next;
626
0
    return x;
627
0
  default:
628
0
    return NULL;
629
0
  }
630
0
}
631
632
static struct grep_expr *compile_pattern_not(struct grep_pat **list)
633
0
{
634
0
  struct grep_pat *p;
635
0
  struct grep_expr *x;
636
637
0
  p = *list;
638
0
  if (!p)
639
0
    return NULL;
640
0
  switch (p->token) {
641
0
  case GREP_NOT:
642
0
    if (!p->next)
643
0
      die("--not not followed by pattern expression");
644
0
    *list = p->next;
645
0
    x = compile_pattern_not(list);
646
0
    if (!x)
647
0
      die("--not followed by non pattern expression");
648
0
    return grep_not_expr(x);
649
0
  default:
650
0
    return compile_pattern_atom(list);
651
0
  }
652
0
}
653
654
static struct grep_expr *compile_pattern_and(struct grep_pat **list)
655
0
{
656
0
  struct grep_pat *p;
657
0
  struct grep_expr *x, *y;
658
659
0
  x = compile_pattern_not(list);
660
0
  p = *list;
661
0
  if (p && p->token == GREP_AND) {
662
0
    if (!x)
663
0
      die("--and not preceded by pattern expression");
664
0
    if (!p->next)
665
0
      die("--and not followed by pattern expression");
666
0
    *list = p->next;
667
0
    y = compile_pattern_and(list);
668
0
    if (!y)
669
0
      die("--and not followed by pattern expression");
670
0
    return grep_and_expr(x, y);
671
0
  }
672
0
  return x;
673
0
}
674
675
static struct grep_expr *compile_pattern_or(struct grep_pat **list)
676
0
{
677
0
  struct grep_pat *p;
678
0
  struct grep_expr *x, *y;
679
680
0
  x = compile_pattern_and(list);
681
0
  p = *list;
682
0
  if (x && p && p->token != GREP_CLOSE_PAREN) {
683
0
    y = compile_pattern_or(list);
684
0
    if (!y)
685
0
      die("not a pattern expression %s", p->pattern);
686
0
    return grep_or_expr(x, y);
687
0
  }
688
0
  return x;
689
0
}
690
691
static struct grep_expr *compile_pattern_expr(struct grep_pat **list)
692
0
{
693
0
  return compile_pattern_or(list);
694
0
}
695
696
static struct grep_expr *grep_true_expr(void)
697
0
{
698
0
  struct grep_expr *z = xcalloc(1, sizeof(*z));
699
0
  z->node = GREP_NODE_TRUE;
700
0
  return z;
701
0
}
702
703
static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
704
0
{
705
0
  struct grep_pat *p;
706
0
  struct grep_expr *header_expr;
707
0
  struct grep_expr *(header_group[GREP_HEADER_FIELD_MAX]);
708
0
  enum grep_header_field fld;
709
710
0
  if (!opt->header_list)
711
0
    return NULL;
712
713
0
  for (p = opt->header_list; p; p = p->next) {
714
0
    if (p->token != GREP_PATTERN_HEAD)
715
0
      BUG("a non-header pattern in grep header list.");
716
0
    if (p->field < GREP_HEADER_FIELD_MIN ||
717
0
        GREP_HEADER_FIELD_MAX <= p->field)
718
0
      BUG("unknown header field %d", p->field);
719
0
    compile_regexp(p, opt);
720
0
  }
721
722
0
  for (fld = 0; fld < GREP_HEADER_FIELD_MAX; fld++)
723
0
    header_group[fld] = NULL;
724
725
0
  for (p = opt->header_list; p; p = p->next) {
726
0
    struct grep_expr *h;
727
0
    struct grep_pat *pp = p;
728
729
0
    h = compile_pattern_atom(&pp);
730
0
    if (!h || pp != p->next)
731
0
      BUG("malformed header expr");
732
0
    if (!header_group[p->field]) {
733
0
      header_group[p->field] = h;
734
0
      continue;
735
0
    }
736
0
    header_group[p->field] = grep_or_expr(h, header_group[p->field]);
737
0
  }
738
739
0
  header_expr = NULL;
740
741
0
  for (fld = 0; fld < GREP_HEADER_FIELD_MAX; fld++) {
742
0
    if (!header_group[fld])
743
0
      continue;
744
0
    if (!header_expr)
745
0
      header_expr = grep_true_expr();
746
0
    header_expr = grep_or_expr(header_group[fld], header_expr);
747
0
  }
748
0
  return header_expr;
749
0
}
750
751
static struct grep_expr *grep_splice_or(struct grep_expr *x, struct grep_expr *y)
752
0
{
753
0
  struct grep_expr *z = x;
754
755
0
  while (x) {
756
0
    assert(x->node == GREP_NODE_OR);
757
0
    if (x->u.binary.right &&
758
0
        x->u.binary.right->node == GREP_NODE_TRUE) {
759
0
      x->u.binary.right = y;
760
0
      break;
761
0
    }
762
0
    x = x->u.binary.right;
763
0
  }
764
0
  return z;
765
0
}
766
767
void compile_grep_patterns(struct grep_opt *opt)
768
0
{
769
0
  struct grep_pat *p;
770
0
  struct grep_expr *header_expr = prep_header_patterns(opt);
771
0
  int extended = 0;
772
773
0
  for (p = opt->pattern_list; p; p = p->next) {
774
0
    switch (p->token) {
775
0
    case GREP_PATTERN: /* atom */
776
0
    case GREP_PATTERN_HEAD:
777
0
    case GREP_PATTERN_BODY:
778
0
      compile_regexp(p, opt);
779
0
      break;
780
0
    default:
781
0
      extended = 1;
782
0
      break;
783
0
    }
784
0
  }
785
786
0
  if (opt->all_match || opt->no_body_match || header_expr)
787
0
    extended = 1;
788
0
  else if (!extended)
789
0
    return;
790
791
0
  p = opt->pattern_list;
792
0
  if (p)
793
0
    opt->pattern_expression = compile_pattern_expr(&p);
794
0
  if (p)
795
0
    die("incomplete pattern expression group: %s", p->pattern);
796
797
0
  if (opt->no_body_match && opt->pattern_expression)
798
0
    opt->pattern_expression = grep_not_expr(opt->pattern_expression);
799
800
0
  if (!header_expr)
801
0
    return;
802
803
0
  if (!opt->pattern_expression)
804
0
    opt->pattern_expression = header_expr;
805
0
  else if (opt->all_match)
806
0
    opt->pattern_expression = grep_splice_or(header_expr,
807
0
               opt->pattern_expression);
808
0
  else
809
0
    opt->pattern_expression = grep_or_expr(opt->pattern_expression,
810
0
                   header_expr);
811
0
  opt->all_match = 1;
812
0
}
813
814
static void free_pattern_expr(struct grep_expr *x)
815
0
{
816
0
  switch (x->node) {
817
0
  case GREP_NODE_TRUE:
818
0
  case GREP_NODE_ATOM:
819
0
    break;
820
0
  case GREP_NODE_NOT:
821
0
    free_pattern_expr(x->u.unary);
822
0
    break;
823
0
  case GREP_NODE_AND:
824
0
  case GREP_NODE_OR:
825
0
    free_pattern_expr(x->u.binary.left);
826
0
    free_pattern_expr(x->u.binary.right);
827
0
    break;
828
0
  }
829
0
  free(x);
830
0
}
831
832
static void free_grep_pat(struct grep_pat *pattern)
833
0
{
834
0
  struct grep_pat *p, *n;
835
836
0
  for (p = pattern; p; p = n) {
837
0
    n = p->next;
838
0
    switch (p->token) {
839
0
    case GREP_PATTERN: /* atom */
840
0
    case GREP_PATTERN_HEAD:
841
0
    case GREP_PATTERN_BODY:
842
0
      if (p->pcre2_pattern)
843
0
        free_pcre2_pattern(p);
844
0
      else
845
0
        regfree(&p->regexp);
846
0
      free(p->pattern);
847
0
      break;
848
0
    default:
849
0
      break;
850
0
    }
851
0
    free(p);
852
0
  }
853
0
}
854
855
void free_grep_patterns(struct grep_opt *opt)
856
0
{
857
0
  free_grep_pat(opt->pattern_list);
858
0
  free_grep_pat(opt->header_list);
859
860
0
  if (opt->pattern_expression)
861
0
    free_pattern_expr(opt->pattern_expression);
862
0
}
863
864
static const char *end_of_line(const char *cp, unsigned long *left)
865
0
{
866
0
  unsigned long l = *left;
867
0
  while (l && *cp != '\n') {
868
0
    l--;
869
0
    cp++;
870
0
  }
871
0
  *left = l;
872
0
  return cp;
873
0
}
874
875
static int word_char(char ch)
876
0
{
877
0
  return isalnum(ch) || ch == '_';
878
0
}
879
880
static void output_color(struct grep_opt *opt, const void *data, size_t size,
881
       const char *color)
882
0
{
883
0
  if (want_color(opt->color) && color && color[0]) {
884
0
    opt->output(opt, color, strlen(color));
885
0
    opt->output(opt, data, size);
886
0
    opt->output(opt, GIT_COLOR_RESET, strlen(GIT_COLOR_RESET));
887
0
  } else
888
0
    opt->output(opt, data, size);
889
0
}
890
891
static void output_sep(struct grep_opt *opt, char sign)
892
0
{
893
0
  if (opt->null_following_name)
894
0
    opt->output(opt, "\0", 1);
895
0
  else
896
0
    output_color(opt, &sign, 1, opt->colors[GREP_COLOR_SEP]);
897
0
}
898
899
static void show_name(struct grep_opt *opt, const char *name)
900
0
{
901
0
  output_color(opt, name, strlen(name), opt->colors[GREP_COLOR_FILENAME]);
902
0
  opt->output(opt, opt->null_following_name ? "\0" : "\n", 1);
903
0
}
904
905
static int patmatch(struct grep_pat *p,
906
        const char *line, const char *eol,
907
        regmatch_t *match, int eflags)
908
0
{
909
0
  int hit;
910
911
0
  if (p->pcre2_pattern)
912
0
    hit = !pcre2match(p, line, eol, match, eflags);
913
0
  else
914
0
    hit = !regexec_buf(&p->regexp, line, eol - line, 1, match,
915
0
           eflags);
916
917
0
  return hit;
918
0
}
919
920
static void strip_timestamp(const char *bol, const char **eol_p)
921
0
{
922
0
  const char *eol = *eol_p;
923
924
0
  while (bol < --eol) {
925
0
    if (*eol != '>')
926
0
      continue;
927
0
    *eol_p = ++eol;
928
0
    break;
929
0
  }
930
0
}
931
932
static struct {
933
  const char *field;
934
  size_t len;
935
} header_field[] = {
936
  { "author ", 7 },
937
  { "committer ", 10 },
938
  { "reflog ", 7 },
939
};
940
941
static int headerless_match_one_pattern(struct grep_pat *p,
942
          const char *bol, const char *eol,
943
          enum grep_context ctx,
944
          regmatch_t *pmatch, int eflags)
945
0
{
946
0
  int hit = 0;
947
0
  const char *start = bol;
948
949
0
  if ((p->token != GREP_PATTERN) &&
950
0
      ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD)))
951
0
    return 0;
952
953
0
 again:
954
0
  hit = patmatch(p, bol, eol, pmatch, eflags);
955
956
0
  if (hit && p->word_regexp) {
957
0
    if ((pmatch[0].rm_so < 0) ||
958
0
        (eol - bol) < pmatch[0].rm_so ||
959
0
        (pmatch[0].rm_eo < 0) ||
960
0
        (eol - bol) < pmatch[0].rm_eo)
961
0
      die("regexp returned nonsense");
962
963
    /* Match beginning must be either beginning of the
964
     * line, or at word boundary (i.e. the last char must
965
     * not be a word char).  Similarly, match end must be
966
     * either end of the line, or at word boundary
967
     * (i.e. the next char must not be a word char).
968
     */
969
0
    if ( ((pmatch[0].rm_so == 0) ||
970
0
          !word_char(bol[pmatch[0].rm_so-1])) &&
971
0
         ((pmatch[0].rm_eo == (eol-bol)) ||
972
0
          !word_char(bol[pmatch[0].rm_eo])) )
973
0
      ;
974
0
    else
975
0
      hit = 0;
976
977
    /* Words consist of at least one character. */
978
0
    if (pmatch->rm_so == pmatch->rm_eo)
979
0
      hit = 0;
980
981
0
    if (!hit && pmatch[0].rm_so + bol + 1 < eol) {
982
      /* There could be more than one match on the
983
       * line, and the first match might not be
984
       * strict word match.  But later ones could be!
985
       * Forward to the next possible start, i.e. the
986
       * next position following a non-word char.
987
       */
988
0
      bol = pmatch[0].rm_so + bol + 1;
989
0
      while (word_char(bol[-1]) && bol < eol)
990
0
        bol++;
991
0
      eflags |= REG_NOTBOL;
992
0
      if (bol < eol)
993
0
        goto again;
994
0
    }
995
0
  }
996
0
  if (hit) {
997
0
    pmatch[0].rm_so += bol - start;
998
0
    pmatch[0].rm_eo += bol - start;
999
0
  }
1000
0
  return hit;
1001
0
}
1002
1003
static int match_one_pattern(struct grep_pat *p,
1004
           const char *bol, const char *eol,
1005
           enum grep_context ctx, regmatch_t *pmatch,
1006
           int eflags)
1007
0
{
1008
0
  const char *field;
1009
0
  size_t len;
1010
1011
0
  if (p->token == GREP_PATTERN_HEAD) {
1012
0
    assert(p->field < ARRAY_SIZE(header_field));
1013
0
    field = header_field[p->field].field;
1014
0
    len = header_field[p->field].len;
1015
0
    if (strncmp(bol, field, len))
1016
0
      return 0;
1017
0
    bol += len;
1018
1019
0
    switch (p->field) {
1020
0
    case GREP_HEADER_AUTHOR:
1021
0
    case GREP_HEADER_COMMITTER:
1022
0
      strip_timestamp(bol, &eol);
1023
0
      break;
1024
0
    default:
1025
0
      break;
1026
0
    }
1027
0
  }
1028
1029
0
  return headerless_match_one_pattern(p, bol, eol, ctx, pmatch, eflags);
1030
0
}
1031
1032
1033
static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x,
1034
         const char *bol, const char *eol,
1035
         enum grep_context ctx, ssize_t *col,
1036
         ssize_t *icol, int collect_hits)
1037
0
{
1038
0
  int h = 0;
1039
1040
0
  switch (x->node) {
1041
0
  case GREP_NODE_TRUE:
1042
0
    h = 1;
1043
0
    break;
1044
0
  case GREP_NODE_ATOM:
1045
0
    {
1046
0
      regmatch_t tmp;
1047
0
      h = match_one_pattern(x->u.atom, bol, eol, ctx,
1048
0
                &tmp, 0);
1049
0
      if (h && (*col < 0 || tmp.rm_so < *col))
1050
0
        *col = tmp.rm_so;
1051
0
    }
1052
0
    if (x->u.atom->token == GREP_PATTERN_BODY)
1053
0
      opt->body_hit |= h;
1054
0
    break;
1055
0
  case GREP_NODE_NOT:
1056
    /*
1057
     * Upon visiting a GREP_NODE_NOT, col and icol become swapped.
1058
     */
1059
0
    h = !match_expr_eval(opt, x->u.unary, bol, eol, ctx, icol, col,
1060
0
             0);
1061
0
    break;
1062
0
  case GREP_NODE_AND:
1063
0
    h = match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col,
1064
0
            icol, 0);
1065
0
    if (h || opt->columnnum) {
1066
      /*
1067
       * Don't short-circuit AND when given --column, since a
1068
       * NOT earlier in the tree may turn this into an OR. In
1069
       * this case, see the below comment.
1070
       */
1071
0
      h &= match_expr_eval(opt, x->u.binary.right, bol, eol,
1072
0
               ctx, col, icol, 0);
1073
0
    }
1074
0
    break;
1075
0
  case GREP_NODE_OR:
1076
0
    if (!(collect_hits || opt->columnnum)) {
1077
      /*
1078
       * Don't short-circuit OR when given --column (or
1079
       * collecting hits) to ensure we don't skip a later
1080
       * child that would produce an earlier match.
1081
       */
1082
0
      return (match_expr_eval(opt, x->u.binary.left, bol, eol,
1083
0
            ctx, col, icol, 0) ||
1084
0
        match_expr_eval(opt, x->u.binary.right, bol,
1085
0
            eol, ctx, col, icol, 0));
1086
0
    }
1087
0
    h = match_expr_eval(opt, x->u.binary.left, bol, eol, ctx, col,
1088
0
            icol, 0);
1089
0
    if (collect_hits)
1090
0
      x->u.binary.left->hit |= h;
1091
0
    h |= match_expr_eval(opt, x->u.binary.right, bol, eol, ctx, col,
1092
0
             icol, collect_hits);
1093
0
    break;
1094
0
  default:
1095
0
    die("Unexpected node type (internal error) %d", x->node);
1096
0
  }
1097
0
  if (collect_hits)
1098
0
    x->hit |= h;
1099
0
  return h;
1100
0
}
1101
1102
static int match_expr(struct grep_opt *opt,
1103
          const char *bol, const char *eol,
1104
          enum grep_context ctx, ssize_t *col,
1105
          ssize_t *icol, int collect_hits)
1106
0
{
1107
0
  struct grep_expr *x = opt->pattern_expression;
1108
0
  return match_expr_eval(opt, x, bol, eol, ctx, col, icol, collect_hits);
1109
0
}
1110
1111
static int match_line(struct grep_opt *opt,
1112
          const char *bol, const char *eol,
1113
          ssize_t *col, ssize_t *icol,
1114
          enum grep_context ctx, int collect_hits)
1115
0
{
1116
0
  struct grep_pat *p;
1117
0
  int hit = 0;
1118
1119
0
  if (opt->pattern_expression)
1120
0
    return match_expr(opt, bol, eol, ctx, col, icol,
1121
0
          collect_hits);
1122
1123
  /* we do not call with collect_hits without being extended */
1124
0
  for (p = opt->pattern_list; p; p = p->next) {
1125
0
    regmatch_t tmp;
1126
0
    if (match_one_pattern(p, bol, eol, ctx, &tmp, 0)) {
1127
0
      hit |= 1;
1128
0
      if (!opt->columnnum) {
1129
        /*
1130
         * Without --column, any single match on a line
1131
         * is enough to know that it needs to be
1132
         * printed. With --column, scan _all_ patterns
1133
         * to find the earliest.
1134
         */
1135
0
        break;
1136
0
      }
1137
0
      if (*col < 0 || tmp.rm_so < *col)
1138
0
        *col = tmp.rm_so;
1139
0
    }
1140
0
  }
1141
0
  return hit;
1142
0
}
1143
1144
static int match_next_pattern(struct grep_pat *p,
1145
            const char *bol, const char *eol,
1146
            enum grep_context ctx,
1147
            regmatch_t *pmatch, int eflags)
1148
0
{
1149
0
  regmatch_t match;
1150
1151
0
  if (!headerless_match_one_pattern(p, bol, eol, ctx, &match, eflags))
1152
0
    return 0;
1153
0
  if (match.rm_so < 0 || match.rm_eo < 0)
1154
0
    return 0;
1155
0
  if (pmatch->rm_so >= 0 && pmatch->rm_eo >= 0) {
1156
0
    if (match.rm_so > pmatch->rm_so)
1157
0
      return 1;
1158
0
    if (match.rm_so == pmatch->rm_so && match.rm_eo < pmatch->rm_eo)
1159
0
      return 1;
1160
0
  }
1161
0
  pmatch->rm_so = match.rm_so;
1162
0
  pmatch->rm_eo = match.rm_eo;
1163
0
  return 1;
1164
0
}
1165
1166
int grep_next_match(struct grep_opt *opt,
1167
        const char *bol, const char *eol,
1168
        enum grep_context ctx, regmatch_t *pmatch,
1169
        enum grep_header_field field, int eflags)
1170
0
{
1171
0
  struct grep_pat *p;
1172
0
  int hit = 0;
1173
1174
0
  pmatch->rm_so = pmatch->rm_eo = -1;
1175
0
  if (bol < eol) {
1176
0
    for (p = ((ctx == GREP_CONTEXT_HEAD)
1177
0
         ? opt->header_list : opt->pattern_list);
1178
0
        p; p = p->next) {
1179
0
      switch (p->token) {
1180
0
      case GREP_PATTERN_HEAD:
1181
0
        if ((field != GREP_HEADER_FIELD_MAX) &&
1182
0
            (p->field != field))
1183
0
          continue;
1184
        /* fall thru */
1185
0
      case GREP_PATTERN: /* atom */
1186
0
      case GREP_PATTERN_BODY:
1187
0
        hit |= match_next_pattern(p, bol, eol, ctx,
1188
0
                pmatch, eflags);
1189
0
        break;
1190
0
      default:
1191
0
        break;
1192
0
      }
1193
0
    }
1194
0
  }
1195
0
  return hit;
1196
0
}
1197
1198
static void show_line_header(struct grep_opt *opt, const char *name,
1199
           unsigned lno, ssize_t cno, char sign)
1200
0
{
1201
0
  if (opt->heading && opt->last_shown == 0) {
1202
0
    output_color(opt, name, strlen(name), opt->colors[GREP_COLOR_FILENAME]);
1203
0
    opt->output(opt, "\n", 1);
1204
0
  }
1205
0
  opt->last_shown = lno;
1206
1207
0
  if (!opt->heading && opt->pathname) {
1208
0
    output_color(opt, name, strlen(name), opt->colors[GREP_COLOR_FILENAME]);
1209
0
    output_sep(opt, sign);
1210
0
  }
1211
0
  if (opt->linenum) {
1212
0
    char buf[32];
1213
0
    xsnprintf(buf, sizeof(buf), "%d", lno);
1214
0
    output_color(opt, buf, strlen(buf), opt->colors[GREP_COLOR_LINENO]);
1215
0
    output_sep(opt, sign);
1216
0
  }
1217
  /*
1218
   * Treat 'cno' as the 1-indexed offset from the start of a non-context
1219
   * line to its first match. Otherwise, 'cno' is 0 indicating that we are
1220
   * being called with a context line.
1221
   */
1222
0
  if (opt->columnnum && cno) {
1223
0
    char buf[32];
1224
0
    xsnprintf(buf, sizeof(buf), "%"PRIuMAX, (uintmax_t)cno);
1225
0
    output_color(opt, buf, strlen(buf), opt->colors[GREP_COLOR_COLUMNNO]);
1226
0
    output_sep(opt, sign);
1227
0
  }
1228
0
}
1229
1230
static void show_line(struct grep_opt *opt,
1231
          const char *bol, const char *eol,
1232
          const char *name, unsigned lno, ssize_t cno, char sign)
1233
0
{
1234
0
  int rest = eol - bol;
1235
0
  const char *match_color = NULL;
1236
0
  const char *line_color = NULL;
1237
1238
0
  if (opt->file_break && opt->last_shown == 0) {
1239
0
    if (opt->show_hunk_mark)
1240
0
      opt->output(opt, "\n", 1);
1241
0
  } else if (opt->pre_context || opt->post_context || opt->funcbody) {
1242
0
    if (opt->last_shown == 0) {
1243
0
      if (opt->show_hunk_mark) {
1244
0
        output_color(opt, "--", 2, opt->colors[GREP_COLOR_SEP]);
1245
0
        opt->output(opt, "\n", 1);
1246
0
      }
1247
0
    } else if (lno > opt->last_shown + 1) {
1248
0
      output_color(opt, "--", 2, opt->colors[GREP_COLOR_SEP]);
1249
0
      opt->output(opt, "\n", 1);
1250
0
    }
1251
0
  }
1252
0
  if (!opt->only_matching) {
1253
    /*
1254
     * In case the line we're being called with contains more than
1255
     * one match, leave printing each header to the loop below.
1256
     */
1257
0
    show_line_header(opt, name, lno, cno, sign);
1258
0
  }
1259
0
  if (opt->color || opt->only_matching) {
1260
0
    regmatch_t match;
1261
0
    enum grep_context ctx = GREP_CONTEXT_BODY;
1262
0
    int eflags = 0;
1263
1264
0
    if (opt->color) {
1265
0
      if (sign == ':')
1266
0
        match_color = opt->colors[GREP_COLOR_MATCH_SELECTED];
1267
0
      else
1268
0
        match_color = opt->colors[GREP_COLOR_MATCH_CONTEXT];
1269
0
      if (sign == ':')
1270
0
        line_color = opt->colors[GREP_COLOR_SELECTED];
1271
0
      else if (sign == '-')
1272
0
        line_color = opt->colors[GREP_COLOR_CONTEXT];
1273
0
      else if (sign == '=')
1274
0
        line_color = opt->colors[GREP_COLOR_FUNCTION];
1275
0
    }
1276
0
    while (grep_next_match(opt, bol, eol, ctx, &match,
1277
0
               GREP_HEADER_FIELD_MAX, eflags)) {
1278
0
      if (match.rm_so == match.rm_eo)
1279
0
        break;
1280
1281
0
      if (opt->only_matching)
1282
0
        show_line_header(opt, name, lno, cno, sign);
1283
0
      else
1284
0
        output_color(opt, bol, match.rm_so, line_color);
1285
0
      output_color(opt, bol + match.rm_so,
1286
0
             match.rm_eo - match.rm_so, match_color);
1287
0
      if (opt->only_matching)
1288
0
        opt->output(opt, "\n", 1);
1289
0
      bol += match.rm_eo;
1290
0
      cno += match.rm_eo;
1291
0
      rest -= match.rm_eo;
1292
0
      eflags = REG_NOTBOL;
1293
0
    }
1294
0
  }
1295
0
  if (!opt->only_matching) {
1296
0
    output_color(opt, bol, rest, line_color);
1297
0
    opt->output(opt, "\n", 1);
1298
0
  }
1299
0
}
1300
1301
int grep_use_locks;
1302
1303
/*
1304
 * This lock protects access to the gitattributes machinery, which is
1305
 * not thread-safe.
1306
 */
1307
pthread_mutex_t grep_attr_mutex;
1308
1309
static inline void grep_attr_lock(void)
1310
0
{
1311
0
  if (grep_use_locks)
1312
0
    pthread_mutex_lock(&grep_attr_mutex);
1313
0
}
1314
1315
static inline void grep_attr_unlock(void)
1316
0
{
1317
0
  if (grep_use_locks)
1318
0
    pthread_mutex_unlock(&grep_attr_mutex);
1319
0
}
1320
1321
static int match_funcname(struct grep_opt *opt, struct grep_source *gs,
1322
        const char *bol, const char *eol)
1323
0
{
1324
0
  xdemitconf_t *xecfg = opt->priv;
1325
0
  if (xecfg && !xecfg->find_func) {
1326
0
    grep_source_load_driver(gs, opt->repo->index);
1327
0
    if (gs->driver->funcname.pattern) {
1328
0
      const struct userdiff_funcname *pe = &gs->driver->funcname;
1329
0
      xdiff_set_find_func(xecfg, pe->pattern, pe->cflags);
1330
0
    } else {
1331
0
      xecfg = opt->priv = NULL;
1332
0
    }
1333
0
  }
1334
1335
0
  if (xecfg) {
1336
0
    char buf[1];
1337
0
    return xecfg->find_func(bol, eol - bol, buf, 1,
1338
0
          xecfg->find_func_priv) >= 0;
1339
0
  }
1340
1341
0
  if (bol == eol)
1342
0
    return 0;
1343
0
  if (isalpha(*bol) || *bol == '_' || *bol == '$')
1344
0
    return 1;
1345
0
  return 0;
1346
0
}
1347
1348
static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
1349
             const char *bol, unsigned lno)
1350
0
{
1351
0
  while (bol > gs->buf) {
1352
0
    const char *eol = --bol;
1353
1354
0
    while (bol > gs->buf && bol[-1] != '\n')
1355
0
      bol--;
1356
0
    lno--;
1357
1358
0
    if (lno <= opt->last_shown)
1359
0
      break;
1360
1361
0
    if (match_funcname(opt, gs, bol, eol)) {
1362
0
      show_line(opt, bol, eol, gs->name, lno, 0, '=');
1363
0
      break;
1364
0
    }
1365
0
  }
1366
0
}
1367
1368
static int is_empty_line(const char *bol, const char *eol);
1369
1370
static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
1371
           const char *bol, const char *end, unsigned lno)
1372
0
{
1373
0
  unsigned cur = lno, from = 1, funcname_lno = 0, orig_from;
1374
0
  int funcname_needed = !!opt->funcname, comment_needed = 0;
1375
1376
0
  if (opt->pre_context < lno)
1377
0
    from = lno - opt->pre_context;
1378
0
  if (from <= opt->last_shown)
1379
0
    from = opt->last_shown + 1;
1380
0
  orig_from = from;
1381
0
  if (opt->funcbody) {
1382
0
    if (match_funcname(opt, gs, bol, end))
1383
0
      comment_needed = 1;
1384
0
    else
1385
0
      funcname_needed = 1;
1386
0
    from = opt->last_shown + 1;
1387
0
  }
1388
1389
  /* Rewind. */
1390
0
  while (bol > gs->buf && cur > from) {
1391
0
    const char *next_bol = bol;
1392
0
    const char *eol = --bol;
1393
1394
0
    while (bol > gs->buf && bol[-1] != '\n')
1395
0
      bol--;
1396
0
    cur--;
1397
0
    if (comment_needed && (is_empty_line(bol, eol) ||
1398
0
               match_funcname(opt, gs, bol, eol))) {
1399
0
      comment_needed = 0;
1400
0
      from = orig_from;
1401
0
      if (cur < from) {
1402
0
        cur++;
1403
0
        bol = next_bol;
1404
0
        break;
1405
0
      }
1406
0
    }
1407
0
    if (funcname_needed && match_funcname(opt, gs, bol, eol)) {
1408
0
      funcname_lno = cur;
1409
0
      funcname_needed = 0;
1410
0
      if (opt->funcbody)
1411
0
        comment_needed = 1;
1412
0
      else
1413
0
        from = orig_from;
1414
0
    }
1415
0
  }
1416
1417
  /* We need to look even further back to find a function signature. */
1418
0
  if (opt->funcname && funcname_needed)
1419
0
    show_funcname_line(opt, gs, bol, cur);
1420
1421
  /* Back forward. */
1422
0
  while (cur < lno) {
1423
0
    const char *eol = bol, sign = (cur == funcname_lno) ? '=' : '-';
1424
1425
0
    while (*eol != '\n')
1426
0
      eol++;
1427
0
    show_line(opt, bol, eol, gs->name, cur, 0, sign);
1428
0
    bol = eol + 1;
1429
0
    cur++;
1430
0
  }
1431
0
}
1432
1433
static int should_lookahead(struct grep_opt *opt)
1434
0
{
1435
0
  struct grep_pat *p;
1436
1437
0
  if (opt->pattern_expression)
1438
0
    return 0; /* punt for too complex stuff */
1439
0
  if (opt->invert)
1440
0
    return 0;
1441
0
  for (p = opt->pattern_list; p; p = p->next) {
1442
0
    if (p->token != GREP_PATTERN)
1443
0
      return 0; /* punt for "header only" and stuff */
1444
0
  }
1445
0
  return 1;
1446
0
}
1447
1448
static int look_ahead(struct grep_opt *opt,
1449
          unsigned long *left_p,
1450
          unsigned *lno_p,
1451
          const char **bol_p)
1452
0
{
1453
0
  unsigned lno = *lno_p;
1454
0
  const char *bol = *bol_p;
1455
0
  struct grep_pat *p;
1456
0
  const char *sp, *last_bol;
1457
0
  regoff_t earliest = -1;
1458
1459
0
  for (p = opt->pattern_list; p; p = p->next) {
1460
0
    int hit;
1461
0
    regmatch_t m;
1462
1463
0
    hit = patmatch(p, bol, bol + *left_p, &m, 0);
1464
0
    if (!hit || m.rm_so < 0 || m.rm_eo < 0)
1465
0
      continue;
1466
0
    if (earliest < 0 || m.rm_so < earliest)
1467
0
      earliest = m.rm_so;
1468
0
  }
1469
1470
0
  if (earliest < 0) {
1471
0
    *bol_p = bol + *left_p;
1472
0
    *left_p = 0;
1473
0
    return 1;
1474
0
  }
1475
0
  for (sp = bol + earliest; bol < sp && sp[-1] != '\n'; sp--)
1476
0
    ; /* find the beginning of the line */
1477
0
  last_bol = sp;
1478
1479
0
  for (sp = bol; sp < last_bol; sp++) {
1480
0
    if (*sp == '\n')
1481
0
      lno++;
1482
0
  }
1483
0
  *left_p -= last_bol - bol;
1484
0
  *bol_p = last_bol;
1485
0
  *lno_p = lno;
1486
0
  return 0;
1487
0
}
1488
1489
static int fill_textconv_grep(struct repository *r,
1490
            struct userdiff_driver *driver,
1491
            struct grep_source *gs)
1492
0
{
1493
0
  struct diff_filespec *df;
1494
0
  char *buf;
1495
0
  size_t size;
1496
1497
0
  if (!driver || !driver->textconv)
1498
0
    return grep_source_load(gs);
1499
1500
  /*
1501
   * The textconv interface is intimately tied to diff_filespecs, so we
1502
   * have to pretend to be one. If we could unify the grep_source
1503
   * and diff_filespec structs, this mess could just go away.
1504
   */
1505
0
  df = alloc_filespec(gs->path);
1506
0
  switch (gs->type) {
1507
0
  case GREP_SOURCE_OID:
1508
0
    fill_filespec(df, gs->identifier, 1, 0100644);
1509
0
    break;
1510
0
  case GREP_SOURCE_FILE:
1511
0
    fill_filespec(df, null_oid(), 0, 0100644);
1512
0
    break;
1513
0
  default:
1514
0
    BUG("attempt to textconv something without a path?");
1515
0
  }
1516
1517
  /*
1518
   * fill_textconv is not remotely thread-safe; it modifies the global
1519
   * diff tempfile structure, writes to the_repo's odb and might
1520
   * internally call thread-unsafe functions such as the
1521
   * prepare_packed_git() lazy-initializator. Because of the last two, we
1522
   * must ensure mutual exclusion between this call and the object reading
1523
   * API, thus we use obj_read_lock() here.
1524
   *
1525
   * TODO: allowing text conversion to run in parallel with object
1526
   * reading operations might increase performance in the multithreaded
1527
   * non-worktreee git-grep with --textconv.
1528
   */
1529
0
  obj_read_lock();
1530
0
  size = fill_textconv(r, driver, df, &buf);
1531
0
  obj_read_unlock();
1532
0
  free_filespec(df);
1533
1534
  /*
1535
   * The normal fill_textconv usage by the diff machinery would just keep
1536
   * the textconv'd buf separate from the diff_filespec. But much of the
1537
   * grep code passes around a grep_source and assumes that its "buf"
1538
   * pointer is the beginning of the thing we are searching. So let's
1539
   * install our textconv'd version into the grep_source, taking care not
1540
   * to leak any existing buffer.
1541
   */
1542
0
  grep_source_clear_data(gs);
1543
0
  gs->buf = buf;
1544
0
  gs->size = size;
1545
1546
0
  return 0;
1547
0
}
1548
1549
static int is_empty_line(const char *bol, const char *eol)
1550
0
{
1551
0
  while (bol < eol && isspace(*bol))
1552
0
    bol++;
1553
0
  return bol == eol;
1554
0
}
1555
1556
static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
1557
0
{
1558
0
  const char *bol;
1559
0
  const char *peek_bol = NULL;
1560
0
  unsigned long left;
1561
0
  unsigned lno = 1;
1562
0
  unsigned last_hit = 0;
1563
0
  int binary_match_only = 0;
1564
0
  unsigned count = 0;
1565
0
  int try_lookahead = 0;
1566
0
  int show_function = 0;
1567
0
  struct userdiff_driver *textconv = NULL;
1568
0
  enum grep_context ctx = GREP_CONTEXT_HEAD;
1569
0
  xdemitconf_t xecfg;
1570
1571
0
  if (!opt->status_only && gs->name == NULL)
1572
0
    BUG("grep call which could print a name requires "
1573
0
        "grep_source.name be non-NULL");
1574
1575
0
  if (!opt->output)
1576
0
    opt->output = std_output;
1577
1578
0
  if (opt->pre_context || opt->post_context || opt->file_break ||
1579
0
      opt->funcbody) {
1580
    /* Show hunk marks, except for the first file. */
1581
0
    if (opt->last_shown)
1582
0
      opt->show_hunk_mark = 1;
1583
    /*
1584
     * If we're using threads then we can't easily identify
1585
     * the first file.  Always put hunk marks in that case
1586
     * and skip the very first one later in work_done().
1587
     */
1588
0
    if (opt->output != std_output)
1589
0
      opt->show_hunk_mark = 1;
1590
0
  }
1591
0
  opt->last_shown = 0;
1592
1593
0
  if (opt->allow_textconv) {
1594
0
    grep_source_load_driver(gs, opt->repo->index);
1595
    /*
1596
     * We might set up the shared textconv cache data here, which
1597
     * is not thread-safe. Also, get_oid_with_context() and
1598
     * parse_object() might be internally called. As they are not
1599
     * currently thread-safe and might be racy with object reading,
1600
     * obj_read_lock() must be called.
1601
     */
1602
0
    grep_attr_lock();
1603
0
    obj_read_lock();
1604
0
    textconv = userdiff_get_textconv(opt->repo, gs->driver);
1605
0
    obj_read_unlock();
1606
0
    grep_attr_unlock();
1607
0
  }
1608
1609
  /*
1610
   * We know the result of a textconv is text, so we only have to care
1611
   * about binary handling if we are not using it.
1612
   */
1613
0
  if (!textconv) {
1614
0
    switch (opt->binary) {
1615
0
    case GREP_BINARY_DEFAULT:
1616
0
      if (grep_source_is_binary(gs, opt->repo->index))
1617
0
        binary_match_only = 1;
1618
0
      break;
1619
0
    case GREP_BINARY_NOMATCH:
1620
0
      if (grep_source_is_binary(gs, opt->repo->index))
1621
0
        return 0; /* Assume unmatch */
1622
0
      break;
1623
0
    case GREP_BINARY_TEXT:
1624
0
      break;
1625
0
    default:
1626
0
      BUG("unknown binary handling mode");
1627
0
    }
1628
0
  }
1629
1630
0
  memset(&xecfg, 0, sizeof(xecfg));
1631
0
  opt->priv = &xecfg;
1632
1633
0
  try_lookahead = should_lookahead(opt);
1634
1635
0
  if (fill_textconv_grep(opt->repo, textconv, gs) < 0)
1636
0
    return 0;
1637
1638
0
  bol = gs->buf;
1639
0
  left = gs->size;
1640
0
  while (left) {
1641
0
    const char *eol;
1642
0
    int hit;
1643
0
    ssize_t cno;
1644
0
    ssize_t col = -1, icol = -1;
1645
1646
    /*
1647
     * look_ahead() skips quickly to the line that possibly
1648
     * has the next hit; don't call it if we need to do
1649
     * something more than just skipping the current line
1650
     * in response to an unmatch for the current line.  E.g.
1651
     * inside a post-context window, we will show the current
1652
     * line as a context around the previous hit when it
1653
     * doesn't hit.
1654
     */
1655
0
    if (try_lookahead
1656
0
        && !(last_hit
1657
0
       && (show_function ||
1658
0
           lno <= last_hit + opt->post_context))
1659
0
        && look_ahead(opt, &left, &lno, &bol))
1660
0
      break;
1661
0
    eol = end_of_line(bol, &left);
1662
1663
0
    if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol))
1664
0
      ctx = GREP_CONTEXT_BODY;
1665
1666
0
    hit = match_line(opt, bol, eol, &col, &icol, ctx, collect_hits);
1667
1668
0
    if (collect_hits)
1669
0
      goto next_line;
1670
1671
    /* "grep -v -e foo -e bla" should list lines
1672
     * that do not have either, so inversion should
1673
     * be done outside.
1674
     */
1675
0
    if (opt->invert)
1676
0
      hit = !hit;
1677
0
    if (opt->unmatch_name_only) {
1678
0
      if (hit)
1679
0
        return 0;
1680
0
      goto next_line;
1681
0
    }
1682
0
    if (hit && (opt->max_count < 0 || count < opt->max_count)) {
1683
0
      count++;
1684
0
      if (opt->status_only)
1685
0
        return 1;
1686
0
      if (opt->name_only) {
1687
0
        show_name(opt, gs->name);
1688
0
        return 1;
1689
0
      }
1690
0
      if (opt->count)
1691
0
        goto next_line;
1692
0
      if (binary_match_only) {
1693
0
        opt->output(opt, "Binary file ", 12);
1694
0
        output_color(opt, gs->name, strlen(gs->name),
1695
0
               opt->colors[GREP_COLOR_FILENAME]);
1696
0
        opt->output(opt, " matches\n", 9);
1697
0
        return 1;
1698
0
      }
1699
      /* Hit at this line.  If we haven't shown the
1700
       * pre-context lines, we would need to show them.
1701
       */
1702
0
      if (opt->pre_context || opt->funcbody)
1703
0
        show_pre_context(opt, gs, bol, eol, lno);
1704
0
      else if (opt->funcname)
1705
0
        show_funcname_line(opt, gs, bol, lno);
1706
0
      cno = opt->invert ? icol : col;
1707
0
      if (cno < 0) {
1708
        /*
1709
         * A negative cno indicates that there was no
1710
         * match on the line. We are thus inverted and
1711
         * being asked to show all lines that _don't_
1712
         * match a given expression. Therefore, set cno
1713
         * to 0 to suggest the whole line matches.
1714
         */
1715
0
        cno = 0;
1716
0
      }
1717
0
      show_line(opt, bol, eol, gs->name, lno, cno + 1, ':');
1718
0
      last_hit = lno;
1719
0
      if (opt->funcbody)
1720
0
        show_function = 1;
1721
0
      goto next_line;
1722
0
    }
1723
0
    if (show_function && (!peek_bol || peek_bol < bol)) {
1724
0
      unsigned long peek_left = left;
1725
0
      const char *peek_eol = eol;
1726
1727
      /*
1728
       * Trailing empty lines are not interesting.
1729
       * Peek past them to see if they belong to the
1730
       * body of the current function.
1731
       */
1732
0
      peek_bol = bol;
1733
0
      while (is_empty_line(peek_bol, peek_eol)) {
1734
0
        peek_bol = peek_eol + 1;
1735
0
        peek_eol = end_of_line(peek_bol, &peek_left);
1736
0
      }
1737
1738
0
      if (peek_bol >= gs->buf + gs->size ||
1739
0
          match_funcname(opt, gs, peek_bol, peek_eol))
1740
0
        show_function = 0;
1741
0
    }
1742
0
    if (show_function ||
1743
0
        (last_hit && lno <= last_hit + opt->post_context)) {
1744
      /* If the last hit is within the post context,
1745
       * we need to show this line.
1746
       */
1747
0
      show_line(opt, bol, eol, gs->name, lno, col + 1, '-');
1748
0
    }
1749
1750
0
  next_line:
1751
0
    bol = eol + 1;
1752
0
    if (!left)
1753
0
      break;
1754
0
    left--;
1755
0
    lno++;
1756
0
  }
1757
1758
0
  if (collect_hits)
1759
0
    return 0;
1760
1761
0
  if (opt->status_only)
1762
0
    return opt->unmatch_name_only;
1763
0
  if (opt->unmatch_name_only) {
1764
    /* We did not see any hit, so we want to show this */
1765
0
    show_name(opt, gs->name);
1766
0
    return 1;
1767
0
  }
1768
1769
0
  xdiff_clear_find_func(&xecfg);
1770
0
  opt->priv = NULL;
1771
1772
  /* NEEDSWORK:
1773
   * The real "grep -c foo *.c" gives many "bar.c:0" lines,
1774
   * which feels mostly useless but sometimes useful.  Maybe
1775
   * make it another option?  For now suppress them.
1776
   */
1777
0
  if (opt->count && count) {
1778
0
    char buf[32];
1779
0
    if (opt->pathname) {
1780
0
      output_color(opt, gs->name, strlen(gs->name),
1781
0
             opt->colors[GREP_COLOR_FILENAME]);
1782
0
      output_sep(opt, ':');
1783
0
    }
1784
0
    xsnprintf(buf, sizeof(buf), "%u\n", count);
1785
0
    opt->output(opt, buf, strlen(buf));
1786
0
    return 1;
1787
0
  }
1788
0
  return !!last_hit;
1789
0
}
1790
1791
static void clr_hit_marker(struct grep_expr *x)
1792
0
{
1793
  /* All-hit markers are meaningful only at the very top level
1794
   * OR node.
1795
   */
1796
0
  while (1) {
1797
0
    x->hit = 0;
1798
0
    if (x->node != GREP_NODE_OR)
1799
0
      return;
1800
0
    x->u.binary.left->hit = 0;
1801
0
    x = x->u.binary.right;
1802
0
  }
1803
0
}
1804
1805
static int chk_hit_marker(struct grep_expr *x)
1806
0
{
1807
  /* Top level nodes have hit markers.  See if they all are hits */
1808
0
  while (1) {
1809
0
    if (x->node != GREP_NODE_OR)
1810
0
      return x->hit;
1811
0
    if (!x->u.binary.left->hit)
1812
0
      return 0;
1813
0
    x = x->u.binary.right;
1814
0
  }
1815
0
}
1816
1817
int grep_source(struct grep_opt *opt, struct grep_source *gs)
1818
0
{
1819
  /*
1820
   * we do not have to do the two-pass grep when we do not check
1821
   * buffer-wide "all-match".
1822
   */
1823
0
  if (!opt->all_match && !opt->no_body_match)
1824
0
    return grep_source_1(opt, gs, 0);
1825
1826
  /* Otherwise the toplevel "or" terms hit a bit differently.
1827
   * We first clear hit markers from them.
1828
   */
1829
0
  clr_hit_marker(opt->pattern_expression);
1830
0
  opt->body_hit = 0;
1831
0
  grep_source_1(opt, gs, 1);
1832
1833
0
  if (opt->all_match && !chk_hit_marker(opt->pattern_expression))
1834
0
    return 0;
1835
0
  if (opt->no_body_match && opt->body_hit)
1836
0
    return 0;
1837
1838
0
  return grep_source_1(opt, gs, 0);
1839
0
}
1840
1841
static void grep_source_init_buf(struct grep_source *gs,
1842
         const char *buf,
1843
         unsigned long size)
1844
0
{
1845
0
  gs->type = GREP_SOURCE_BUF;
1846
0
  gs->name = NULL;
1847
0
  gs->path = NULL;
1848
0
  gs->buf = buf;
1849
0
  gs->size = size;
1850
0
  gs->driver = NULL;
1851
0
  gs->identifier = NULL;
1852
0
}
1853
1854
int grep_buffer(struct grep_opt *opt, const char *buf, unsigned long size)
1855
0
{
1856
0
  struct grep_source gs;
1857
0
  int r;
1858
1859
0
  grep_source_init_buf(&gs, buf, size);
1860
1861
0
  r = grep_source(opt, &gs);
1862
1863
0
  grep_source_clear(&gs);
1864
0
  return r;
1865
0
}
1866
1867
void grep_source_init_file(struct grep_source *gs, const char *name,
1868
         const char *path)
1869
0
{
1870
0
  gs->type = GREP_SOURCE_FILE;
1871
0
  gs->name = xstrdup_or_null(name);
1872
0
  gs->path = xstrdup_or_null(path);
1873
0
  gs->buf = NULL;
1874
0
  gs->size = 0;
1875
0
  gs->driver = NULL;
1876
0
  gs->identifier = xstrdup(path);
1877
0
}
1878
1879
void grep_source_init_oid(struct grep_source *gs, const char *name,
1880
        const char *path, const struct object_id *oid,
1881
        struct repository *repo)
1882
0
{
1883
0
  gs->type = GREP_SOURCE_OID;
1884
0
  gs->name = xstrdup_or_null(name);
1885
0
  gs->path = xstrdup_or_null(path);
1886
0
  gs->buf = NULL;
1887
0
  gs->size = 0;
1888
0
  gs->driver = NULL;
1889
0
  gs->identifier = oiddup(oid);
1890
0
  gs->repo = repo;
1891
0
}
1892
1893
void grep_source_clear(struct grep_source *gs)
1894
0
{
1895
0
  FREE_AND_NULL(gs->name);
1896
0
  FREE_AND_NULL(gs->path);
1897
0
  FREE_AND_NULL(gs->identifier);
1898
0
  grep_source_clear_data(gs);
1899
0
}
1900
1901
void grep_source_clear_data(struct grep_source *gs)
1902
0
{
1903
0
  switch (gs->type) {
1904
0
  case GREP_SOURCE_FILE:
1905
0
  case GREP_SOURCE_OID:
1906
    /* these types own the buffer */
1907
0
    free((char *)gs->buf);
1908
0
    gs->buf = NULL;
1909
0
    gs->size = 0;
1910
0
    break;
1911
0
  case GREP_SOURCE_BUF:
1912
    /* leave user-provided buf intact */
1913
0
    break;
1914
0
  }
1915
0
}
1916
1917
static int grep_source_load_oid(struct grep_source *gs)
1918
0
{
1919
0
  enum object_type type;
1920
1921
0
  gs->buf = repo_read_object_file(gs->repo, gs->identifier, &type,
1922
0
          &gs->size);
1923
0
  if (!gs->buf)
1924
0
    return error(_("'%s': unable to read %s"),
1925
0
           gs->name,
1926
0
           oid_to_hex(gs->identifier));
1927
0
  return 0;
1928
0
}
1929
1930
static int grep_source_load_file(struct grep_source *gs)
1931
0
{
1932
0
  const char *filename = gs->identifier;
1933
0
  struct stat st;
1934
0
  char *data;
1935
0
  size_t size;
1936
0
  int i;
1937
1938
0
  if (lstat(filename, &st) < 0) {
1939
0
  err_ret:
1940
0
    if (errno != ENOENT)
1941
0
      error_errno(_("failed to stat '%s'"), filename);
1942
0
    return -1;
1943
0
  }
1944
0
  if (!S_ISREG(st.st_mode))
1945
0
    return -1;
1946
0
  size = xsize_t(st.st_size);
1947
0
  i = open(filename, O_RDONLY);
1948
0
  if (i < 0)
1949
0
    goto err_ret;
1950
0
  data = xmallocz(size);
1951
0
  if (st.st_size != read_in_full(i, data, size)) {
1952
0
    error_errno(_("'%s': short read"), filename);
1953
0
    close(i);
1954
0
    free(data);
1955
0
    return -1;
1956
0
  }
1957
0
  close(i);
1958
1959
0
  gs->buf = data;
1960
0
  gs->size = size;
1961
0
  return 0;
1962
0
}
1963
1964
static int grep_source_load(struct grep_source *gs)
1965
0
{
1966
0
  if (gs->buf)
1967
0
    return 0;
1968
1969
0
  switch (gs->type) {
1970
0
  case GREP_SOURCE_FILE:
1971
0
    return grep_source_load_file(gs);
1972
0
  case GREP_SOURCE_OID:
1973
0
    return grep_source_load_oid(gs);
1974
0
  case GREP_SOURCE_BUF:
1975
0
    return gs->buf ? 0 : -1;
1976
0
  }
1977
0
  BUG("invalid grep_source type to load");
1978
0
}
1979
1980
void grep_source_load_driver(struct grep_source *gs,
1981
           struct index_state *istate)
1982
0
{
1983
0
  if (gs->driver)
1984
0
    return;
1985
1986
0
  grep_attr_lock();
1987
0
  if (gs->path)
1988
0
    gs->driver = userdiff_find_by_path(istate, gs->path);
1989
0
  if (!gs->driver)
1990
0
    gs->driver = userdiff_find_by_name("default");
1991
0
  grep_attr_unlock();
1992
0
}
1993
1994
static int grep_source_is_binary(struct grep_source *gs,
1995
         struct index_state *istate)
1996
0
{
1997
0
  grep_source_load_driver(gs, istate);
1998
0
  if (gs->driver->binary != -1)
1999
0
    return gs->driver->binary;
2000
2001
0
  if (!grep_source_load(gs))
2002
0
    return buffer_is_binary(gs->buf, gs->size);
2003
2004
0
  return 0;
2005
0
}