@matheusbsbs / matheus-bagliano / commits / 3d8dccd74a
Fork 0

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: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Sep 20, 2008 at 00:52 UTC 3d8dccd74aa29a9019c4e8b52e75a40189e6f5cb
2 files changed +11 -8
diff.c
+1 -1
@@ -1414,7 +1414,7 @@ static const struct funcname_pattern_entry builtin_funcname_pattern[] = {
1414 { "pascal",
1415 "^((procedure|function|constructor|destructor|interface|"
1416 "implementation|initialization|finalization)[ \t]*.*)$"
1417 - "|"
1417 + "\n"
1418 "^(.*=[ \t]*(class|record).*)$",
1419 REG_EXTENDED },
1420 { "php", "^[\t ]*((function|class).*)", REG_EXTENDED },
xdiff-interface.c
+10 -7
@@ -194,26 +194,29 @@ static long ff_regexp(const char *line, long len,
194 char *line_buffer = xstrndup(line, len); /* make NUL terminated */
195 struct ff_regs *regs = priv;
196 regmatch_t pmatch[2];
197 - int result = 0, i;
197 + int i;
198 + int result = -1;
199
200 for (i = 0; i < regs->nr; i++) {
201 struct ff_reg *reg = regs->array + i;
201 - if (reg->negate ^ !!regexec(&reg->re,
202 - line_buffer, 2, pmatch, 0)) {
203 - free(line_buffer);
204 - return -1;
202 + if (!regexec(&reg->re, line_buffer, 2, pmatch, 0)) {
203 + if (reg->negate)
204 + goto fail;
205 + break;
206 }
207 }
208 + if (regs->nr <= i)
209 + goto fail;
210 i = pmatch[1].rm_so >= 0 ? 1 : 0;
211 line += pmatch[i].rm_so;
212 result = pmatch[i].rm_eo - pmatch[i].rm_so;
213 if (result > buffer_size)
214 result = buffer_size;
215 else
213 - while (result > 0 && (isspace(line[result - 1]) ||
214 - line[result - 1] == '\n'))
216 + while (result > 0 && (isspace(line[result - 1])))
217 result--;
218 memcpy(buffer, line, result);
219 + fail:
220 free(line_buffer);
221 return result;
222 }