Merge branch 'fk/use-kwset-pickaxe-grep-f'
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Sep 2011 17:00:38 +0000 (10:00 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Sep 2011 17:00:38 +0000 (10:00 -0700)
* fk/use-kwset-pickaxe-grep-f:
obstack: Fix portability issues
Use kwset in grep
Use kwset in pickaxe
Adapt the kwset code to Git
Add string search routines from GNU grep
Add obstack.[ch] from EGLIBC 2.10

1  2 
Makefile
grep.c
diff --combined Makefile
index 6bf7d6c30f41cf0046d992c166e9a688a9af0b72,45ef51f1807eccbb322d5e33913d9acdfb7b4938..8d6d4515d2d635ff8b5e59e0ce38ffa566f5bb64
+++ b/Makefile
@@@ -302,7 -302,6 +302,7 @@@ bindir = $(prefix)/$(bindir_relative
  mandir = share/man
  infodir = share/info
  gitexecdir = libexec/git-core
 +mergetoolsdir = $(gitexecdir)/mergetools
  sharedir = $(prefix)/share
  gitwebdir = $(sharedir)/gitweb
  template_dir = share/git-core/templates
@@@ -515,6 -514,7 +515,7 @@@ LIB_H += commit.
  LIB_H += compat/bswap.h
  LIB_H += compat/cygwin.h
  LIB_H += compat/mingw.h
+ LIB_H += compat/obstack.h
  LIB_H += compat/win32/pthread.h
  LIB_H += compat/win32/syslog.h
  LIB_H += compat/win32/sys/poll.h
@@@ -533,6 -533,7 +534,7 @@@ LIB_H += graph.
  LIB_H += grep.h
  LIB_H += hash.h
  LIB_H += help.h
+ LIB_H += kwset.h
  LIB_H += levenshtein.h
  LIB_H += list-objects.h
  LIB_H += ll-merge.h
@@@ -594,6 -595,7 +596,7 @@@ LIB_OBJS += cache-tree.
  LIB_OBJS += color.o
  LIB_OBJS += combine-diff.o
  LIB_OBJS += commit.o
+ LIB_OBJS += compat/obstack.o
  LIB_OBJS += config.o
  LIB_OBJS += connect.o
  LIB_OBJS += convert.o
@@@ -623,6 -625,7 +626,7 @@@ LIB_OBJS += hash.
  LIB_OBJS += help.o
  LIB_OBJS += hex.o
  LIB_OBJS += ident.o
+ LIB_OBJS += kwset.o
  LIB_OBJS += levenshtein.o
  LIB_OBJS += list-objects.o
  LIB_OBJS += ll-merge.o
@@@ -643,7 -646,6 +647,7 @@@ LIB_OBJS += pack-revindex.
  LIB_OBJS += pack-write.o
  LIB_OBJS += pager.o
  LIB_OBJS += parse-options.o
 +LIB_OBJS += parse-options-cb.o
  LIB_OBJS += patch-delta.o
  LIB_OBJS += patch-ids.o
  LIB_OBJS += path.o
@@@ -2206,7 -2208,7 +2210,7 @@@ test-delta$X: diff-delta.o patch-delta.
  
  test-line-buffer$X: vcs-svn/lib.a
  
 -test-parse-options$X: parse-options.o
 +test-parse-options$X: parse-options.o parse-options-cb.o
  
  test-string-pool$X: vcs-svn/lib.a
  
@@@ -2259,13 -2261,6 +2263,13 @@@ endi
  gitexec_instdir_SQ = $(subst ','\'',$(gitexec_instdir))
  export gitexec_instdir
  
 +ifneq ($(filter /%,$(firstword $(mergetoolsdir))),)
 +mergetools_instdir = $(mergetoolsdir)
 +else
 +mergetools_instdir = $(prefix)/$(mergetoolsdir)
 +endif
 +mergetools_instdir_SQ = $(subst ','\'',$(mergetools_instdir))
 +
  install_bindir_programs := $(patsubst %,%$X,$(BINDIR_PROGRAMS_NEED_X)) $(BINDIR_PROGRAMS_NO_X)
  
  install: all
        $(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
        $(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
        $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
 +      $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
 +      (cd mergetools && $(TAR) cf - .) | \
 +      (cd '$(DESTDIR_SQ)$(mergetools_instdir_SQ)' && umask 022 && $(TAR) xof -)
  ifndef NO_PERL
        $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
        $(MAKE) -C gitweb install
diff --combined grep.c
index 2dd2a25ad7086698e5bee28442b3cd935444432e,6618cd8b92fc1948304a73e7e99d74ca0035d51e..b29d09c7f6a5a7f9621fb5287eb07e72ece7f484
--- 1/grep.c
--- 2/grep.c
+++ b/grep.c
@@@ -137,16 -137,50 +137,50 @@@ static void free_pcre_regexp(struct gre
  }
  #endif /* !USE_LIBPCRE */
  
+ static int is_fixed(const char *s, size_t len)
+ {
+       size_t i;
+       /* regcomp cannot accept patterns with NULs so we
+        * consider any pattern containing a NUL fixed.
+        */
+       if (memchr(s, 0, len))
+               return 1;
+       for (i = 0; i < len; i++) {
+               if (is_regex_special(s[i]))
+                       return 0;
+       }
+       return 1;
+ }
  static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
  {
        int err;
  
        p->word_regexp = opt->word_regexp;
        p->ignore_case = opt->ignore_case;
-       p->fixed = opt->fixed;
  
-       if (p->fixed)
+       if (opt->fixed || is_fixed(p->pattern, p->patternlen))
+               p->fixed = 1;
+       else
+               p->fixed = 0;
+       if (p->fixed) {
+               if (opt->regflags & REG_ICASE || p->ignore_case) {
+                       static char trans[256];
+                       int i;
+                       for (i = 0; i < 256; i++)
+                               trans[i] = tolower(i);
+                       p->kws = kwsalloc(trans);
+               } else {
+                       p->kws = kwsalloc(NULL);
+               }
+               kwsincr(p->kws, p->pattern, p->patternlen);
+               kwsprep(p->kws);
                return;
+       }
  
        if (opt->pcre) {
                compile_pcre_regexp(p, opt);
@@@ -395,7 -429,9 +429,9 @@@ void free_grep_patterns(struct grep_op
                case GREP_PATTERN: /* atom */
                case GREP_PATTERN_HEAD:
                case GREP_PATTERN_BODY:
-                       if (p->pcre_regexp)
+                       if (p->kws)
+                               kwsfree(p->kws);
+                       else if (p->pcre_regexp)
                                free_pcre_regexp(p);
                        else
                                regfree(&p->regexp);
@@@ -430,7 -466,7 +466,7 @@@ static int word_char(char ch
  static void output_color(struct grep_opt *opt, const void *data, size_t size,
                         const char *color)
  {
 -      if (opt->color && color && color[0]) {
 +      if (want_color(opt->color) && color && color[0]) {
                opt->output(opt, color, strlen(color));
                opt->output(opt, data, size);
                opt->output(opt, GIT_COLOR_RESET, strlen(GIT_COLOR_RESET));
@@@ -455,26 -491,14 +491,14 @@@ static void show_name(struct grep_opt *
  static int fixmatch(struct grep_pat *p, char *line, char *eol,
                    regmatch_t *match)
  {
-       char *hit;
-       if (p->ignore_case) {
-               char *s = line;
-               do {
-                       hit = strcasestr(s, p->pattern);
-                       if (hit)
-                               break;
-                       s += strlen(s) + 1;
-               } while (s < eol);
-       } else
-               hit = memmem(line, eol - line, p->pattern, p->patternlen);
-       if (!hit) {
+       struct kwsmatch kwsm;
+       size_t offset = kwsexec(p->kws, line, eol - line, &kwsm);
+       if (offset == -1) {
                match->rm_so = match->rm_eo = -1;
                return REG_NOMATCH;
-       }
-       else {
-               match->rm_so = hit - line;
-               match->rm_eo = match->rm_so + p->patternlen;
+       } else {
+               match->rm_so = offset;
+               match->rm_eo = match->rm_so + kwsm.size[0];
                return 0;
        }
  }