--- patch.c | 42 +++++++++++++++++++++++++++++++-------- tests/unified-reject-files.shrun | 32 ++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 16 deletions(-) Index: b/patch.c =================================================================== --- a/patch.c +++ b/patch.c @@ -66,8 +66,8 @@ static bool patch_match (LINENUM, LINENU static bool similar (char const *, size_t, char const *, size_t); static bool spew_output (struct outstate *); static char const *make_temp (char); -static void abort_hunk_context (void); -static void abort_hunk_unified (void); +static void abort_hunk_context (bool, bool); +static void abort_hunk_unified (bool, bool); static int numeric_string (char const *, bool, char const *); static void cleanup (void); static void get_some_switches (void); @@ -77,7 +77,7 @@ static void reinitialize_almost_everythi static void remove_if_needed (char const *, int volatile *); static void usage (FILE *, int) __attribute__((noreturn)); -static void (*abort_hunk) (void) = abort_hunk_context; +static void (*abort_hunk) (bool, bool) = abort_hunk_context; static bool make_backups; static bool backup_if_mismatch; @@ -281,7 +281,7 @@ main (int argc, char **argv) newwhere = pch_newfirst() + last_offset; if (skip_rest_of_patch) { - abort_hunk(); + abort_hunk(!failed, reverse); failed++; if (verbosity == VERBOSE) say ("Hunk #%d ignored at %s.\n", hunk, @@ -295,14 +295,14 @@ main (int argc, char **argv) say ("Patch attempted to create file %s, which already exists.\n", quotearg (inname)); - abort_hunk(); + abort_hunk(!failed, reverse); failed++; if (verbosity != SILENT) say ("Hunk #%d FAILED at %s.\n", hunk, format_linenum (numbuf, newwhere)); } else if (! apply_hunk (&outstate, where)) { - abort_hunk (); + abort_hunk (!failed, reverse); failed++; if (verbosity != SILENT) say ("Hunk #%d FAILED at %s.\n", hunk, @@ -938,7 +938,24 @@ locate_hunk (LINENUM fuzz) /* We did not find the pattern, dump out the hunk so they can handle it. */ static void -abort_hunk_context (void) +print_header_line(FILE *fp, const char *tag, bool reverse) +{ + const char *name = pch_name(reverse); + time_t time = pch_timestamp(reverse); + char timebuf[37]; + + if (time != -1) { + timebuf[0] = '\t'; + strftime(timebuf + 1, sizeof(timebuf), + "%Y-%m-%d %H:%M:%S %z", + (set_utc ? gmtime : localtime)(&time)); + } else + *timebuf = '\0'; + fprintf(fp, "%s %s%s\n", tag, name ? name : "/dev/null", timebuf); +} + +static void +abort_hunk_context (bool header, bool reverse) { register LINENUM i; register LINENUM pat_end = pch_end (); @@ -953,6 +970,10 @@ abort_hunk_context (void) (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ----" : " -----"; char const *c_function = pch_c_function(); + if (header) { + print_header_line(rejfp, "***", reverse); + print_header_line(rejfp, "---", ! reverse); + } fprintf(rejfp, "***************%s\n", c_function ? c_function : ""); for (i=0; i<=pat_end; i++) { char numbuf0[LINENUM_LENGTH_BOUND + 1]; @@ -1066,7 +1087,7 @@ print_unified(FILE *fp) } static void -abort_hunk_unified (void) +abort_hunk_unified (bool header, bool reverse) { char rangebuf0[LINERANGE_LENGTH_BOUND + 1]; char rangebuf1[LINERANGE_LENGTH_BOUND + 1]; @@ -1074,6 +1095,11 @@ abort_hunk_unified (void) LINENUM newfirst = pch_newfirst () + last_offset; char const *c_function = pch_c_function (); + if (header) + { + print_header_line (rejfp, "---", reverse); + print_header_line (rejfp, "+++", ! reverse); + } fprintf (rejfp, "@@ -%s +%s @@%s\n", format_startcount (rangebuf0, oldfirst, pch_ptrn_lines ()), format_startcount (rangebuf1, newfirst, pch_repl_lines ()), Index: b/tests/unified-reject-files.shrun =================================================================== --- a/tests/unified-reject-files.shrun +++ b/tests/unified-reject-files.shrun @@ -1,4 +1,6 @@ -$ PATCH=$(pwd)/patch +$ PATCH=$(PATH=.:$PATH which patch) +$ patch() { $PATCH "$@"; } + $ tmpdir=$(mktemp -d) $ trap "cd /; rm -rf $tmpdir" EXIT $ cd $tmpdir @@ -17,12 +19,14 @@ $ diff -U0 -p \ + -L "f 2009-02-07 14:49:03.000000000 +0100" \ + f.orig f > f.diff -$ $PATCH -f -F0 -s --no-backup-if-mismatch f < f.diff +$ patch -f -F0 -s --no-backup-if-mismatch f < f.diff > 1 out of 1 hunk FAILED -- saving rejects to file f.rej Note: patch cannot deal with nanosecond timestamps :-( $ cat f.rej +> *** f.orig 2009-02-07 14:49:02 +0100 +> --- f 2009-02-07 14:49:03 +0100 > *************** a() { > *** 5 **** > - 5 @@ -30,38 +34,46 @@ $ cat f.rej > + 5a $ diff -U0 -p -L f.orig -L f f.orig f > f.diff -$ $PATCH -f -F0 -s --no-backup-if-mismatch --unified-reject-files f < f.diff +$ patch -f -F0 -s --no-backup-if-mismatch --unified-reject-files f < f.diff > 1 out of 1 hunk FAILED -- saving rejects to file f.rej $ cat f.rej +> --- f.orig +> +++ f > @@ -5 +5 @@ a() { > -5 > +5a -$ $PATCH -f -F0 -s --no-backup-if-mismatch f < f.diff +$ patch -f -F0 -s --no-backup-if-mismatch f < f.diff > 1 out of 1 hunk FAILED -- saving rejects to file f.rej $ cat f.rej +> *** f.orig +> --- f > *************** a() { > *** 5 **** > - 5 > --- 5 ---- > + 5a -$ $PATCH -f -F0 -s --no-backup-if-mismatch --unified-reject-files -R f.orig < f.diff +$ patch -f -F0 -s --no-backup-if-mismatch --unified-reject-files -R f.orig < f.diff > 1 out of 1 hunk FAILED -- saving rejects to file f.orig.rej $ cat f.orig.rej +> --- f +> +++ f.orig > @@ -5 +5 @@ a() { > -5a > +5 $ diff -U2 -p -L f.orig -L f f.orig f > f.diff $ sed -e 's/5/5a/' -e 's/6/6x/' f.orig > f -$ $PATCH -F0 -s --no-backup-if-mismatch --unified-reject-files f < f.diff +$ patch -F0 -s --no-backup-if-mismatch --unified-reject-files f < f.diff > 1 out of 1 hunk FAILED -- saving rejects to file f.rej $ cat f.rej +> --- f.orig +> +++ f > @@ -3,5 +3,5 @@ a() { > 3 > @@ -70,10 +82,12 @@ $ cat f.rej > 6 > } -$ $PATCH -F0 -s --no-backup-if-mismatch f < f.diff +$ patch -F0 -s --no-backup-if-mismatch f < f.diff > 1 out of 1 hunk FAILED -- saving rejects to file f.rej $ cat f.rej +> *** f.orig +> --- f > *************** a() { > *** 3,7 **** > 3 @@ -89,11 +103,13 @@ $ cat f.rej > } $ diff -Nu -p -L /dev/null -L f.orig /dev/null f.orig > f2.diff -$ $PATCH -F0 -s --no-backup-if-mismatch --unified-reject-files f --set-utc < f2.diff +$ patch -F0 -s --no-backup-if-mismatch --unified-reject-files f --set-utc < f2.diff > Patch attempted to create file f, which already exists. > 1 out of 1 hunk FAILED -- saving rejects to file f.rej $ cat f.rej +> --- /dev/null 1970-01-01 00:00:00 +0000 +> +++ f.orig > @@ -0,0 +1,7 @@ > +a() { > +2