From: Junio C Hamano Date: Tue, 2 May 2006 22:40:49 +0000 (-0700) Subject: builtin-grep: support -w (--word-regexp). X-Git-Tag: v1.4.0-rc1~142^2~13 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=7839a25eab7177024b809fbb3796907e3eed17c1;p=git-core%2Fgit.git builtin-grep: support -w (--word-regexp). Signed-off-by: Junio C Hamano --- diff --git a/builtin-grep.c b/builtin-grep.c index f1800a54d..09e367782 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -89,6 +89,7 @@ struct grep_opt { unsigned invert:1; unsigned name_only:1; unsigned count:1; + unsigned word_regexp:1; int regflags; unsigned pre_context; unsigned post_context; @@ -128,6 +129,11 @@ static char *end_of_line(char *cp, unsigned long *left) return cp; } +static int word_char(char ch) +{ + return isalnum(ch) || ch == '_'; +} + static void show_line(struct grep_opt *opt, const char *bol, const char *eol, const char *name, unsigned lno, char sign) { @@ -171,6 +177,25 @@ static int grep_buffer(struct grep_opt *opt, const char *name, regex_t *exp = &p->regexp; hit = !regexec(exp, bol, ARRAY_SIZE(pmatch), pmatch, 0); + + if (hit && opt->word_regexp) { + /* Match beginning must be either + * beginning of the line, or at word + * boundary (i.e. the last char must + * not be alnum or underscore). + */ + if ((pmatch[0].rm_so < 0) || + (eol - bol) <= pmatch[0].rm_so || + (pmatch[0].rm_eo < 0) || + (eol - bol) < pmatch[0].rm_eo) + die("regexp returned nonsense"); + if (pmatch[0].rm_so != 0 && + word_char(bol[pmatch[0].rm_so-1])) + continue; /* not a word boundary */ + if ((eol-bol) < pmatch[0].rm_eo && + word_char(bol[pmatch[0].rm_eo])) + continue; /* not a word boundary */ + } if (hit) break; } @@ -461,6 +486,11 @@ int cmd_grep(int argc, const char **argv, char **envp) opt.count = 1; continue; } + if (!strcmp("-w", arg) || + !strcmp("--word-regexp", arg)) { + opt.word_regexp = 1; + continue; + } if (!strncmp("-A", arg, 2) || !strncmp("-B", arg, 2) || !strncmp("-C", arg, 2) ||