mirror of
https://github.com/git/git.git
synced 2024-11-18 06:54:55 +01:00
Merge branch 'jc/grep' into next
* jc/grep: builtin-grep: -L (--files-without-match). builtin-grep: binary files -a and -I builtin-grep: terminate correctly at EOF
This commit is contained in:
commit
f8098a3329
1 changed files with 66 additions and 0 deletions
|
@ -93,8 +93,13 @@ struct grep_opt {
|
||||||
unsigned linenum:1;
|
unsigned linenum:1;
|
||||||
unsigned invert:1;
|
unsigned invert:1;
|
||||||
unsigned name_only:1;
|
unsigned name_only:1;
|
||||||
|
unsigned unmatch_name_only:1;
|
||||||
unsigned count:1;
|
unsigned count:1;
|
||||||
unsigned word_regexp:1;
|
unsigned word_regexp:1;
|
||||||
|
#define GREP_BINARY_DEFAULT 0
|
||||||
|
#define GREP_BINARY_NOMATCH 1
|
||||||
|
#define GREP_BINARY_TEXT 2
|
||||||
|
unsigned binary:2;
|
||||||
int regflags;
|
int regflags;
|
||||||
unsigned pre_context;
|
unsigned pre_context;
|
||||||
unsigned post_context;
|
unsigned post_context;
|
||||||
|
@ -148,6 +153,19 @@ static void show_line(struct grep_opt *opt, const char *bol, const char *eol,
|
||||||
printf("%.*s\n", (int)(eol-bol), bol);
|
printf("%.*s\n", (int)(eol-bol), bol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NEEDSWORK: share code with diff.c
|
||||||
|
*/
|
||||||
|
#define FIRST_FEW_BYTES 8000
|
||||||
|
static int buffer_is_binary(const char *ptr, unsigned long size)
|
||||||
|
{
|
||||||
|
if (FIRST_FEW_BYTES < size)
|
||||||
|
size = FIRST_FEW_BYTES;
|
||||||
|
if (memchr(ptr, 0, size))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int grep_buffer(struct grep_opt *opt, const char *name,
|
static int grep_buffer(struct grep_opt *opt, const char *name,
|
||||||
char *buf, unsigned long size)
|
char *buf, unsigned long size)
|
||||||
{
|
{
|
||||||
|
@ -160,9 +178,23 @@ static int grep_buffer(struct grep_opt *opt, const char *name,
|
||||||
} *prev = NULL, *pcl;
|
} *prev = NULL, *pcl;
|
||||||
unsigned last_hit = 0;
|
unsigned last_hit = 0;
|
||||||
unsigned last_shown = 0;
|
unsigned last_shown = 0;
|
||||||
|
int binary_match_only = 0;
|
||||||
const char *hunk_mark = "";
|
const char *hunk_mark = "";
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
|
|
||||||
|
if (buffer_is_binary(buf, size)) {
|
||||||
|
switch (opt->binary) {
|
||||||
|
case GREP_BINARY_DEFAULT:
|
||||||
|
binary_match_only = 1;
|
||||||
|
break;
|
||||||
|
case GREP_BINARY_NOMATCH:
|
||||||
|
return 0; /* Assume unmatch */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (opt->pre_context)
|
if (opt->pre_context)
|
||||||
prev = xcalloc(opt->pre_context, sizeof(*prev));
|
prev = xcalloc(opt->pre_context, sizeof(*prev));
|
||||||
if (opt->pre_context || opt->post_context)
|
if (opt->pre_context || opt->post_context)
|
||||||
|
@ -210,8 +242,17 @@ static int grep_buffer(struct grep_opt *opt, const char *name,
|
||||||
*/
|
*/
|
||||||
if (opt->invert)
|
if (opt->invert)
|
||||||
hit = !hit;
|
hit = !hit;
|
||||||
|
if (opt->unmatch_name_only) {
|
||||||
|
if (hit)
|
||||||
|
return 0;
|
||||||
|
goto next_line;
|
||||||
|
}
|
||||||
if (hit) {
|
if (hit) {
|
||||||
count++;
|
count++;
|
||||||
|
if (binary_match_only) {
|
||||||
|
printf("Binary file %s matches\n", name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (opt->name_only) {
|
if (opt->name_only) {
|
||||||
printf("%s\n", name);
|
printf("%s\n", name);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -262,11 +303,22 @@ static int grep_buffer(struct grep_opt *opt, const char *name,
|
||||||
prev->bol = bol;
|
prev->bol = bol;
|
||||||
prev->eol = eol;
|
prev->eol = eol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next_line:
|
||||||
*eol = ch;
|
*eol = ch;
|
||||||
bol = eol + 1;
|
bol = eol + 1;
|
||||||
|
if (!left)
|
||||||
|
break;
|
||||||
left--;
|
left--;
|
||||||
lno++;
|
lno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt->unmatch_name_only) {
|
||||||
|
/* We did not see any hit, so we want to show this */
|
||||||
|
printf("%s\n", name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* NEEDSWORK:
|
/* NEEDSWORK:
|
||||||
* The real "grep -c foo *.c" gives many "bar.c:0" lines,
|
* The real "grep -c foo *.c" gives many "bar.c:0" lines,
|
||||||
* which feels mostly useless but sometimes useful. Maybe
|
* which feels mostly useless but sometimes useful. Maybe
|
||||||
|
@ -451,11 +503,20 @@ int cmd_grep(int argc, const char **argv, char **envp)
|
||||||
cached = 1;
|
cached = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("-a", arg) ||
|
||||||
|
!strcmp("--text", arg)) {
|
||||||
|
opt.binary = GREP_BINARY_TEXT;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp("-i", arg) ||
|
if (!strcmp("-i", arg) ||
|
||||||
!strcmp("--ignore-case", arg)) {
|
!strcmp("--ignore-case", arg)) {
|
||||||
opt.regflags |= REG_ICASE;
|
opt.regflags |= REG_ICASE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("-I", arg)) {
|
||||||
|
opt.binary = GREP_BINARY_NOMATCH;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp("-v", arg) ||
|
if (!strcmp("-v", arg) ||
|
||||||
!strcmp("--invert-match", arg)) {
|
!strcmp("--invert-match", arg)) {
|
||||||
opt.invert = 1;
|
opt.invert = 1;
|
||||||
|
@ -486,6 +547,11 @@ int cmd_grep(int argc, const char **argv, char **envp)
|
||||||
opt.name_only = 1;
|
opt.name_only = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("-L", arg) ||
|
||||||
|
!strcmp("--files-without-match", arg)) {
|
||||||
|
opt.unmatch_name_only = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp("-c", arg) ||
|
if (!strcmp("-c", arg) ||
|
||||||
!strcmp("--count", arg)) {
|
!strcmp("--count", arg)) {
|
||||||
opt.count = 1;
|
opt.count = 1;
|
||||||
|
|
Loading…
Reference in a new issue