Coverage Report

Created: 2025-12-31 07:01

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