diff options
author | Junio C Hamano <junkio@cox.net> | 2006-05-04 08:05:29 +0400 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-05-04 08:05:29 +0400 |
commit | b8d0f5a00313bc5fb173f77c9a91a94f94a5aa1b (patch) | |
tree | e1a6ef7f9e6d2dd14d1753b60da796b57faa94af | |
parent | 7ed36f56e33bd838d06521a37a916516397e9e8b (diff) |
builtin-grep: binary files -a and -I
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | builtin-grep.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/builtin-grep.c b/builtin-grep.c index e87b5cb48d..0d6115763b 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -95,6 +95,10 @@ struct grep_opt { unsigned name_only:1; unsigned count: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; unsigned pre_context; unsigned post_context; @@ -148,6 +152,19 @@ static void show_line(struct grep_opt *opt, const char *bol, const char *eol, 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, char *buf, unsigned long size) { @@ -160,9 +177,23 @@ static int grep_buffer(struct grep_opt *opt, const char *name, } *prev = NULL, *pcl; unsigned last_hit = 0; unsigned last_shown = 0; + int binary_match_only = 0; const char *hunk_mark = ""; 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) prev = xcalloc(opt->pre_context, sizeof(*prev)); if (opt->pre_context || opt->post_context) @@ -212,6 +243,10 @@ static int grep_buffer(struct grep_opt *opt, const char *name, hit = !hit; if (hit) { count++; + if (binary_match_only) { + printf("Binary file %s matches\n", name); + return 1; + } if (opt->name_only) { printf("%s\n", name); return 1; @@ -453,11 +488,20 @@ int cmd_grep(int argc, const char **argv, char **envp) cached = 1; continue; } + if (!strcmp("-a", arg) || + !strcmp("--text", arg)) { + opt.binary = GREP_BINARY_TEXT; + continue; + } if (!strcmp("-i", arg) || !strcmp("--ignore-case", arg)) { opt.regflags |= REG_ICASE; continue; } + if (!strcmp("-I", arg)) { + opt.binary = GREP_BINARY_NOMATCH; + continue; + } if (!strcmp("-v", arg) || !strcmp("--invert-match", arg)) { opt.invert = 1; |