Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Tue, 28 Apr 2009 07:46:39 +0000 (00:46 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 28 Apr 2009 07:46:39 +0000 (00:46 -0700)
* 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

1  2 
builtin-merge.c
grep.c
diff --combined builtin-merge.c
index 6a51823a55502766bee74dfd0a3857a8330a0f75,c339380cf3a94c5c157e7b3fae082ea2321320fc..0b58e5eda1f38c1560cc9dcf69be37fa5fc9886f
@@@ -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 f3a27d7d6e141bd8813b978edbe33d16aa764fb4,b0d992a6e0a838d0fb4e71e3a8bebe8266ed1070..04c777a20c1a8c10417cc9d44e53e5b99dc32a27
--- 1/grep.c
--- 2/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)))
        }
  
   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) ||
        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)
  {