FYI, This was discussed some time ago. I've just pushed it, along with a test and one more small change.
>From 24cc227fa1900502d167a60a8325af576dfe5552 Mon Sep 17 00:00:00 2001 From: Yannick Moy <[email protected]> Date: Thu, 4 Mar 2010 14:20:16 +0100 Subject: [PATCH 1/5] with -F or -p, emit better function lines: no leading white space * src/diff.c (print_context_function): For languages like Ada that allow local functions and procedures, the plain context function line may start with enough blank characters that the function name does not get completely printed in the 40 characters limit. This patch solves this problem by removing these useless initial blank characters. * NEWS (Changes in behavior): Mention this change. --- NEWS | 7 +++++++ src/context.c | 12 +++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 569c4ef..2d20b40 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,13 @@ GNU diffutils NEWS -*- outline -*- ** Changes in behavior + In context-style diffs, diff prints a portion of a preceding "function" + line for each hunk, with --show-function-line=RE (-F) or + --show-c-function (-p). Now, it trims leading blanks from such lines + before extracting a prefix. This is useful especially when a function + line is so far indented that the name itself would be truncated or not + included in the limited-width substring that diff appends. + diff once again reports a difference with the diagnostic "Binary files A and B differ" when at least one of the files appears to be binary. From 2.8.4 through diffutils-2.9, it printed diff --git a/src/context.c b/src/context.c index e918134..84120f0 100644 --- a/src/context.c +++ b/src/context.c @@ -145,13 +145,15 @@ print_context_number_range (struct file_data const *file, lin a, lin b) static void print_context_function (FILE *out, char const *function) { - int i; + int i, j; putc (' ', out); - for (i = 0; i < 40 && function[i] != '\n'; i++) + for (i = 0; isspace ((unsigned char)function[i]) && function[i] != '\n'; i++) continue; - while (0 < i && isspace ((unsigned char) function[i - 1])) - i--; - fwrite (function, sizeof (char), i, out); + for (j = i; j < i + 40 && function[j] != '\n'; j++) + continue; + while (i < j && isspace ((unsigned char) function[j - 1])) + j--; + fwrite (function + i, sizeof (char), j - i, out); } /* Print a portion of an edit script in context format. -- 1.7.0.4.552.gc303 >From f21d1195aef067e6459cca8a1b79a50498a10532 Mon Sep 17 00:00:00 2001 From: Jim Meyering <[email protected]> Date: Thu, 18 Mar 2010 17:25:50 +0100 Subject: [PATCH 2/5] tests: exercise new behavior of -F RE * tests/function-line-vs-leading-space: New file. * tests/Makefile.am (TESTS): Add it. --- tests/Makefile.am | 1 + tests/function-line-vs-leading-space | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 0 deletions(-) create mode 100755 tests/function-line-vs-leading-space diff --git a/tests/Makefile.am b/tests/Makefile.am index 9edd28c..cf48f15 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,6 +2,7 @@ TESTS = \ basic \ binary \ help-version \ + function-line-vs-leading-space \ label-vs-func \ stdin diff --git a/tests/function-line-vs-leading-space b/tests/function-line-vs-leading-space new file mode 100755 index 0000000..320452c --- /dev/null +++ b/tests/function-line-vs-leading-space @@ -0,0 +1,67 @@ +#!/bin/sh +# Demonstrate how -F RE behavior changed after diff-2.9. + +test "$VERBOSE" = yes && set -x +: ${srcdir=.} +. "$srcdir/init.sh" + +cat <<EOF > in || fail_ "failed to create temporary file" +procedure AdaCode is + procedure Local_Level_1 is + procedure Local_Level_2 is + procedure Local_Level_3 is + procedure Local_Level_4 is + procedure Local_Level_5 is + begin + null; + null; + null; + foo; + end; + begin + Local_Level_5; + end; + begin + Local_Level_4; + end; + begin + Local_Level_3; + end; + begin + Local_Level_2; + end; +begin + Local_Level_1; +end; +EOF + +sed s/foo/null/ < in > in2 || fail_ "failed to create temporary file" + +# Before diff-2.10, the function line would be truncated like this: +# @@ -8,7 +8,7 @@ procedure Local_Leve + +cat <<EOF > exp || fail_ "failed to create temporary file" +@@ -8,7 +8,7 @@ procedure Local_Level_5 is + null; + null; + null; +- foo; ++ null; + end; + begin + Local_Level_5; +EOF + +fail=0 + +diff -u -F '^[[:space:]]*\(function\|procedure\)' in in2 > out 2> err +test $? = 1 || fail=1 + +tail -n+3 out > k && mv k out || fail=1 + +compare out exp || fail=1 + +# expect empty stderr +compare err /dev/null || fail=1 + +Exit $fail -- 1.7.0.4.552.gc303 >From eb8258b8c6b3930e06fc20b02456448c43daeff1 Mon Sep 17 00:00:00 2001 From: Jim Meyering <[email protected]> Date: Thu, 18 Mar 2010 18:10:29 +0100 Subject: [PATCH 3/5] diff -F/-p: don't depend on locale-specific white-space definition * src/context.c: Include "c-ctype.h". Use c_isspace, not isspace. --- src/context.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/context.c b/src/context.c index 84120f0..0be8cc5 100644 --- a/src/context.c +++ b/src/context.c @@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "diff.h" +#include "c-ctype.h" #include <inttostr.h> #include <stat-time.h> #include <strftime.h> @@ -147,11 +148,11 @@ print_context_function (FILE *out, char const *function) { int i, j; putc (' ', out); - for (i = 0; isspace ((unsigned char)function[i]) && function[i] != '\n'; i++) + for (i = 0; c_isspace ((unsigned char) function[i]) && function[i] != '\n'; i++) continue; for (j = i; j < i + 40 && function[j] != '\n'; j++) continue; - while (i < j && isspace ((unsigned char) function[j - 1])) + while (i < j && c_isspace ((unsigned char) function[j - 1])) j--; fwrite (function + i, sizeof (char), j - i, out); } -- 1.7.0.4.552.gc303
