forked from pool/patch
296 lines
7.7 KiB
Diff
296 lines
7.7 KiB
Diff
Generate unified diff style reject files.
|
|
|
|
---
|
|
patch.c | 104 +++++++++++++++++++++++++++++++++++++--
|
|
patch.man | 3 +
|
|
tests/unified-reject-files.shrun | 104 +++++++++++++++++++++++++++++++++++++++
|
|
3 files changed, 208 insertions(+), 3 deletions(-)
|
|
|
|
Index: b/patch.man
|
|
===================================================================
|
|
--- a/patch.man
|
|
+++ b/patch.man
|
|
@@ -517,6 +517,9 @@ instead of the default
|
|
.B \&.rej
|
|
file.
|
|
.TP
|
|
+\fB\*=unified\-reject\-files\fP
|
|
+Produce unified reject files. The default is to produce context type reject files.
|
|
+.TP
|
|
\fB\-R\fP or \fB\*=reverse\fP
|
|
Assume that this patch was created with the old and new files swapped.
|
|
(Yes, I'm afraid that does happen occasionally, human nature being what it
|
|
Index: b/patch.c
|
|
===================================================================
|
|
--- a/patch.c
|
|
+++ b/patch.c
|
|
@@ -66,8 +66,9 @@ 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 int numeric_string (char const *, bool, char const *);
|
|
-static void abort_hunk (void);
|
|
static void cleanup (void);
|
|
static void get_some_switches (void);
|
|
static void init_output (char const *, int, struct outstate *);
|
|
@@ -76,6 +77,8 @@ 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 bool make_backups;
|
|
static bool backup_if_mismatch;
|
|
static char const *version_control;
|
|
@@ -522,6 +525,7 @@ static struct option const longopts[] =
|
|
{"no-backup-if-mismatch", no_argument, NULL, CHAR_MAX + 6},
|
|
{"posix", no_argument, NULL, CHAR_MAX + 7},
|
|
{"quoting-style", required_argument, NULL, CHAR_MAX + 8},
|
|
+ {"unified-reject-files", no_argument, NULL, CHAR_MAX + 9},
|
|
{NULL, no_argument, NULL, 0}
|
|
};
|
|
|
|
@@ -580,6 +584,7 @@ static char const *const option_help[] =
|
|
" --verbose Output extra information about the work being done.",
|
|
" --dry-run Do not actually change any files; just print what would happen.",
|
|
" --posix Conform to the POSIX standard.",
|
|
+" --unified-reject-files Create unified reject files.",
|
|
"",
|
|
" -d DIR --directory=DIR Change the working directory to DIR first.",
|
|
#if HAVE_SETMODE_DOS
|
|
@@ -779,6 +784,9 @@ get_some_switches (void)
|
|
(enum quoting_style) i);
|
|
}
|
|
break;
|
|
+ case CHAR_MAX + 9:
|
|
+ abort_hunk = abort_hunk_unified;
|
|
+ break;
|
|
default:
|
|
usage (stderr, 2);
|
|
}
|
|
@@ -930,7 +938,7 @@ locate_hunk (LINENUM fuzz)
|
|
/* We did not find the pattern, dump out the hunk so they can handle it. */
|
|
|
|
static void
|
|
-abort_hunk (void)
|
|
+abort_hunk_context (void)
|
|
{
|
|
register LINENUM i;
|
|
register LINENUM pat_end = pch_end ();
|
|
@@ -979,13 +987,103 @@ abort_hunk (void)
|
|
pch_write_line (i, rejfp);
|
|
break;
|
|
default:
|
|
- fatal ("fatal internal error in abort_hunk");
|
|
+ fatal ("fatal internal error in abort_hunk_context");
|
|
}
|
|
if (ferror (rejfp))
|
|
write_fatal ();
|
|
}
|
|
}
|
|
|
|
+/* Produce unified reject files */
|
|
+
|
|
+static void
|
|
+print_unified(FILE *fp)
|
|
+{
|
|
+ register LINENUM old = 1;
|
|
+ register LINENUM lastline = pch_ptrn_lines ();
|
|
+ register LINENUM new = lastline + 1;
|
|
+ register LINENUM pat_end = pch_end ();
|
|
+
|
|
+ while (pch_char (new) == '=' || pch_char (new) == '\n')
|
|
+ new++;
|
|
+
|
|
+ while (old <= lastline)
|
|
+ {
|
|
+ if (pch_char (old) == '-')
|
|
+ {
|
|
+ fputc ('-', fp);
|
|
+ pch_write_line (old++, fp);
|
|
+ }
|
|
+ else if (new > pat_end)
|
|
+ break;
|
|
+ else if (pch_char (new) == '+')
|
|
+ {
|
|
+ fputc ('+', fp);
|
|
+ pch_write_line (new++, fp);
|
|
+ }
|
|
+ else if (pch_char (new) != pch_char (old))
|
|
+ {
|
|
+ char numbuf0[LINENUM_LENGTH_BOUND + 1];
|
|
+ char numbuf1[LINENUM_LENGTH_BOUND + 1];
|
|
+ if (debug & 1)
|
|
+ say ("oldchar = '%c', newchar = '%c'\n",
|
|
+ pch_char (old), pch_char (new));
|
|
+ fatal ("Out-of-sync patch, lines %s,%s -- mangled text or "
|
|
+ "line numbers, maybe?",
|
|
+ format_linenum (numbuf0, pch_hunk_beg () + old),
|
|
+ format_linenum (numbuf1, pch_hunk_beg () + new));
|
|
+ }
|
|
+ else if (pch_char (new) == '!')
|
|
+ {
|
|
+ do
|
|
+ {
|
|
+ fputc ('-', fp);
|
|
+ pch_write_line (old++, fp);
|
|
+ }
|
|
+ while (pch_char (old) == '!');
|
|
+ do
|
|
+ {
|
|
+ fputc ('+', fp);
|
|
+ pch_write_line (new++, fp);
|
|
+ }
|
|
+ while (pch_char (new) == '!');
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ assert (pch_char (new) == ' ');
|
|
+ fputc (' ', fp);
|
|
+ pch_write_line (new, fp);
|
|
+ old++;
|
|
+ new++;
|
|
+ }
|
|
+ }
|
|
+ while (pch_char (new) == '+' || pch_char (new) == ' ')
|
|
+ {
|
|
+ fputc ('+', fp);
|
|
+ pch_write_line (new++, fp);
|
|
+ }
|
|
+ assert (new > pat_end);
|
|
+}
|
|
+
|
|
+static void
|
|
+abort_hunk_unified (void)
|
|
+{
|
|
+ char rangebuf0[LINERANGE_LENGTH_BOUND + 1];
|
|
+ char rangebuf1[LINERANGE_LENGTH_BOUND + 1];
|
|
+ LINENUM oldfirst = pch_first () + last_offset;
|
|
+ LINENUM newfirst = pch_newfirst () + last_offset;
|
|
+ char const *c_function = pch_c_function ();
|
|
+
|
|
+ fprintf (rejfp, "@@ -%s +%s @@%s\n",
|
|
+ format_startcount (rangebuf0, oldfirst, pch_ptrn_lines ()),
|
|
+ format_startcount (rangebuf1, newfirst, pch_repl_lines ()),
|
|
+ c_function ? c_function : "");
|
|
+ print_unified (rejfp);
|
|
+
|
|
+ if (ferror (rejfp))
|
|
+ write_fatal ();
|
|
+}
|
|
+
|
|
/* We found where to apply it (we hope), so do it. */
|
|
|
|
static bool
|
|
Index: b/tests/unified-reject-files.shrun
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ b/tests/unified-reject-files.shrun
|
|
@@ -0,0 +1,104 @@
|
|
+$ PATCH=$(pwd)/patch
|
|
+$ tmpdir=$(mktemp -d)
|
|
+$ trap "cd /; rm -rf $tmpdir" EXIT
|
|
+$ cd $tmpdir
|
|
+$ cat > f.orig
|
|
+< a() {
|
|
+< 2
|
|
+< 3
|
|
+<
|
|
+< 5
|
|
+< 6
|
|
+< }
|
|
+
|
|
+$ sed -e 's/5/5a/' f.orig > f
|
|
+$ diff -U0 -p \
|
|
++ -L "f.orig 2009-02-07 14:49:02.000000000 +0100" \
|
|
++ -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
|
|
+> 1 out of 1 hunk FAILED -- saving rejects to file f.rej
|
|
+
|
|
+Note: patch cannot deal with nanosecond timestamps :-(
|
|
+
|
|
+$ cat f.rej
|
|
+> *************** a() {
|
|
+> *** 5 ****
|
|
+> - 5
|
|
+> --- 5 ----
|
|
+> + 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
|
|
+> 1 out of 1 hunk FAILED -- saving rejects to file f.rej
|
|
+
|
|
+$ cat f.rej
|
|
+> @@ -5 +5 @@ a() {
|
|
+> -5
|
|
+> +5a
|
|
+
|
|
+$ $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
|
|
+> *************** a() {
|
|
+> *** 5 ****
|
|
+> - 5
|
|
+> --- 5 ----
|
|
+> + 5a
|
|
+
|
|
+$ $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
|
|
+> @@ -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
|
|
+> 1 out of 1 hunk FAILED -- saving rejects to file f.rej
|
|
+
|
|
+$ cat f.rej
|
|
+> @@ -3,5 +3,5 @@ a() {
|
|
+> 3
|
|
+>
|
|
+> -5
|
|
+> +5a
|
|
+> 6
|
|
+> }
|
|
+
|
|
+$ $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
|
|
+> *************** a() {
|
|
+> *** 3,7 ****
|
|
+> 3
|
|
+>
|
|
+> - 5
|
|
+> 6
|
|
+> }
|
|
+> --- 3,7 ----
|
|
+> 3
|
|
+>
|
|
+> + 5a
|
|
+> 6
|
|
+> }
|
|
+
|
|
+$ 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 attempted to create file f, which already exists.
|
|
+> 1 out of 1 hunk FAILED -- saving rejects to file f.rej
|
|
+
|
|
+$ cat f.rej
|
|
+> @@ -0,0 +1,7 @@
|
|
+> +a() {
|
|
+> +2
|
|
+> +3
|
|
+> +
|
|
+> +5
|
|
+> +6
|
|
+> +}
|