diff options
| author | Junio C Hamano <gitster@pobox.com> | 2008-09-20 00:52:11 -0700 | 
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2008-09-20 00:52:11 -0700 | 
| commit | 3d8dccd74aa29a9019c4e8b52e75a40189e6f5cb (patch) | |
| tree | 909f000e201535f714e52bef7cf142ddb25a62eb /xdiff-interface.c | |
| parent | 1883a0d3b7ad7c9de1ac790bda6f1a6181237439 (diff) | |
| download | git-3d8dccd74aa29a9019c4e8b52e75a40189e6f5cb.tar.gz | |
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>
Diffstat (limited to 'xdiff-interface.c')
| -rw-r--r-- | xdiff-interface.c | 17 | 
1 files changed, 10 insertions, 7 deletions
diff --git a/xdiff-interface.c b/xdiff-interface.c index 7f1a7d3ffc..6c6bb19973 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -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(®->re, -					line_buffer, 2, pmatch, 0)) { -			free(line_buffer); -			return -1; +		if (!regexec(®->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;  }  | 
