Merge branch 'jk/grep-haystack-is-read-only' into hm/paint-hits-in-log-grep
* jk/grep-haystack-is-read-only: grep: store grep_source buffer as const grep: mark "haystack" buffers as const grep: stop modifying buffer in grep_source_1() grep: stop modifying buffer in show_line() grep: stop modifying buffer in strip_timestamp
This commit is contained in:
commit
28ecef4c84
87
grep.c
87
grep.c
@ -867,7 +867,7 @@ void free_grep_patterns(struct grep_opt *opt)
|
|||||||
free_pattern_expr(opt->pattern_expression);
|
free_pattern_expr(opt->pattern_expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *end_of_line(char *cp, unsigned long *left)
|
static const char *end_of_line(const char *cp, unsigned long *left)
|
||||||
{
|
{
|
||||||
unsigned long l = *left;
|
unsigned long l = *left;
|
||||||
while (l && *cp != '\n') {
|
while (l && *cp != '\n') {
|
||||||
@ -908,7 +908,8 @@ static void show_name(struct grep_opt *opt, const char *name)
|
|||||||
opt->output(opt, opt->null_following_name ? "\0" : "\n", 1);
|
opt->output(opt, opt->null_following_name ? "\0" : "\n", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int patmatch(struct grep_pat *p, char *line, char *eol,
|
static int patmatch(struct grep_pat *p,
|
||||||
|
const char *line, const char *eol,
|
||||||
regmatch_t *match, int eflags)
|
regmatch_t *match, int eflags)
|
||||||
{
|
{
|
||||||
int hit;
|
int hit;
|
||||||
@ -922,20 +923,16 @@ static int patmatch(struct grep_pat *p, char *line, char *eol,
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int strip_timestamp(char *bol, char **eol_p)
|
static void strip_timestamp(const char *bol, const char **eol_p)
|
||||||
{
|
{
|
||||||
char *eol = *eol_p;
|
const char *eol = *eol_p;
|
||||||
int ch;
|
|
||||||
|
|
||||||
while (bol < --eol) {
|
while (bol < --eol) {
|
||||||
if (*eol != '>')
|
if (*eol != '>')
|
||||||
continue;
|
continue;
|
||||||
*eol_p = ++eol;
|
*eol_p = ++eol;
|
||||||
ch = *eol;
|
break;
|
||||||
*eol = '\0';
|
|
||||||
return ch;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -947,12 +944,12 @@ static struct {
|
|||||||
{ "reflog ", 7 },
|
{ "reflog ", 7 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
static int match_one_pattern(struct grep_pat *p,
|
||||||
|
const char *bol, const char *eol,
|
||||||
enum grep_context ctx,
|
enum grep_context ctx,
|
||||||
regmatch_t *pmatch, int eflags)
|
regmatch_t *pmatch, int eflags)
|
||||||
{
|
{
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
int saved_ch = 0;
|
|
||||||
const char *start = bol;
|
const char *start = bol;
|
||||||
|
|
||||||
if ((p->token != GREP_PATTERN) &&
|
if ((p->token != GREP_PATTERN) &&
|
||||||
@ -971,7 +968,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
|||||||
switch (p->field) {
|
switch (p->field) {
|
||||||
case GREP_HEADER_AUTHOR:
|
case GREP_HEADER_AUTHOR:
|
||||||
case GREP_HEADER_COMMITTER:
|
case GREP_HEADER_COMMITTER:
|
||||||
saved_ch = strip_timestamp(bol, &eol);
|
strip_timestamp(bol, &eol);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1021,8 +1018,6 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p->token == GREP_PATTERN_HEAD && saved_ch)
|
|
||||||
*eol = saved_ch;
|
|
||||||
if (hit) {
|
if (hit) {
|
||||||
pmatch[0].rm_so += bol - start;
|
pmatch[0].rm_so += bol - start;
|
||||||
pmatch[0].rm_eo += bol - start;
|
pmatch[0].rm_eo += bol - start;
|
||||||
@ -1030,8 +1025,9 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x, char *bol,
|
static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x,
|
||||||
char *eol, enum grep_context ctx, ssize_t *col,
|
const char *bol, const char *eol,
|
||||||
|
enum grep_context ctx, ssize_t *col,
|
||||||
ssize_t *icol, int collect_hits)
|
ssize_t *icol, int collect_hits)
|
||||||
{
|
{
|
||||||
int h = 0;
|
int h = 0;
|
||||||
@ -1098,7 +1094,8 @@ static int match_expr_eval(struct grep_opt *opt, struct grep_expr *x, char *bol,
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_expr(struct grep_opt *opt, char *bol, char *eol,
|
static int match_expr(struct grep_opt *opt,
|
||||||
|
const char *bol, const char *eol,
|
||||||
enum grep_context ctx, ssize_t *col,
|
enum grep_context ctx, ssize_t *col,
|
||||||
ssize_t *icol, int collect_hits)
|
ssize_t *icol, int collect_hits)
|
||||||
{
|
{
|
||||||
@ -1106,7 +1103,8 @@ static int match_expr(struct grep_opt *opt, char *bol, char *eol,
|
|||||||
return match_expr_eval(opt, x, bol, eol, ctx, col, icol, collect_hits);
|
return match_expr_eval(opt, x, bol, eol, ctx, col, icol, collect_hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_line(struct grep_opt *opt, char *bol, char *eol,
|
static int match_line(struct grep_opt *opt,
|
||||||
|
const char *bol, const char *eol,
|
||||||
ssize_t *col, ssize_t *icol,
|
ssize_t *col, ssize_t *icol,
|
||||||
enum grep_context ctx, int collect_hits)
|
enum grep_context ctx, int collect_hits)
|
||||||
{
|
{
|
||||||
@ -1138,7 +1136,8 @@ static int match_line(struct grep_opt *opt, char *bol, char *eol,
|
|||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_next_pattern(struct grep_pat *p, char *bol, char *eol,
|
static int match_next_pattern(struct grep_pat *p,
|
||||||
|
const char *bol, const char *eol,
|
||||||
enum grep_context ctx,
|
enum grep_context ctx,
|
||||||
regmatch_t *pmatch, int eflags)
|
regmatch_t *pmatch, int eflags)
|
||||||
{
|
{
|
||||||
@ -1159,7 +1158,8 @@ static int match_next_pattern(struct grep_pat *p, char *bol, char *eol,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int next_match(struct grep_opt *opt, char *bol, char *eol,
|
static int next_match(struct grep_opt *opt,
|
||||||
|
const char *bol, const char *eol,
|
||||||
enum grep_context ctx, regmatch_t *pmatch, int eflags)
|
enum grep_context ctx, regmatch_t *pmatch, int eflags)
|
||||||
{
|
{
|
||||||
struct grep_pat *p;
|
struct grep_pat *p;
|
||||||
@ -1215,7 +1215,8 @@ static void show_line_header(struct grep_opt *opt, const char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
static void show_line(struct grep_opt *opt,
|
||||||
|
const char *bol, const char *eol,
|
||||||
const char *name, unsigned lno, ssize_t cno, char sign)
|
const char *name, unsigned lno, ssize_t cno, char sign)
|
||||||
{
|
{
|
||||||
int rest = eol - bol;
|
int rest = eol - bol;
|
||||||
@ -1246,7 +1247,6 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
|||||||
if (opt->color || opt->only_matching) {
|
if (opt->color || opt->only_matching) {
|
||||||
regmatch_t match;
|
regmatch_t match;
|
||||||
enum grep_context ctx = GREP_CONTEXT_BODY;
|
enum grep_context ctx = GREP_CONTEXT_BODY;
|
||||||
int ch = *eol;
|
|
||||||
int eflags = 0;
|
int eflags = 0;
|
||||||
|
|
||||||
if (opt->color) {
|
if (opt->color) {
|
||||||
@ -1261,7 +1261,6 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
|||||||
else if (sign == '=')
|
else if (sign == '=')
|
||||||
line_color = opt->colors[GREP_COLOR_FUNCTION];
|
line_color = opt->colors[GREP_COLOR_FUNCTION];
|
||||||
}
|
}
|
||||||
*eol = '\0';
|
|
||||||
while (next_match(opt, bol, eol, ctx, &match, eflags)) {
|
while (next_match(opt, bol, eol, ctx, &match, eflags)) {
|
||||||
if (match.rm_so == match.rm_eo)
|
if (match.rm_so == match.rm_eo)
|
||||||
break;
|
break;
|
||||||
@ -1279,7 +1278,6 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
|
|||||||
rest -= match.rm_eo;
|
rest -= match.rm_eo;
|
||||||
eflags = REG_NOTBOL;
|
eflags = REG_NOTBOL;
|
||||||
}
|
}
|
||||||
*eol = ch;
|
|
||||||
}
|
}
|
||||||
if (!opt->only_matching) {
|
if (!opt->only_matching) {
|
||||||
output_color(opt, bol, rest, line_color);
|
output_color(opt, bol, rest, line_color);
|
||||||
@ -1307,7 +1305,8 @@ static inline void grep_attr_unlock(void)
|
|||||||
pthread_mutex_unlock(&grep_attr_mutex);
|
pthread_mutex_unlock(&grep_attr_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bol, char *eol)
|
static int match_funcname(struct grep_opt *opt, struct grep_source *gs,
|
||||||
|
const char *bol, const char *eol)
|
||||||
{
|
{
|
||||||
xdemitconf_t *xecfg = opt->priv;
|
xdemitconf_t *xecfg = opt->priv;
|
||||||
if (xecfg && !xecfg->find_func) {
|
if (xecfg && !xecfg->find_func) {
|
||||||
@ -1334,10 +1333,10 @@ static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
|
static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
|
||||||
char *bol, unsigned lno)
|
const char *bol, unsigned lno)
|
||||||
{
|
{
|
||||||
while (bol > gs->buf) {
|
while (bol > gs->buf) {
|
||||||
char *eol = --bol;
|
const char *eol = --bol;
|
||||||
|
|
||||||
while (bol > gs->buf && bol[-1] != '\n')
|
while (bol > gs->buf && bol[-1] != '\n')
|
||||||
bol--;
|
bol--;
|
||||||
@ -1356,7 +1355,7 @@ static void show_funcname_line(struct grep_opt *opt, struct grep_source *gs,
|
|||||||
static int is_empty_line(const char *bol, const char *eol);
|
static int is_empty_line(const char *bol, const char *eol);
|
||||||
|
|
||||||
static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
|
static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
|
||||||
char *bol, char *end, unsigned lno)
|
const char *bol, const char *end, unsigned lno)
|
||||||
{
|
{
|
||||||
unsigned cur = lno, from = 1, funcname_lno = 0, orig_from;
|
unsigned cur = lno, from = 1, funcname_lno = 0, orig_from;
|
||||||
int funcname_needed = !!opt->funcname, comment_needed = 0;
|
int funcname_needed = !!opt->funcname, comment_needed = 0;
|
||||||
@ -1376,8 +1375,8 @@ static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
|
|||||||
|
|
||||||
/* Rewind. */
|
/* Rewind. */
|
||||||
while (bol > gs->buf && cur > from) {
|
while (bol > gs->buf && cur > from) {
|
||||||
char *next_bol = bol;
|
const char *next_bol = bol;
|
||||||
char *eol = --bol;
|
const char *eol = --bol;
|
||||||
|
|
||||||
while (bol > gs->buf && bol[-1] != '\n')
|
while (bol > gs->buf && bol[-1] != '\n')
|
||||||
bol--;
|
bol--;
|
||||||
@ -1408,7 +1407,7 @@ static void show_pre_context(struct grep_opt *opt, struct grep_source *gs,
|
|||||||
|
|
||||||
/* Back forward. */
|
/* Back forward. */
|
||||||
while (cur < lno) {
|
while (cur < lno) {
|
||||||
char *eol = bol, sign = (cur == funcname_lno) ? '=' : '-';
|
const char *eol = bol, sign = (cur == funcname_lno) ? '=' : '-';
|
||||||
|
|
||||||
while (*eol != '\n')
|
while (*eol != '\n')
|
||||||
eol++;
|
eol++;
|
||||||
@ -1436,12 +1435,12 @@ static int should_lookahead(struct grep_opt *opt)
|
|||||||
static int look_ahead(struct grep_opt *opt,
|
static int look_ahead(struct grep_opt *opt,
|
||||||
unsigned long *left_p,
|
unsigned long *left_p,
|
||||||
unsigned *lno_p,
|
unsigned *lno_p,
|
||||||
char **bol_p)
|
const char **bol_p)
|
||||||
{
|
{
|
||||||
unsigned lno = *lno_p;
|
unsigned lno = *lno_p;
|
||||||
char *bol = *bol_p;
|
const char *bol = *bol_p;
|
||||||
struct grep_pat *p;
|
struct grep_pat *p;
|
||||||
char *sp, *last_bol;
|
const char *sp, *last_bol;
|
||||||
regoff_t earliest = -1;
|
regoff_t earliest = -1;
|
||||||
|
|
||||||
for (p = opt->pattern_list; p; p = p->next) {
|
for (p = opt->pattern_list; p; p = p->next) {
|
||||||
@ -1543,8 +1542,8 @@ static int is_empty_line(const char *bol, const char *eol)
|
|||||||
|
|
||||||
static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
|
static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int collect_hits)
|
||||||
{
|
{
|
||||||
char *bol;
|
const char *bol;
|
||||||
char *peek_bol = NULL;
|
const char *peek_bol = NULL;
|
||||||
unsigned long left;
|
unsigned long left;
|
||||||
unsigned lno = 1;
|
unsigned lno = 1;
|
||||||
unsigned last_hit = 0;
|
unsigned last_hit = 0;
|
||||||
@ -1626,7 +1625,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
|
|||||||
bol = gs->buf;
|
bol = gs->buf;
|
||||||
left = gs->size;
|
left = gs->size;
|
||||||
while (left) {
|
while (left) {
|
||||||
char *eol, ch;
|
const char *eol;
|
||||||
int hit;
|
int hit;
|
||||||
ssize_t cno;
|
ssize_t cno;
|
||||||
ssize_t col = -1, icol = -1;
|
ssize_t col = -1, icol = -1;
|
||||||
@ -1647,14 +1646,11 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
|
|||||||
&& look_ahead(opt, &left, &lno, &bol))
|
&& look_ahead(opt, &left, &lno, &bol))
|
||||||
break;
|
break;
|
||||||
eol = end_of_line(bol, &left);
|
eol = end_of_line(bol, &left);
|
||||||
ch = *eol;
|
|
||||||
*eol = 0;
|
|
||||||
|
|
||||||
if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol))
|
if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol))
|
||||||
ctx = GREP_CONTEXT_BODY;
|
ctx = GREP_CONTEXT_BODY;
|
||||||
|
|
||||||
hit = match_line(opt, bol, eol, &col, &icol, ctx, collect_hits);
|
hit = match_line(opt, bol, eol, &col, &icol, ctx, collect_hits);
|
||||||
*eol = ch;
|
|
||||||
|
|
||||||
if (collect_hits)
|
if (collect_hits)
|
||||||
goto next_line;
|
goto next_line;
|
||||||
@ -1713,7 +1709,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
|
|||||||
}
|
}
|
||||||
if (show_function && (!peek_bol || peek_bol < bol)) {
|
if (show_function && (!peek_bol || peek_bol < bol)) {
|
||||||
unsigned long peek_left = left;
|
unsigned long peek_left = left;
|
||||||
char *peek_eol = eol;
|
const char *peek_eol = eol;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trailing empty lines are not interesting.
|
* Trailing empty lines are not interesting.
|
||||||
@ -1825,7 +1821,8 @@ int grep_source(struct grep_opt *opt, struct grep_source *gs)
|
|||||||
return grep_source_1(opt, gs, 0);
|
return grep_source_1(opt, gs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void grep_source_init_buf(struct grep_source *gs, char *buf,
|
static void grep_source_init_buf(struct grep_source *gs,
|
||||||
|
const char *buf,
|
||||||
unsigned long size)
|
unsigned long size)
|
||||||
{
|
{
|
||||||
gs->type = GREP_SOURCE_BUF;
|
gs->type = GREP_SOURCE_BUF;
|
||||||
@ -1837,7 +1834,7 @@ static void grep_source_init_buf(struct grep_source *gs, char *buf,
|
|||||||
gs->identifier = NULL;
|
gs->identifier = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size)
|
int grep_buffer(struct grep_opt *opt, const char *buf, unsigned long size)
|
||||||
{
|
{
|
||||||
struct grep_source gs;
|
struct grep_source gs;
|
||||||
int r;
|
int r;
|
||||||
@ -1889,7 +1886,9 @@ void grep_source_clear_data(struct grep_source *gs)
|
|||||||
switch (gs->type) {
|
switch (gs->type) {
|
||||||
case GREP_SOURCE_FILE:
|
case GREP_SOURCE_FILE:
|
||||||
case GREP_SOURCE_OID:
|
case GREP_SOURCE_OID:
|
||||||
FREE_AND_NULL(gs->buf);
|
/* these types own the buffer */
|
||||||
|
free((char *)gs->buf);
|
||||||
|
gs->buf = NULL;
|
||||||
gs->size = 0;
|
gs->size = 0;
|
||||||
break;
|
break;
|
||||||
case GREP_SOURCE_BUF:
|
case GREP_SOURCE_BUF:
|
||||||
|
4
grep.h
4
grep.h
@ -189,7 +189,7 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *orig
|
|||||||
void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
|
void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
|
||||||
void compile_grep_patterns(struct grep_opt *opt);
|
void compile_grep_patterns(struct grep_opt *opt);
|
||||||
void free_grep_patterns(struct grep_opt *opt);
|
void free_grep_patterns(struct grep_opt *opt);
|
||||||
int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size);
|
int grep_buffer(struct grep_opt *opt, const char *buf, unsigned long size);
|
||||||
|
|
||||||
struct grep_source {
|
struct grep_source {
|
||||||
char *name;
|
char *name;
|
||||||
@ -202,7 +202,7 @@ struct grep_source {
|
|||||||
void *identifier;
|
void *identifier;
|
||||||
struct repository *repo; /* if GREP_SOURCE_OID */
|
struct repository *repo; /* if GREP_SOURCE_OID */
|
||||||
|
|
||||||
char *buf;
|
const char *buf;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
char *path; /* for attribute lookups */
|
char *path; /* for attribute lookups */
|
||||||
|
Loading…
Reference in New Issue
Block a user