Code

Merge branch 'bc/maint-diff-hunk-header-fix' into maint
authorShawn O. Pearce <spearce@spearce.org>
Mon, 29 Sep 2008 17:23:19 +0000 (10:23 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 29 Sep 2008 17:23:19 +0000 (10:23 -0700)
* bc/maint-diff-hunk-header-fix:
  t4018-diff-funcname: test syntax of builtin xfuncname patterns
  diff hunk pattern: fix misconverted "\{" tex macro introducers
  diff: use extended regexp to find hunk headers
  diff.*.xfuncname which uses "extended" regex's for hunk header selection
  diff.c: associate a flag with each pattern and use it for compiling regex
  diff.c: return pattern entry pointer rather than just the hunk header pattern

Conflicts:
Documentation/gitattributes.txt

1  2 
Documentation/gitattributes.txt
diff.c

index 89627688b81761771f17865a67d10ad85a830ea2,9259637609da2b34d15d217daeebeccc6ba853e4..53da9b4f6ba34b03768d77158c19d53e44681809
@@@ -270,31 -270,31 +270,31 @@@ See linkgit:git[1] for details
  Defining a custom hunk-header
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  
 -Each group of changes (called "hunk") in the textual diff output
 +Each group of changes (called "hunk") in the textual diff output
  is prefixed with a line of the form:
  
        @@ -k,l +n,m @@ TEXT
  
 -The text is called 'hunk header', and by default a line that
 -begins with an alphabet, an underscore or a dollar sign is used,
 -which matches what GNU 'diff -p' output uses.  This default
 -selection however is not suited for some contents, and you can
 -use customized pattern to make a selection.
 +This is called a 'hunk header'.  The "TEXT" portion is by default a line
 +that begins with an alphabet, an underscore or a dollar sign; this
 +matches what GNU 'diff -p' output uses.  This default selection however
 +is not suited for some contents, and you can use a customized pattern
 +to make a selection.
  
 -First in .gitattributes, you would assign the `diff` attribute
 +First, in .gitattributes, you would assign the `diff` attribute
  for paths.
  
  ------------------------
  *.tex diff=tex
  ------------------------
  
- Then, you would define a "diff.tex.funcname" configuration to
 -Then, you would define "diff.tex.xfuncname" configuration to
++Then, you would define a "diff.tex.xfuncname" configuration to
  specify a regular expression that matches a line that you would
 -want to appear as the hunk header, like this:
 +want to appear as the hunk header "TEXT", like this:
  
  ------------------------
  [diff "tex"]
-       funcname = "^\\(\\\\\\(sub\\)*section{.*\\)$"
+       xfuncname = "^(\\\\(sub)*section\\{.*)$"
  ------------------------
  
  Note.  A single level of backslashes are eaten by the
diff --combined diff.c
index 9385a36f1efb1f52250dfa42dbf994f5fd03856d,a28373861689d1baf02ffdf969da1e843ea9c237..781fa15ac13ce11f8b77b95665659cfcbcab5836
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -94,32 -94,37 +94,37 @@@ static int parse_lldiff_command(const c
   * to define a customized regexp to find the beginning of a function to
   * be used for hunk header lines of "diff -p" style output.
   */
- static struct funcname_pattern {
+ struct funcname_pattern_entry {
        char *name;
        char *pattern;
-       struct funcname_pattern *next;
+       int cflags;
+ };
+ static struct funcname_pattern_list {
+       struct funcname_pattern_list *next;
+       struct funcname_pattern_entry e;
  } *funcname_pattern_list;
  
- static int parse_funcname_pattern(const char *var, const char *ep, const char *value)
+ static int parse_funcname_pattern(const char *var, const char *ep, const char *value, int cflags)
  {
        const char *name;
        int namelen;
-       struct funcname_pattern *pp;
+       struct funcname_pattern_list *pp;
  
        name = var + 5; /* "diff." */
        namelen = ep - name;
  
        for (pp = funcname_pattern_list; pp; pp = pp->next)
-               if (!strncmp(pp->name, name, namelen) && !pp->name[namelen])
+               if (!strncmp(pp->e.name, name, namelen) && !pp->e.name[namelen])
                        break;
        if (!pp) {
                pp = xcalloc(1, sizeof(*pp));
-               pp->name = xmemdupz(name, namelen);
+               pp->e.name = xmemdupz(name, namelen);
                pp->next = funcname_pattern_list;
                funcname_pattern_list = pp;
        }
-       free(pp->pattern);
-       pp->pattern = xstrdup(value);
+       free(pp->e.pattern);
+       pp->e.pattern = xstrdup(value);
+       pp->e.cflags = cflags;
        return 0;
  }
  
@@@ -182,7 -187,13 +187,13 @@@ int git_diff_basic_config(const char *v
                        if (!strcmp(ep, ".funcname")) {
                                if (!value)
                                        return config_error_nonbool(var);
-                               return parse_funcname_pattern(var, ep, value);
+                               return parse_funcname_pattern(var, ep, value,
+                                       0);
+                       } else if (!strcmp(ep, ".xfuncname")) {
+                               if (!value)
+                                       return config_error_nonbool(var);
+                               return parse_funcname_pattern(var, ep, value,
+                                       REG_EXTENDED);
                        }
                }
        }
@@@ -1377,39 -1388,40 +1388,40 @@@ int diff_filespec_is_binary(struct diff
        return one->is_binary;
  }
  
- static const char *funcname_pattern(const char *ident)
+ static const struct funcname_pattern_entry *funcname_pattern(const char *ident)
  {
-       struct funcname_pattern *pp;
+       struct funcname_pattern_list *pp;
  
        for (pp = funcname_pattern_list; pp; pp = pp->next)
-               if (!strcmp(ident, pp->name))
-                       return pp->pattern;
+               if (!strcmp(ident, pp->e.name))
+                       return &pp->e;
        return NULL;
  }
  
- static struct builtin_funcname_pattern {
-       const char *name;
-       const char *pattern;
- } builtin_funcname_pattern[] = {
-       { "java", "!^[  ]*\\(catch\\|do\\|for\\|if\\|instanceof\\|"
-                       "new\\|return\\|switch\\|throw\\|while\\)\n"
-                       "^[     ]*\\(\\([       ]*"
-                       "[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}"
-                       "[      ]*([^;]*\\)$" },
-       { "pascal", "^\\(\\(procedure\\|function\\|constructor\\|"
-                       "destructor\\|interface\\|implementation\\|"
-                       "initialization\\|finalization\\)[ \t]*.*\\)$"
-                       "\\|"
-                       "^\\(.*=[ \t]*\\(class\\|record\\).*\\)$"
-                       },
-       { "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" },
-       { "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" },
-       { "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" },
+ static const struct funcname_pattern_entry builtin_funcname_pattern[] = {
+       { "java",
+         "!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
+         "^[ \t]*(([ \t]*[A-Za-z_][A-Za-z_0-9]*){2,}[ \t]*\\([^;]*)$",
+         REG_EXTENDED },
+       { "pascal",
+         "^((procedure|function|constructor|destructor|interface|"
+               "implementation|initialization|finalization)[ \t]*.*)$"
+         "|"
+         "^(.*=[ \t]*(class|record).*)$",
+         REG_EXTENDED },
+       { "bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
+         REG_EXTENDED },
+       { "tex",
+         "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
+         REG_EXTENDED },
+       { "ruby", "^[ \t]*((class|module|def)[ \t].*)$",
+         REG_EXTENDED },
  };
  
- static const char *diff_funcname_pattern(struct diff_filespec *one)
+ static const struct funcname_pattern_entry *diff_funcname_pattern(struct diff_filespec *one)
  {
-       const char *ident, *pattern;
+       const char *ident;
+       const struct funcname_pattern_entry *pe;
        int i;
  
        diff_filespec_check_attr(one);
                return funcname_pattern("default");
  
        /* Look up custom "funcname.$ident" regexp from config. */
-       pattern = funcname_pattern(ident);
-       if (pattern)
-               return pattern;
+       pe = funcname_pattern(ident);
+       if (pe)
+               return pe;
  
        /*
         * And define built-in fallback patterns here.  Note that
         */
        for (i = 0; i < ARRAY_SIZE(builtin_funcname_pattern); i++)
                if (!strcmp(ident, builtin_funcname_pattern[i].name))
-                       return builtin_funcname_pattern[i].pattern;
+                       return &builtin_funcname_pattern[i];
  
        return NULL;
  }
@@@ -1512,11 -1524,11 +1524,11 @@@ static void builtin_diff(const char *na
                xdemitconf_t xecfg;
                xdemitcb_t ecb;
                struct emit_callback ecbdata;
-               const char *funcname_pattern;
+               const struct funcname_pattern_entry *pe;
  
-               funcname_pattern = diff_funcname_pattern(one);
-               if (!funcname_pattern)
-                       funcname_pattern = diff_funcname_pattern(two);
+               pe = diff_funcname_pattern(one);
+               if (!pe)
+                       pe = diff_funcname_pattern(two);
  
                memset(&xecfg, 0, sizeof(xecfg));
                memset(&ecbdata, 0, sizeof(ecbdata));
                xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
                xecfg.ctxlen = o->context;
                xecfg.flags = XDL_EMIT_FUNCNAMES;
-               if (funcname_pattern)
-                       xdiff_set_find_func(&xecfg, funcname_pattern);
+               if (pe)
+                       xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags);
                if (!diffopts)
                        ;
                else if (!prefixcmp(diffopts, "--unified="))
@@@ -2400,6 -2412,13 +2412,6 @@@ int diff_setup_done(struct diff_option
                DIFF_OPT_SET(options, EXIT_WITH_STATUS);
        }
  
 -      /*
 -       * If we postprocess in diffcore, we cannot simply return
 -       * upon the first hit.  We need to run diff as usual.
 -       */
 -      if (options->pickaxe || options->filter)
 -              DIFF_OPT_CLR(options, QUIET);
 -
        return 0;
  }
  
@@@ -3391,7 -3410,10 +3403,7 @@@ static void diffcore_skip_stat_unmatch(
  
  void diffcore_std(struct diff_options *options)
  {
 -      if (DIFF_OPT_TST(options, QUIET))
 -              return;
 -
 -      if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER))
 +      if (options->skip_stat_unmatch)
                diffcore_skip_stat_unmatch(options);
        if (options->break_opt != -1)
                diffcore_break(options->break_opt);