提交 3d8dccd7 编写于 作者: J Junio C Hamano

diff: fix "multiple regexp" semantics to find hunk header comment

When multiple regular expressions are concatenated with "\n", they were
traditionally AND'ed together, and only a line that matches _all_ of them
is taken as a match.  This however is unwieldy when multiple regexp
feature is used to specify alternatives.

This fixes the semantics to take the first match.  A nagative pattern, if
matches, makes the line to fail as before.  A match with a positive
pattern will be the final match, and what it captures in $1 is used as the
hunk header comment.

We could write alternatives using "|" in ERE, but the machinery can only
use captured $1 as the hunk header comment (or $0 if there is no match in
$1), so you cannot write:

    "junk ( A | B ) | garbage ( C | D )"

and expect both "junk" and "garbage" to get stripped with the existing
code.  With this fix, you can write it as:

    "junk ( A | B ) \n garbage ( C | D )"

and the way capture works would match the user expectation more
naturally.
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 1883a0d3
......@@ -1414,7 +1414,7 @@ static const struct funcname_pattern_entry builtin_funcname_pattern[] = {
{ "pascal",
"^((procedure|function|constructor|destructor|interface|"
"implementation|initialization|finalization)[ \t]*.*)$"
"|"
"\n"
"^(.*=[ \t]*(class|record).*)$",
REG_EXTENDED },
{ "php", "^[\t ]*((function|class).*)", REG_EXTENDED },
......
......@@ -194,26 +194,29 @@ static long ff_regexp(const char *line, long len,
char *line_buffer = xstrndup(line, len); /* make NUL terminated */
struct ff_regs *regs = priv;
regmatch_t pmatch[2];
int result = 0, i;
int i;
int result = -1;
for (i = 0; i < regs->nr; i++) {
struct ff_reg *reg = regs->array + i;
if (reg->negate ^ !!regexec(&reg->re,
line_buffer, 2, pmatch, 0)) {
free(line_buffer);
return -1;
if (!regexec(&reg->re, line_buffer, 2, pmatch, 0)) {
if (reg->negate)
goto fail;
break;
}
}
if (regs->nr <= i)
goto fail;
i = pmatch[1].rm_so >= 0 ? 1 : 0;
line += pmatch[i].rm_so;
result = pmatch[i].rm_eo - pmatch[i].rm_so;
if (result > buffer_size)
result = buffer_size;
else
while (result > 0 && (isspace(line[result - 1]) ||
line[result - 1] == '\n'))
while (result > 0 && (isspace(line[result - 1])))
result--;
memcpy(buffer, line, result);
fail:
free(line_buffer);
return result;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册