From: Shawn O. Pearce Date: Mon, 29 Sep 2008 17:23:19 +0000 (-0700) Subject: Merge branch 'bc/maint-diff-hunk-header-fix' into maint X-Git-Tag: v1.6.0.3~52 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/edb7e82f72106add9f2fbaf9d99d9532a72e3f91?ds=inline;hp=-c Merge branch 'bc/maint-diff-hunk-header-fix' into maint * 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 --- edb7e82f72106add9f2fbaf9d99d9532a72e3f91 diff --combined Documentation/gitattributes.txt index 89627688b8,9259637609..53da9b4f6b --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@@ -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 a "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 9385a36f1e,a283738616..781fa15ac1 --- a/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); @@@ -1424,9 -1436,9 +1436,9 @@@ 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 @@@ -1434,7 -1446,7 +1446,7 @@@ */ 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)); @@@ -1528,8 -1540,8 +1540,8 @@@ 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);