Merge branch 'rs/maint-grep-F'
"git grep -e '$pattern'", unlike the case where the patterns are read from a file, did not treat individual lines in the given pattern argument as separate regular expressions as it should.
This commit is contained in:
74
grep.c
74
grep.c
@ -3,18 +3,64 @@
|
||||
#include "userdiff.h"
|
||||
#include "xdiff-interface.h"
|
||||
|
||||
void append_header_grep_pattern(struct grep_opt *opt, enum grep_header_field field, const char *pat)
|
||||
static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,
|
||||
const char *origin, int no,
|
||||
enum grep_pat_token t,
|
||||
enum grep_header_field field)
|
||||
{
|
||||
struct grep_pat *p = xcalloc(1, sizeof(*p));
|
||||
p->pattern = pat;
|
||||
p->patternlen = strlen(pat);
|
||||
p->origin = "header";
|
||||
p->no = 0;
|
||||
p->token = GREP_PATTERN_HEAD;
|
||||
p->pattern = xmemdupz(pat, patlen);
|
||||
p->patternlen = patlen;
|
||||
p->origin = origin;
|
||||
p->no = no;
|
||||
p->token = t;
|
||||
p->field = field;
|
||||
*opt->header_tail = p;
|
||||
opt->header_tail = &p->next;
|
||||
return p;
|
||||
}
|
||||
|
||||
static void do_append_grep_pat(struct grep_pat ***tail, struct grep_pat *p)
|
||||
{
|
||||
**tail = p;
|
||||
*tail = &p->next;
|
||||
p->next = NULL;
|
||||
|
||||
switch (p->token) {
|
||||
case GREP_PATTERN: /* atom */
|
||||
case GREP_PATTERN_HEAD:
|
||||
case GREP_PATTERN_BODY:
|
||||
for (;;) {
|
||||
struct grep_pat *new_pat;
|
||||
size_t len = 0;
|
||||
char *cp = p->pattern + p->patternlen, *nl = NULL;
|
||||
while (++len <= p->patternlen) {
|
||||
if (*(--cp) == '\n') {
|
||||
nl = cp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nl)
|
||||
break;
|
||||
new_pat = create_grep_pat(nl + 1, len - 1, p->origin,
|
||||
p->no, p->token, p->field);
|
||||
new_pat->next = p->next;
|
||||
if (!p->next)
|
||||
*tail = &new_pat->next;
|
||||
p->next = new_pat;
|
||||
*nl = '\0';
|
||||
p->patternlen -= len;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void append_header_grep_pattern(struct grep_opt *opt,
|
||||
enum grep_header_field field, const char *pat)
|
||||
{
|
||||
struct grep_pat *p = create_grep_pat(pat, strlen(pat), "header", 0,
|
||||
GREP_PATTERN_HEAD, field);
|
||||
do_append_grep_pat(&opt->header_tail, p);
|
||||
}
|
||||
|
||||
void append_grep_pattern(struct grep_opt *opt, const char *pat,
|
||||
@ -26,15 +72,8 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
|
||||
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen,
|
||||
const char *origin, int no, enum grep_pat_token t)
|
||||
{
|
||||
struct grep_pat *p = xcalloc(1, sizeof(*p));
|
||||
p->pattern = pat;
|
||||
p->patternlen = patlen;
|
||||
p->origin = origin;
|
||||
p->no = no;
|
||||
p->token = t;
|
||||
*opt->pattern_tail = p;
|
||||
opt->pattern_tail = &p->next;
|
||||
p->next = NULL;
|
||||
struct grep_pat *p = create_grep_pat(pat, patlen, origin, no, t, 0);
|
||||
do_append_grep_pat(&opt->pattern_tail, p);
|
||||
}
|
||||
|
||||
struct grep_opt *grep_opt_dup(const struct grep_opt *opt)
|
||||
@ -430,6 +469,7 @@ void free_grep_patterns(struct grep_opt *opt)
|
||||
free_pcre_regexp(p);
|
||||
else
|
||||
regfree(&p->regexp);
|
||||
free(p->pattern);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
Reference in New Issue
Block a user