From: Junio C Hamano Date: Tue, 28 Apr 2009 07:46:39 +0000 (-0700) Subject: Merge branch 'maint' X-Git-Tag: v1.6.3-rc4~14 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/b79376cdf3bd6ee922261776613d085a7b36ffd9?hp=-c Merge branch 'maint' * maint: grep: fix segfault when "git grep '('" is given Documentation: fix a grammatical error in api-builtin.txt builtin-merge: fix a typo in an error message --- b79376cdf3bd6ee922261776613d085a7b36ffd9 diff --combined builtin-merge.c index 6a51823a55,c339380cf3..0b58e5eda1 --- a/builtin-merge.c +++ b/builtin-merge.c @@@ -360,8 -360,9 +360,8 @@@ static void merge_name(const char *remo const char *ptr; int len, early; - len = strlen(remote); - if (interpret_nth_last_branch(remote, &bname) == len) - remote = bname.buf; + strbuf_branchname(&bname, remote); + remote = bname.buf; memset(branch_head, 0, sizeof(branch_head)); remote_head = peel_to_type(remote, 0, NULL, OBJ_COMMIT); @@@ -635,7 -636,7 +635,7 @@@ static int checkout_fast_forward(unsign memset(&opts, 0, sizeof(opts)); memset(&t, 0, sizeof(t)); memset(&dir, 0, sizeof(dir)); - dir.show_ignored = 1; + dir.flags |= DIR_SHOW_IGNORED; dir.exclude_per_dir = ".gitignore"; opts.dir = &dir; @@@ -764,7 -765,7 +764,7 @@@ static int suggest_conflicts(void fp = fopen(git_path("MERGE_MSG"), "a"); if (!fp) - die("Could open %s for writing", git_path("MERGE_MSG")); + die("Could not open %s for writing", git_path("MERGE_MSG")); fprintf(fp, "\nConflicts:\n"); for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; diff --combined grep.c index f3a27d7d6e,b0d992a6e0..04c777a20c --- a/grep.c +++ b/grep.c @@@ -39,8 -39,6 +39,8 @@@ static void compile_regexp(struct grep_ { int err; + p->word_regexp = opt->word_regexp; + if (opt->fixed || is_fixed(p->pattern)) p->fixed = 1; if (opt->regflags & REG_ICASE) @@@ -72,6 -70,8 +72,8 @@@ static struct grep_expr *compile_patter struct grep_expr *x; p = *list; + if (!p) + return NULL; switch (p->token) { case GREP_PATTERN: /* atom */ case GREP_PATTERN_HEAD: @@@ -84,8 -84,6 +86,6 @@@ case GREP_OPEN_PAREN: *list = p->next; x = compile_pattern_or(list); - if (!x) - return NULL; if (!*list || (*list)->token != GREP_CLOSE_PAREN) die("unmatched parenthesis"); *list = (*list)->next; @@@ -101,6 -99,8 +101,8 @@@ static struct grep_expr *compile_patter struct grep_expr *x; p = *list; + if (!p) + return NULL; switch (p->token) { case GREP_NOT: if (!p->next) @@@ -192,8 -192,7 +194,8 @@@ void compile_grep_patterns(struct grep_ * A classic recursive descent parser would do. */ p = opt->pattern_list; - opt->pattern_expression = compile_pattern_expr(&p); + if (p) + opt->pattern_expression = compile_pattern_expr(&p); if (p) die("incomplete pattern expression: %s", p->pattern); } @@@ -254,6 -253,18 +256,6 @@@ 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) -{ - if (opt->null_following_name) - sign = '\0'; - if (opt->pathname) - printf("%s%c", name, sign); - if (opt->linenum) - printf("%d%c", lno, sign); - printf("%.*s\n", (int)(eol-bol), bol); -} - static void show_name(struct grep_opt *opt, const char *name) { printf("%s%c", name, opt->null_following_name ? '\0' : '\n'); @@@ -297,12 -308,11 +299,12 @@@ static struct { "committer ", 10 }, }; -static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol, enum grep_context ctx) +static int match_one_pattern(struct grep_pat *p, char *bol, char *eol, + enum grep_context ctx, + regmatch_t *pmatch, int eflags) { int hit = 0; int saved_ch = 0; - regmatch_t pmatch[10]; if ((p->token != GREP_PATTERN) && ((p->token == GREP_PATTERN_HEAD) != (ctx == GREP_CONTEXT_HEAD))) @@@ -321,12 -331,16 +323,12 @@@ } again: - if (!p->fixed) { - regex_t *exp = &p->regexp; - hit = !regexec(exp, bol, ARRAY_SIZE(pmatch), - pmatch, 0); - } - else { + if (p->fixed) hit = !fixmatch(p->pattern, bol, pmatch); - } + else + hit = !regexec(&p->regexp, bol, 1, pmatch, eflags); - if (hit && opt->word_regexp) { + if (hit && p->word_regexp) { if ((pmatch[0].rm_so < 0) || (eol - bol) <= pmatch[0].rm_so || (pmatch[0].rm_eo < 0) || @@@ -366,33 -380,41 +368,35 @@@ return hit; } -static int match_expr_eval(struct grep_opt *o, - struct grep_expr *x, - char *bol, char *eol, - enum grep_context ctx, - int collect_hits) +static int match_expr_eval(struct grep_expr *x, char *bol, char *eol, + enum grep_context ctx, int collect_hits) { int h = 0; + regmatch_t match; + if (!x) + die("Not a valid grep expression"); switch (x->node) { case GREP_NODE_ATOM: - h = match_one_pattern(o, x->u.atom, bol, eol, ctx); + h = match_one_pattern(x->u.atom, bol, eol, ctx, &match, 0); break; case GREP_NODE_NOT: - h = !match_expr_eval(o, x->u.unary, bol, eol, ctx, 0); + h = !match_expr_eval(x->u.unary, bol, eol, ctx, 0); break; case GREP_NODE_AND: - if (!collect_hits) - return (match_expr_eval(o, x->u.binary.left, - bol, eol, ctx, 0) && - match_expr_eval(o, x->u.binary.right, - bol, eol, ctx, 0)); - h = match_expr_eval(o, x->u.binary.left, bol, eol, ctx, 0); - h &= match_expr_eval(o, x->u.binary.right, bol, eol, ctx, 0); + if (!match_expr_eval(x->u.binary.left, bol, eol, ctx, 0)) + return 0; + h = match_expr_eval(x->u.binary.right, bol, eol, ctx, 0); break; case GREP_NODE_OR: if (!collect_hits) - return (match_expr_eval(o, x->u.binary.left, + return (match_expr_eval(x->u.binary.left, bol, eol, ctx, 0) || - match_expr_eval(o, x->u.binary.right, + match_expr_eval(x->u.binary.right, bol, eol, ctx, 0)); - h = match_expr_eval(o, x->u.binary.left, bol, eol, ctx, 0); + h = match_expr_eval(x->u.binary.left, bol, eol, ctx, 0); x->u.binary.left->hit |= h; - h |= match_expr_eval(o, x->u.binary.right, bol, eol, ctx, 1); + h |= match_expr_eval(x->u.binary.right, bol, eol, ctx, 1); break; default: die("Unexpected node type (internal error) %d", x->node); @@@ -406,104 -428,24 +410,104 @@@ static int match_expr(struct grep_opt * enum grep_context ctx, int collect_hits) { struct grep_expr *x = opt->pattern_expression; - return match_expr_eval(opt, x, bol, eol, ctx, collect_hits); + return match_expr_eval(x, bol, eol, ctx, collect_hits); } static int match_line(struct grep_opt *opt, char *bol, char *eol, enum grep_context ctx, int collect_hits) { struct grep_pat *p; + regmatch_t match; + if (opt->extended) return match_expr(opt, bol, eol, ctx, collect_hits); /* we do not call with collect_hits without being extended */ for (p = opt->pattern_list; p; p = p->next) { - if (match_one_pattern(opt, p, bol, eol, ctx)) + if (match_one_pattern(p, bol, eol, ctx, &match, 0)) return 1; } return 0; } +static int match_next_pattern(struct grep_pat *p, char *bol, char *eol, + enum grep_context ctx, + regmatch_t *pmatch, int eflags) +{ + regmatch_t match; + + if (!match_one_pattern(p, bol, eol, ctx, &match, eflags)) + return 0; + if (match.rm_so < 0 || match.rm_eo < 0) + return 0; + if (pmatch->rm_so >= 0 && pmatch->rm_eo >= 0) { + if (match.rm_so > pmatch->rm_so) + return 1; + if (match.rm_so == pmatch->rm_so && match.rm_eo < pmatch->rm_eo) + return 1; + } + pmatch->rm_so = match.rm_so; + pmatch->rm_eo = match.rm_eo; + return 1; +} + +static int next_match(struct grep_opt *opt, char *bol, char *eol, + enum grep_context ctx, regmatch_t *pmatch, int eflags) +{ + struct grep_pat *p; + int hit = 0; + + pmatch->rm_so = pmatch->rm_eo = -1; + if (bol < eol) { + for (p = opt->pattern_list; p; p = p->next) { + switch (p->token) { + case GREP_PATTERN: /* atom */ + case GREP_PATTERN_HEAD: + case GREP_PATTERN_BODY: + hit |= match_next_pattern(p, bol, eol, ctx, + pmatch, eflags); + break; + default: + break; + } + } + } + return hit; +} + +static void show_line(struct grep_opt *opt, char *bol, char *eol, + const char *name, unsigned lno, char sign) +{ + int rest = eol - bol; + + if (opt->null_following_name) + sign = '\0'; + if (opt->pathname) + printf("%s%c", name, sign); + if (opt->linenum) + printf("%d%c", lno, sign); + if (opt->color) { + regmatch_t match; + enum grep_context ctx = GREP_CONTEXT_BODY; + int ch = *eol; + int eflags = 0; + + *eol = '\0'; + while (next_match(opt, bol, eol, ctx, &match, eflags)) { + printf("%.*s%s%.*s%s", + (int)match.rm_so, bol, + opt->color_match, + (int)(match.rm_eo - match.rm_so), bol + match.rm_so, + GIT_COLOR_RESET); + bol += match.rm_eo; + rest -= match.rm_eo; + eflags = REG_NOTBOL; + } + *eol = ch; + } + printf("%.*s\n", rest, bol); +} + static int grep_buffer_1(struct grep_opt *opt, const char *name, char *buf, unsigned long size, int collect_hits) {