Hello community,
here is the log from the commit of package patch for openSUSE:Factory
checked in at Thu Feb 26 18:17:01 CET 2009.
--------
--- patch/patch.changes 2009-02-03 06:11:18.000000000 +0100
+++ patch/patch.changes 2009-02-26 18:15:25.264963000 +0100
@@ -1,0 +2,9 @@
+Tue Feb 24 12:56:06 CET 2009 - agruen@suse.de
+
+- Include patch headers in reject files so that they form proper
+ patches themselves.
+- Rewrite the unified reject files patch; this is much cleaner
+ now.
+- Add an improved strategy for locating merges.
+
+-------------------------------------------------------------------
@@ -140,2 +149,2 @@
- � Bugfixes
- � patch -D now outputs preprocessor lines without comments, as
+ + Bugfixes
+ + patch -D now outputs preprocessor lines without comments, as
@@ -143 +152 @@
- � File names in context patches may now contain spaces, so long
+ + File names in context patches may now contain spaces, so long
@@ -146,2 +155,2 @@
- � Perforce is now supported
- � Patch lines beginning with "#" are comments and are ignored
+ + Perforce is now supported
+ + Patch lines beginning with "#" are comments and are ignored
calling whatdependson for head-i586
Old:
----
diff3-style-merges-base.diff
diff3-style-merges-include-filenames.diff
diff3-style-merges-other-strategy.diff
diff3-style-merges-overlap.diff
diff3-style-merges-pch_name.diff
diff3-style-merges-rejects.diff
if_else_endif_comments.diff
patch-man-unified-reject.diff
New:
----
diff3-style-merges-simple-merge.diff
explain-pch_char-oddity.diff
fix-timestamp-parsing.diff
format_startcount.diff
patch-headers-in-reject-files.diff
pch_c_function.diff
pch_name.diff
preserve-c_function-in-reject-files.diff
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ patch.spec ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -23,29 +23,29 @@
Group: Productivity/Text/Utilities
AutoReqProv: on
Version: 2.5.9
-Release: 287
+Release: 288
Summary: GNU patch
Source: ftp://prep.ai.mit.edu/pub/gnu/patch/%{name}-%{version}.tar.bz2
Url: ftp://alpha.gnu.org/gnu/diffutils/
Patch: trailing-cr-fix.diff
Patch1: remember-backup-files.diff
-Patch2: unified-reject-files.diff
-Patch3: global-reject-file.diff
-Patch4: if_else_endif_comments.diff
-Patch5: patch-2.5.9-cat_if_device.diff
-Patch6: patch-man-unified-reject.diff
-Patch7: fix-partial-context.diff
-Patch8: diff3-style-merges-tests.diff
-Patch9: diff3-style-merges-refactoring.diff
-Patch10: diff3-style-merges-refactoring-2.diff
-Patch11: diff3-style-merges-base.diff
-Patch12: diff3-style-merges-rejects.diff
-Patch13: diff3-style-merges-pch_name.diff
-Patch14: diff3-style-merges-include-filenames.diff
-Patch15: diff3-style-merges-add-file-labels.diff
-Patch16: diff3-style-merges-overlap.diff
-Patch17: diff3-style-merges-locate-merge.diff
-Patch18: diff3-style-merges-other-strategy.diff
+Patch2: pch_c_function.diff
+Patch3: pch_name.diff
+Patch4: preserve-c_function-in-reject-files.diff
+Patch5: format_startcount.diff
+Patch6: fix-timestamp-parsing.diff
+Patch7: unified-reject-files.diff
+Patch8: patch-headers-in-reject-files.diff
+Patch9: global-reject-file.diff
+Patch10: patch-2.5.9-cat_if_device.diff
+Patch11: fix-partial-context.diff
+Patch12: explain-pch_char-oddity.diff
+Patch13: diff3-style-merges-tests.diff
+Patch14: diff3-style-merges-refactoring.diff
+Patch15: diff3-style-merges-refactoring-2.diff
+Patch16: diff3-style-merges-simple-merge.diff
+Patch17: diff3-style-merges-add-file-labels.diff
+Patch18: diff3-style-merges-locate-merge.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
@@ -66,6 +66,7 @@
%patch1 -p1
%patch2 -p1
%patch3 -p1
+%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
@@ -105,6 +106,12 @@
%doc %{_mandir}/man1/patch.1.gz
%changelog
+* Tue Feb 24 2009 agruen@suse.de
+- Include patch headers in reject files so that they form proper
+ patches themselves.
+- Rewrite the unified reject files patch; this is much cleaner
+ now.
+- Add an improved strategy for locating merges.
* Tue Feb 03 2009 agruen@suse.de
- Implement diff3-style merges (including several fixes and
improvements).
@@ -188,14 +195,14 @@
patch more than once.
* Wed Mar 26 2003 mmj@suse.de
- Update to 2.5.8:
- � Bugfixes
- � patch -D now outputs preprocessor lines without comments, as
+ + Bugfixes
+ + patch -D now outputs preprocessor lines without comments, as
required by POSIX 1003.1-2001
- � File names in context patches may now contain spaces, so long
+ + File names in context patches may now contain spaces, so long
as the context patch headers use a tab to separate the file name
from the time stamp
- � Perforce is now supported
- � Patch lines beginning with "#" are comments and are ignored
+ + Perforce is now supported
+ + Patch lines beginning with "#" are comments and are ignored
* Wed Jan 15 2003 agruen@suse.de
- Fix a bug with hardlinks (see rename-same-file.patch)
* Tue Sep 17 2002 ro@suse.de
++++++ diff3-style-merges-add-file-labels.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -1,29 +1,36 @@
-From: Andreas Gruenbacher
-Subject: diff3-style merges: add file labels
-
-Add a --label=LABEL option for overriding the labels in the diff3-style
-format. The option can be given up to three times for overriding the
-old, new, and output filename.
-
-Signed-off-by: Andreas Gruenbacher
-
---
- patch.c | 19 +++++++++++++++----
- 1 file changed, 15 insertions(+), 4 deletions(-)
+ common.h | 2 ++
+ merge.c | 8 ++++----
+ patch.c | 14 +++++++++++++-
+ 3 files changed, 19 insertions(+), 5 deletions(-)
+Index: b/common.h
+===================================================================
+--- a/common.h
++++ b/common.h
+@@ -310,6 +310,8 @@ XTERN LINENUM last_offset;
+ /* how many input lines have been irretractably output */
+ XTERN LINENUM last_frozen_line;
+
++XTERN const char *file_label[2];
++
+ bool similar (char const *, size_t, char const *, size_t);
+ bool copy_till (struct outstate *, LINENUM);
+
Index: b/patch.c
===================================================================
--- a/patch.c
+++ b/patch.c
-@@ -82,6 +82,7 @@ static void usage (FILE *, int) __attrib
- enum mergetype { SHOW_ALL = 1, SHOW_FUZZ = 2, MERGE_REJECTS = 4 };
- static enum mergetype mergetype;
+@@ -70,6 +70,8 @@ static void usage (FILE *, int) __attrib
+ static void (*abort_hunk) (bool, bool) = abort_hunk_context;
+ static bool merge;
+const char *file_label[2];
++
static bool make_backups;
static bool backup_if_mismatch;
static char const *version_control;
-@@ -538,7 +539,7 @@ reinitialize_almost_everything (void)
+@@ -506,7 +508,7 @@ reinitialize_almost_everything (void)
skip_rest_of_patch = false;
}
@@ -32,25 +39,25 @@
static struct option const longopts[] =
{
{"backup", no_argument, NULL, 'b'},
-@@ -553,6 +554,7 @@ static struct option const longopts[] =
+@@ -521,6 +523,7 @@ static struct option const longopts[] =
{"get", no_argument, NULL, 'g'},
{"input", required_argument, NULL, 'i'},
{"ignore-whitespace", no_argument, NULL, 'l'},
+ {"label", required_argument, NULL, 'L'},
+ {"merge", no_argument, NULL, 'M'},
{"normal", no_argument, NULL, 'n'},
{"forward", no_argument, NULL, 'N'},
- {"output", required_argument, NULL, 'o'},
-@@ -609,6 +611,7 @@ static char const *const option_help[] =
+@@ -577,6 +580,7 @@ static char const *const option_help[] =
"",
" -D NAME --ifdef=NAME Make merged if-then-else output using NAME.",
- " --merge={rejects,fuzz,all} Produce a diff3-style merge.",
+ " -M --merge Produce a diff3-style merge for rejects.",
+" -L LABEL --label=LABEL Use LABEL instead of file name in merge.",
" -E --remove-empty-files Remove output files that are empty after patching.",
"",
" -Z --set-utc Set times of patched files, assuming diff uses UTC (GMT).",
-@@ -747,6 +750,14 @@ get_some_switches (void)
- case 'l':
- canonicalize = true;
+@@ -718,6 +722,14 @@ get_some_switches (void)
+ case 'M':
+ merge = true;
break;
+ case 'L':
+ if (!file_label[0])
@@ -60,11 +67,15 @@
+ else
+ fatal ("too many file label options");
+ break;
- case 'M':
- mergetype |= MERGE_REJECTS;
+ case 'n':
+ diff_type = NORMAL_DIFF;
break;
-@@ -1411,7 +1422,7 @@ static bool merge_hunk (struct outstate
- }
+Index: b/merge.c
+===================================================================
+--- a/merge.c
++++ b/merge.c
+@@ -50,7 +50,7 @@ merge_hunk (struct outstate *outstate)
+ return false;
/* "From" lines in the patch */
- name = pch_name(OLD);
@@ -72,21 +83,23 @@
if (!name)
name = "";
fprintf(fp, outstate->after_newline + "\n<<<<<<<%*s\n",
-@@ -1426,7 +1437,7 @@ static bool merge_hunk (struct outstate
-
- if (fuzz) {
+@@ -84,7 +84,7 @@ merge_hunk (struct outstate *outstate)
+ if (! same_result)
+ {
/* "To" lines in the patch */
- name = pch_name(NEW);
+ name = file_label[NEW] ? file_label[NEW] : pch_name(NEW);
if (!name)
name = "";
fprintf(fp, outstate->after_newline + "\n|||||||%*s\n",
-@@ -1453,7 +1464,7 @@ static bool merge_hunk (struct outstate
-
- /* If the merge result and the new file are the same, label the merge
+@@ -112,8 +112,8 @@ merge_hunk (struct outstate *outstate)
result with the new file's name. */
-- name = fuzz ? NULL : pch_name(NEW);
-+ name = fuzz ? NULL : (file_label[NEW] ? file_label[NEW] : pch_name(NEW));
- if (!name)
- name = "";
- fprintf(fp, outstate->after_newline + "\n>>>>>>>%*s\n",
+ if (same_result)
+ {
+- name = pch_name(NEW);
+- if (!name)
++ name = file_label[NEW] ? file_label[NEW] : pch_name(NEW);
++ if (! name)
+ name = "";
+ }
+ else
++++++ diff3-style-merges-locate-merge.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -1,70 +1,100 @@
---
- patch.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
- 1 file changed, 72 insertions(+), 6 deletions(-)
+ Makefile.in | 3 -
+ bestmatch.h | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ common.h | 11 ++++
+ merge.c | 95 ++++++++++++++++++++++++++++++++++++++++-
+ patch.c | 19 ++++++--
+ 5 files changed, 256 insertions(+), 10 deletions(-)
+Index: b/Makefile.in
+===================================================================
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -85,7 +85,8 @@ HDRS = argmatch.h backupfile.h common.h
+ error.h getopt.h gettext.h \
+ inp.h maketime.h partime.h pch.h \
+ quote.h quotearg.h quotesys.h \
+- unlocked-io.h util.h version.h xalloc.h hash.h
++ unlocked-io.h util.h version.h xalloc.h hash.h \
++ bestmatch.h
+ MISC = AUTHORS COPYING ChangeLog INSTALL Makefile.in NEWS README \
+ aclocal.m4 \
+ config.hin configure configure.ac \
+Index: b/common.h
+===================================================================
+--- a/common.h
++++ b/common.h
+@@ -296,6 +296,14 @@ void *realloc ();
+ #define TTY_DEVICE "/dev/tty"
+ #endif
+
++#ifndef MIN
++# define MIN(a, b) ((a) <= (b) ? (a) : (b))
++#endif
++
++#ifndef MAX
++# define MAX(a, b) ((a) >= (b) ? (a) : (b))
++#endif
++
+ /* Output stream state. */
+ struct outstate
+ {
+@@ -316,4 +324,5 @@ bool similar (char const *, size_t, char
+ bool copy_till (struct outstate *, LINENUM);
+
+ /* Defined in merge.c */
+-bool merge_hunk (struct outstate *);
++LINENUM locate_merge (LINENUM, LINENUM *);
++bool merge_hunk (struct outstate *, LINENUM, LINENUM);
Index: b/patch.c
===================================================================
--- a/patch.c
+++ b/patch.c
-@@ -62,6 +62,8 @@ static FILE *create_output_file (char co
- static LINENUM locate_hunk (LINENUM);
- static bool apply_hunk (struct outstate *, LINENUM);
- static bool common_context(LINENUM, LINENUM, LINENUM);
-+static LINENUM min_mismatches(LINENUM, LINENUM);
-+static LINENUM locate_merge (void);
- static bool merge_hunk (struct outstate *, LINENUM, LINENUM);
- static void merge_ends_here(struct outstate *outstate);
- static bool copy_till (struct outstate *, LINENUM);
-@@ -304,15 +306,11 @@ main (int argc, char **argv)
+@@ -286,13 +286,22 @@ main (int argc, char **argv)
goto skip_hunk;
} else if (!where) {
- if (mergetype & MERGE_REJECTS) {
-- LINENUM guess = pch_first () + last_offset;
--
-- if (merge_hunk(&outstate, guess, -1)) {
-+ if (merge_hunk(&outstate, locate_merge(), -1)) {
+ if (merge) {
+- if (merge_hunk(&outstate)) {
++ LINENUM matched;
++
++ where = locate_merge (maxfuzz, &matched);
++ if (! where)
++ {
++ where = pch_first () + last_offset;
++ matched = 0;
++ }
++
++ if (merge_hunk (&outstate, where, matched))
++ {
merged++;
mismatch = 1;
- } else {
-- /* FIXME: guess harder! */
-+ } else
- goto skip_hunk;
+- /* FIXME: try harder! */
+- goto skip_hunk;
- }
++ }
++ else
++ goto skip_hunk;
} else
goto skip_hunk;
} else {
-@@ -1356,6 +1354,74 @@ static bool common_context(LINENUM where
- memcmp(line, pfetch(new), size) == 0));
- }
+Index: b/merge.c
+===================================================================
+--- a/merge.c
++++ b/merge.c
+@@ -7,8 +7,97 @@
+ static bool context_matches_file (LINENUM, LINENUM);
+ static bool common_context (LINENUM, LINENUM, LINENUM);
-+static LINENUM min_mismatches(LINENUM where, LINENUM lowest)
-+{
-+ register LINENUM ptrn_lines = pch_ptrn_lines();
-+ register LINENUM old, mismatched = 0;
++#define OFFSET LINENUM
++#define EQUAL(x, y) (context_matches_file (x, y))
+
-+ for (old = 1; old <= ptrn_lines; old++, where++) {
-+ size_t size;
-+ const char *line;
-+
-+ line = ifetch (where, false, &size);
-+ if (!size ||
-+ !(canonicalize ?
-+ similar(pfetch(old), pch_line_len(old), line, size) :
-+ (size == pch_line_len(old) &&
-+ memcmp(line, pfetch(old), size) == 0))) {
-+ mismatched++;
-+ if (mismatched >= lowest)
-+ break;
-+ }
-+ }
-+ return mismatched;
-+}
++#include "bestmatch.h"
+
-+static LINENUM locate_merge ()
++LINENUM
++locate_merge (LINENUM fuzz, LINENUM *matched)
+{
-+ register LINENUM first_guess = pch_first () + last_offset;
-+ register LINENUM lowest = input_lines, where = first_guess;
-+ register LINENUM offset;
++ LINENUM first_guess = pch_first () + last_offset;
+ LINENUM pat_lines = pch_ptrn_lines();
+ LINENUM suffix_context = pch_suffix_context ();
+ LINENUM max_where = input_lines - (pat_lines - suffix_context) + 1;
@@ -73,38 +103,235 @@
+ LINENUM max_neg_offset = first_guess - min_where;
+ LINENUM max_offset = (max_pos_offset < max_neg_offset
+ ? max_neg_offset : max_pos_offset);
++ LINENUM prefix_fuzz = MIN (fuzz, pch_prefix_context());
++ LINENUM suffix_fuzz = MIN (fuzz, pch_suffix_context());
++ LINENUM where = 0, max_matched = 0;
++ LINENUM min, max;
++ LINENUM offset;
++
++ /* The minimum number of matched lines and maximum number of changes
++ are mostly guesses. */
++ min = pat_lines - (prefix_fuzz + suffix_fuzz);
++ max = 2 * (prefix_fuzz + suffix_fuzz);
+
+ /* Do not try lines <= 0. */
+ if (first_guess <= max_neg_offset)
-+ max_neg_offset = first_guess - 1;
++ max_neg_offset = first_guess - 1;
+
-+ for (offset = 0; offset <= max_offset; offset++) {
-+ if (offset <= max_pos_offset) {
-+ register LINENUM mismatched;
-+
-+ mismatched = min_mismatches(first_guess - offset, lowest);
-+ if (mismatched < lowest) {
-+ lowest = mismatched;
-+ where = first_guess - offset;
-+ if (lowest == 1)
-+ break;
-+ }
-+ }
-+ if (0 < offset && offset <= max_neg_offset) {
-+ register LINENUM mismatched;
-+
-+ mismatched = min_mismatches(first_guess + offset, lowest);
-+ if (mismatched < lowest) {
-+ lowest = mismatched;
-+ where = first_guess + offset;
-+ if (lowest == 1)
-+ break;
-+ }
-+ }
-+ }
++ for (offset = 0; offset <= max_offset; offset++)
++ {
++ if (offset <= max_pos_offset)
++ {
++ LINENUM guess = first_guess + offset;
++ LINENUM last;
++ LINENUM changes;
++
++ changes = bestmatch(1, pat_lines + 1, guess, input_lines + 1,
++ min, max, &last);
++ if (changes <= max && max_matched < last - guess)
++ {
++ max_matched = last - guess;
++ where = guess;
++ if (changes == 0)
++ break;
++ min = last - guess;
++ max = changes - 1;
++ }
++ }
++ if (0 < offset && offset <= max_neg_offset)
++ {
++ LINENUM guess = first_guess - offset;
++ LINENUM last;
++ LINENUM changes;
++
++ changes = bestmatch(1, pat_lines + 1, guess, input_lines + 1,
++ min, max, &last);
++ if (changes <= max && max_matched < last - guess)
++ {
++ max_matched = last - guess;
++ where = guess;
++ if (changes == 0)
++ break;
++ min = last - guess;
++ max = changes - 1;
++ }
++ }
++ }
++ if (debug & 1)
++ {
++ char numbuf0[LINENUM_LENGTH_BOUND + 1];
++ char numbuf1[LINENUM_LENGTH_BOUND + 1];
++ char numbuf2[LINENUM_LENGTH_BOUND + 1];
++ char numbuf3[LINENUM_LENGTH_BOUND + 1];
++ say ("locating merge: min=%s max=%s where=%s matched=%s\n",
++ format_linenum (numbuf0, min),
++ format_linenum (numbuf1, max),
++ format_linenum (numbuf2, where),
++ format_linenum (numbuf3, max_matched));
++ }
++
++ if (where)
++ *matched = max_matched;
+ return where;
+}
+
- /* A FUZZ value of -1 indicates that the hunk could not be applied. */
+ bool
+-merge_hunk (struct outstate *outstate)
++merge_hunk (struct outstate *outstate, LINENUM where, LINENUM matched)
+ {
+ LINENUM old = 1;
+ LINENUM lastold = pch_ptrn_lines ();
+@@ -22,8 +111,8 @@ merge_hunk (struct outstate *outstate)
+ while (pch_char(new) == '=' || pch_char(new) == '\n')
+ new++;
+
+- merge = pch_first () + last_offset;
+- lastmerge = merge + lastold - 1;
++ merge = where;
++ lastmerge = where + matched - 1;
+ if (! common_context(lastmerge, lastold, lastnew))
+ lastmerge = merge - 1;
- static bool merge_hunk (struct outstate *outstate, LINENUM where, LINENUM fuzz)
+Index: b/bestmatch.h
+===================================================================
+--- /dev/null
++++ b/bestmatch.h
+@@ -0,0 +1,138 @@
++/* Before including this file, you need to define:
++ EQUAL(x, y) A two-argument macro that tests elements
++ at index x and y for equality.
++ OFFSET A signed integer type sufficient to hold the
++ difference between two indices. Usually
++ something like ssize_t. */
++
++/*
++ * Shortest Edit Sequence
++ *
++ * Based on the Greedy LCS/SES Algorithm (Figure 2) in:
++ *
++ * Eugene W. Myers, "An O(ND) Difference Algorithm and Its Variations",
++ * Algorithmica, Vol. 1, No. 1, pp. 251-266, March 1986.
++ * Available: http://dx.doi.org/10.1007/BF01840446
++ * http://xmailserver.org/diff2.pdf
++ *
++ * Returns the number of changes (insertions and deletions) required to get
++ * from a[] to b[]. Returns MAX + 1 if a[] cannot be turned into b[] with
++ * MAX or fewer changes.
++ *
++ * MIN specifies the minimum number of elements in which a[] and b[] must
++ * match. This allows to prevent trivial matches in which a sequence is
++ * completely discarded, or completely made up.
++ *
++ * If PY is not NULL, matches a[] against a prefix of b[], and returns the
++ * number of elements in b[] that were matched in *PY. Otherwise, matches
++ * all elements of b[].
++ *
++ * Note that the divide-and-conquer strategy discussed in section 4b of the
++ * paper is more efficient, but does not allow an open-ended prefix string
++ * search.
++ */
++
++OFFSET
++bestmatch(OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim,
++ OFFSET min, OFFSET max, OFFSET *py)
++{
++ const OFFSET dmin = xoff - ylim; /* Minimum valid diagonal. */
++ const OFFSET dmax = xlim - yoff; /* Maximum valid diagonal. */
++ const OFFSET fmid = xoff - yoff; /* Center diagonal. */
++ OFFSET fmin = fmid;
++ OFFSET fmax = fmid;
++ OFFSET V[2 * max + 3], *fd = V + max + 2 - fmid;
++ OFFSET fmid_plus_2_min, ymax = -1;
++ OFFSET c;
++
++ /*
++ The number of elements that were matched in x and in y can be
++ computed as either (x - x_skipped) or (y - y_skipped), with:
++
++ delta = (x - xoff) - (y - yoff)
++ x_skipped = (c + delta) / 2
++ y_skipped = (c - delta) / 2
++
++ For searching for a minimum number of matching elements, we end up
++ with this check:
++
++ (x - x_skipped) >= min
++ ...
++ x + y - c >= (xoff - yoff) + 2 * min
++ x + y - c >= fmid + 2 * min
++ */
++
++ if (min)
++ {
++ fmid_plus_2_min = fmid + 2 * min;
++ min += yoff;
++ if (min > ylim)
++ return max + 1;
++ }
++ else
++ fmid_plus_2_min = 0; /* disable this check */
++ if (!py)
++ min = ylim;
++
++ /* Handle the exact-match case. */
++ while (xoff < xlim && yoff < ylim && EQUAL (xoff, yoff))
++ {
++ xoff++;
++ yoff++;
++ }
++ if (xoff == xlim && yoff >= min
++ && xoff + yoff >= fmid_plus_2_min)
++ {
++ ymax = yoff;
++ c = 0;
++ }
++ else
++ {
++ fd[fmid] = xoff;
++ for (c = 1; c <= max; c++)
++ {
++ OFFSET d;
++
++ if (fmin > dmin)
++ fd[--fmin - 1] = -1;
++ else
++ ++fmin;
++ if (fmax < dmax)
++ fd[++fmax + 1] = -1;
++ else
++ --fmax;
++ for (d = fmax; d >= fmin; d -= 2)
++ {
++ OFFSET x, y;
++
++ if (fd[d - 1] < fd[d + 1])
++ x = fd[d + 1];
++ else
++ x = fd[d - 1] + 1;
++ for (y = x - d;
++ x < xlim && y < ylim && EQUAL (x, y);
++ x++, y++)
++ continue;
++ fd[d] = x;
++ if (x == xlim && y >= min
++ && x + y - c >= fmid_plus_2_min)
++ {
++ if (ymax < y)
++ ymax = y;
++ if (y == ylim)
++ goto done;
++ }
++ }
++ if (ymax != -1)
++ goto done;
++ }
++ }
++
++ done:
++ if (py)
++ *py = ymax;
++ return c;
++}
++
++#undef OFFSET
++#undef EQUAL
++++++ diff3-style-merges-refactoring-2.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -6,7 +6,7 @@
===================================================================
--- a/patch.c
+++ b/patch.c
-@@ -286,32 +286,30 @@ main (int argc, char **argv)
+@@ -288,32 +288,30 @@ main (int argc, char **argv)
newwhere = pch_newfirst() + last_offset;
if (skip_rest_of_patch) {
goto skip_hunk;
@@ -44,7 +44,7 @@
+ if (!apply_hunk (&outstate, where))
+ goto skip_hunk;
+ }
-+
++
+ if (verbosity == VERBOSE
+ || (verbosity != SILENT && (fuzz || last_offset))) {
+ say ("Hunk #%d succeeded at %s", hunk,
++++++ diff3-style-merges-refactoring.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -1,18 +1,16 @@
---
- patch.c | 36 +++++++++++++++---------------------
- 1 file changed, 15 insertions(+), 21 deletions(-)
+ patch.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
Index: b/patch.c
===================================================================
--- a/patch.c
+++ b/patch.c
-@@ -285,13 +285,7 @@ main (int argc, char **argv)
+@@ -287,11 +287,7 @@ main (int argc, char **argv)
newwhere = pch_newfirst() + last_offset;
if (skip_rest_of_patch) {
-- if (!failed)
-- reject_header(outname);
-- abort_hunk();
+- abort_hunk(!failed, reverse);
- failed++;
- if (verbosity == VERBOSE)
- say ("Hunk #%d ignored at %s.\n", hunk,
@@ -21,13 +19,11 @@
}
else if (!where
|| (where == 1 && pch_says_nonexistent (reverse) == 2
-@@ -301,22 +295,10 @@ main (int argc, char **argv)
+@@ -301,18 +297,10 @@ main (int argc, char **argv)
say ("Patch attempted to create file %s, which already exists.\n",
quotearg (inname));
-- if (!failed)
-- reject_header(outname);
-- abort_hunk();
+- abort_hunk(!failed, reverse);
- failed++;
- if (verbosity != SILENT)
- say ("Hunk #%d FAILED at %s.\n", hunk,
@@ -35,9 +31,7 @@
+ goto skip_hunk;
}
else if (! apply_hunk (&outstate, where)) {
-- if (!failed)
-- reject_header(outname);
-- abort_hunk ();
+- abort_hunk (!failed, reverse);
- failed++;
- if (verbosity != SILENT)
- say ("Hunk #%d FAILED at %s.\n", hunk,
@@ -46,16 +40,14 @@
} else {
if (verbosity == VERBOSE
|| (verbosity != SILENT && (fuzz || last_offset))) {
-@@ -331,6 +313,18 @@ main (int argc, char **argv)
+@@ -327,6 +315,16 @@ main (int argc, char **argv)
say (".\n");
}
}
+ continue;
+
+skip_hunk:
-+ if (!failed)
-+ reject_header(outname);
-+ abort_hunk ();
++ abort_hunk(!failed, reverse);
+ failed++;
+ if (verbosity == VERBOSE ||
+ (!skip_rest_of_patch && verbosity != SILENT))
++++++ diff3-style-merges-simple-merge.diff ++++++
From: Andreas Gruenbacher
Subject: diff3-style merges
Implement a diff3-style merge format: with the --merge option alone,
all hunks that apply without fuzz will be applied as usual, and
hunks that apply within the allowed fuzz limit will be bracketed as:
<<<<<<<
old lines from patch
|||||||
new lines from patch
=======
merge result
>>>>>>>
When the --show-all option is given in addition, hunks that apply without
fuzz will be bracketed as:
<<<<<<<
old lines from patch
=======
merge result
>>>>>>>
Signed-off-by: Andreas Gruenbacher
---
Makefile.in | 6 +-
common.h | 20 +++++++
merge.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
patch.c | 62 +++++++++++++----------
4 files changed, 222 insertions(+), 27 deletions(-)
Index: b/patch.c
===================================================================
--- a/patch.c
+++ b/patch.c
@@ -48,22 +48,12 @@ struct utimbuf
};
#endif
-/* Output stream state. */
-struct outstate
-{
- FILE *ofp;
- bool after_newline;
- bool zero_output;
-};
-
/* procedures */
static FILE *create_output_file (char const *, int);
static LINENUM locate_hunk (LINENUM);
static bool apply_hunk (struct outstate *, LINENUM);
-static bool copy_till (struct outstate *, LINENUM);
static bool patch_match (LINENUM, LINENUM, LINENUM, LINENUM);
-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 (bool, bool);
@@ -79,6 +69,7 @@ static void usage (FILE *, int) __attrib
static void (*abort_hunk) (bool, bool) = abort_hunk_context;
+static bool merge;
static bool make_backups;
static bool backup_if_mismatch;
static char const *version_control;
@@ -88,9 +79,6 @@ static bool remove_empty_files;
/* true if -R was specified on command line. */
static bool reverse_flag_specified;
-/* how many input lines have been irretractably output */
-static LINENUM last_frozen_line;
-
static char const *do_defines; /* symbol to patch using ifdef, ifndef, etc. */
static char const if_defined[] = "\n#ifdef %s\n";
static char const not_defined[] = "\n#ifndef %s\n";
@@ -108,7 +96,6 @@ static char *rejname;
static char const * volatile TMPREJNAME;
static int volatile TMPREJNAME_needs_removal;
-static LINENUM last_offset;
static LINENUM maxfuzz = 2;
static char serrbuf[BUFSIZ];
@@ -119,7 +106,7 @@ int
main (int argc, char **argv)
{
char const *val;
- bool somefailed = false;
+ bool somemerged = false, somefailed = false;
struct outstate outstate;
char numbuf[LINENUM_LENGTH_BOUND + 1];
@@ -186,6 +173,7 @@ main (int argc, char **argv)
reinitialize_almost_everything()
) { /* for each patch in patch file */
int hunk = 0;
+ int merged = 0;
int failed = 0;
bool mismatch = false;
char *outname = outfile ? outfile : inname;
@@ -295,7 +283,16 @@ main (int argc, char **argv)
goto skip_hunk;
} else if (!where) {
- goto skip_hunk;
+ if (merge) {
+ if (merge_hunk(&outstate)) {
+ merged++;
+ mismatch = 1;
+ } else {
+ /* FIXME: try harder! */
+ goto skip_hunk;
+ }
+ } else
+ goto skip_hunk;
} else {
if (!apply_hunk (&outstate, where))
goto skip_hunk;
@@ -303,10 +300,16 @@ main (int argc, char **argv)
if (verbosity == VERBOSE
|| (verbosity != SILENT && (fuzz || last_offset))) {
- say ("Hunk #%d succeeded at %s", hunk,
- format_linenum (numbuf, newwhere));
- if (fuzz)
- say (" with fuzz %s", format_linenum (numbuf, fuzz));
+ if (fuzz > mymaxfuzz) {
+ say ("Hunk #%d merged at %s with conflicts", hunk,
+ format_linenum (numbuf, newwhere));
+ somefailed = true;
+ } else {
+ say ("Hunk #%d succeeded at %s", hunk,
+ format_linenum (numbuf, newwhere));
+ if (fuzz)
+ say (" with fuzz %s", format_linenum (numbuf, fuzz));
+ }
if (last_offset)
say (" (offset %s line%s)",
format_linenum (numbuf, last_offset),
@@ -325,6 +328,9 @@ skip_hunk:
format_linenum (numbuf, newwhere));
}
+ if (merged)
+ somemerged = true;
+
if (!skip_rest_of_patch)
{
if (got_hunk < 0 && using_plan_a)
@@ -374,7 +380,8 @@ skip_hunk:
else
{
if (! outstate.zero_output
- && pch_says_nonexistent (! reverse))
+ && pch_says_nonexistent (! reverse)
+ && !merged)
{
mismatch = true;
if (verbosity != SILENT)
@@ -465,7 +472,7 @@ skip_hunk:
if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
write_fatal ();
cleanup ();
- if (somefailed)
+ if (somemerged || somefailed)
exit (1);
return 0;
}
@@ -499,7 +506,7 @@ reinitialize_almost_everything (void)
skip_rest_of_patch = false;
}
-static char const shortopts[] = "bB:cd:D:eEfF:g:i:lnNo:p:r:RstTuvV:x:Y:z:Z";
+static char const shortopts[] = "bB:cd:D:eEfF:g:i:lMnNo:p:r:RstTuvV:x:Y:z:Z";
static struct option const longopts[] =
{
{"backup", no_argument, NULL, 'b'},
@@ -514,6 +521,7 @@ static struct option const longopts[] =
{"get", no_argument, NULL, 'g'},
{"input", required_argument, NULL, 'i'},
{"ignore-whitespace", no_argument, NULL, 'l'},
+ {"merge", no_argument, NULL, 'M'},
{"normal", no_argument, NULL, 'n'},
{"forward", no_argument, NULL, 'N'},
{"output", required_argument, NULL, 'o'},
@@ -568,6 +576,7 @@ static char const *const option_help[] =
" -r FILE --reject-file=FILE Output rejects to FILE.",
"",
" -D NAME --ifdef=NAME Make merged if-then-else output using NAME.",
+" -M --merge Produce a diff3-style merge for rejects.",
" -E --remove-empty-files Remove output files that are empty after patching.",
"",
" -Z --set-utc Set times of patched files, assuming diff uses UTC (GMT).",
@@ -706,6 +715,9 @@ get_some_switches (void)
case 'l':
canonicalize = true;
break;
+ case 'M':
+ merge = true;
+ break;
case 'n':
diff_type = NORMAL_DIFF;
break;
@@ -1289,7 +1301,7 @@ init_reject (void)
/* Copy input file to output, up to wherever hunk is to be applied. */
-static bool
+bool
copy_till (register struct outstate *outstate, register LINENUM lastline)
{
register LINENUM R_last_frozen_line = last_frozen_line;
@@ -1375,7 +1387,7 @@ patch_match (LINENUM base, LINENUM offse
/* Do two lines match with canonicalized white space? */
-static bool
+bool
similar (register char const *a, register size_t alen,
register char const *b, register size_t blen)
{
Index: b/Makefile.in
===================================================================
--- a/Makefile.in
+++ b/Makefile.in
@@ -70,7 +70,8 @@ SRCS = $(LIBSRCS) \
maketime.c partime.c \
patch.c pch.c \
quote.c quotearg.c quotesys.c \
- util.c version.c xmalloc.c
+ util.c version.c xmalloc.c \
+ merge.c
OBJS = $(LIBOBJS) \
addext.$(OBJEXT) argmatch.$(OBJEXT) backupfile.$(OBJEXT) \
basename.$(OBJEXT) dirname.$(OBJEXT) \
@@ -78,7 +79,8 @@ OBJS = $(LIBOBJS) \
maketime.$(OBJEXT) partime.$(OBJEXT) \
patch.$(OBJEXT) pch.$(OBJEXT) \
quote.$(OBJEXT) quotearg.$(OBJEXT) quotesys.$(OBJEXT) \
- util.$(OBJEXT) version.$(OBJEXT) xmalloc.$(OBJEXT) hash.$(OBJEXT)
+ util.$(OBJEXT) version.$(OBJEXT) xmalloc.$(OBJEXT) hash.$(OBJEXT) \
+ merge.$(OBJEXT)
HDRS = argmatch.h backupfile.h common.h dirname.h \
error.h getopt.h gettext.h \
inp.h maketime.h partime.h pch.h \
Index: b/common.h
===================================================================
--- a/common.h
+++ b/common.h
@@ -295,3 +295,23 @@ void *realloc ();
#ifndef TTY_DEVICE
#define TTY_DEVICE "/dev/tty"
#endif
+
+/* Output stream state. */
+struct outstate
+{
+ FILE *ofp;
+ bool after_newline;
+ bool zero_output;
+};
+
+/* offset at which the previous hunk matched */
+XTERN LINENUM last_offset;
+
+/* how many input lines have been irretractably output */
+XTERN LINENUM last_frozen_line;
+
+bool similar (char const *, size_t, char const *, size_t);
+bool copy_till (struct outstate *, LINENUM);
+
+/* Defined in merge.c */
+bool merge_hunk (struct outstate *);
Index: b/merge.c
===================================================================
--- /dev/null
+++ b/merge.c
@@ -0,0 +1,161 @@
+#define XTERN extern
+#include
+#include
+#include
+#include
+
+static bool context_matches_file (LINENUM, LINENUM);
+static bool common_context (LINENUM, LINENUM, LINENUM);
+
+bool
+merge_hunk (struct outstate *outstate)
+{
+ LINENUM old = 1;
+ LINENUM lastold = pch_ptrn_lines ();
+ LINENUM new = lastold + 1;
+ LINENUM lastnew = pch_end ();
+ LINENUM merge, lastmerge;
+ FILE *fp = outstate->ofp;
+ bool same_result, succeeded = true;
+ const char *name;
+
+ while (pch_char(new) == '=' || pch_char(new) == '\n')
+ new++;
+
+ merge = pch_first () + last_offset;
+ lastmerge = merge + lastold - 1;
+ if (! common_context(lastmerge, lastold, lastnew))
+ lastmerge = merge - 1;
+
+ /* Hide common prefix context */
+ while (old <= lastold && new <= lastnew && merge <= lastmerge &&
+ common_context(merge, old, new))
+ {
+ old++;
+ new++;
+ merge++;
+ }
+
+ /* Hide common suffix context */
+ while (old <= lastold && new <= lastnew && merge <= lastmerge &&
+ common_context(lastmerge, lastold, lastnew))
+ {
+ lastold--;
+ lastnew--;
+ lastmerge--;
+ }
+
+ assert (outstate->after_newline);
+ if (! copy_till(outstate, merge - 1))
+ return false;
+
+ /* "From" lines in the patch */
+ name = pch_name(OLD);
+ if (!name)
+ name = "";
+ fprintf(fp, outstate->after_newline + "\n<<<<<<<%*s\n",
+ strlen(name) ? strlen(name) + 1 : 0, name);
+ if (ferror (fp))
+ write_fatal ();
+ outstate->after_newline = true;
+ while (old <= lastold)
+ {
+ outstate->after_newline = pch_write_line(old, fp);
+ old++;
+ }
+
+ same_result = (lastmerge - merge == lastnew - new);
+ if (same_result)
+ {
+ LINENUM n = new, m = merge;
+
+ while (n <= lastnew)
+ {
+ if (! context_matches_file (n, m))
+ {
+ same_result = false;
+ break;
+ }
+ n++;
+ m++;
+ }
+ }
+
+ if (! same_result)
+ {
+ /* "To" lines in the patch */
+ name = pch_name(NEW);
+ if (!name)
+ name = "";
+ fprintf(fp, outstate->after_newline + "\n|||||||%*s\n",
+ strlen(name) ? strlen(name) + 1 : 0, name);
+ if (ferror (fp))
+ write_fatal ();
+ outstate->after_newline = true;
+ while (new <= lastnew)
+ {
+ outstate->after_newline = pch_write_line(new, fp);
+ new++;
+ }
+ }
+
+ /* Merge result */
+ fprintf(fp, outstate->after_newline + "\n=======\n");
+ if (ferror (fp))
+ write_fatal ();
+ outstate->after_newline = true;
+
+ if (! copy_till(outstate, lastmerge))
+ succeeded = false;
+
+ /* If the merge result and the new file are the same, label the merge
+ result with the new file's name. */
+ if (same_result)
+ {
+ name = pch_name(NEW);
+ if (!name)
+ name = "";
+ }
+ else
+ name = "";
+ fprintf(fp, outstate->after_newline + "\n>>>>>>>%*s\n",
+ strlen(name) ? strlen(name) + 1 : 0, name);
+ if (ferror (fp))
+ write_fatal ();
+ outstate->after_newline = true;
+ outstate->zero_output = false;
+ return succeeded;
+}
+
+static bool
+context_matches_file (LINENUM old, LINENUM where)
+{
+ size_t size;
+ const char *line;
+
+ line = ifetch (where, false, &size);
+ return size &&
+ (canonicalize ?
+ similar(pfetch(old), pch_line_len(old), line, size) :
+ (size == pch_line_len(old) &&
+ memcmp(line, pfetch(old), size) == 0));
+}
+
+static bool
+common_context (LINENUM where, LINENUM old, LINENUM new)
+{
+ size_t size;
+ const char *line;
+
+ if (pch_char(old) != ' ' || pch_char(new) != ' ')
+ return false;
+
+ line = ifetch (where, false, &size);
+ return size &&
+ (canonicalize ?
+ (similar(pfetch(old), pch_line_len(old), line, size) &&
+ similar(pfetch(new), pch_line_len(new), line, size)) :
+ (size == pch_line_len(old) && size == pch_line_len(new) &&
+ memcmp(line, pfetch(old), size) == 0 &&
+ memcmp(line, pfetch(new), size) == 0));
+}
++++++ diff3-style-merges-tests.diff ++++++
++++ 1329 lines (skipped)
++++ between patch/diff3-style-merges-tests.diff
++++ and patch/diff3-style-merges-tests.diff
++++++ explain-pch_char-oddity.diff ++++++
---
pch.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: b/pch.c
===================================================================
--- a/pch.c
+++ b/pch.c
@@ -1877,7 +1877,9 @@ pch_line_len (LINENUM line)
return p_len[line];
}
-/* Return the control character (+, -, *, !, etc) for a patch line. */
+/* Return the control character (+, -, *, !, etc) for a patch line. A '\n'
+ indicates an empty line in a hunk that isn't part of the old or new
+ file's contents -- the context format allows that. */
char
pch_char (LINENUM line)
++++++ fix-partial-context.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -13,6 +13,8 @@
patch.c | 43 ++++---------------------------------------
2 files changed, 11 insertions(+), 39 deletions(-)
+Index: b/ChangeLog
+===================================================================
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
@@ -26,9 +28,11 @@
2003-05-20 Paul Eggert
* NEWS, configure.ac (AC_INIT): Version 2.5.9 released.
+Index: b/patch.c
+===================================================================
--- a/patch.c
+++ b/patch.c
-@@ -849,10 +849,10 @@ locate_hunk (LINENUM fuzz)
+@@ -880,10 +880,10 @@ locate_hunk (LINENUM fuzz)
LINENUM pat_lines = pch_ptrn_lines();
LINENUM prefix_context = pch_prefix_context ();
LINENUM suffix_context = pch_suffix_context ();
@@ -43,7 +47,7 @@
LINENUM max_where = input_lines - (pat_lines - suffix_fuzz) + 1;
LINENUM min_where = last_frozen_line + 1 - (prefix_context - prefix_fuzz);
LINENUM max_pos_offset = max_where - first_guess;
-@@ -867,41 +867,6 @@ locate_hunk (LINENUM fuzz)
+@@ -898,41 +898,6 @@ locate_hunk (LINENUM fuzz)
if (first_guess <= max_neg_offset)
max_neg_offset = first_guess - 1;
++++++ fix-timestamp-parsing.diff ++++++
* str2time() will happily parse "\n" and similar; the result will be
undistinguishable from a valid timestamp. Avoid this by skipping
whitespace before and checking if anything remains first.
* Always parse timestamps in patch headers relative to the local timezone
or UTC so that pch_timestamp() will always contain reasonable values
if a timestamp is present: we may need the timestamps later.
* Change the bizarre logic which checks whether a timestamp is close to
the epoch by checking for exactly that. The result is the same, and we
won't have to parse the timestamp again.
---
util.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
Index: b/util.c
===================================================================
--- a/util.c
+++ b/util.c
@@ -996,25 +996,23 @@ fetchname (char *at, int strip_leading,
if (*u != '\t' && strchr (u + 1, '\t'))
continue;
- if (set_time | set_utc)
- stamp = str2time (&u, initial_time,
- set_utc ? 0L : TM_LOCAL_ZONE);
- else
- {
+ while (ISSPACE((unsigned char) *u))
+ u++;
+ if (*u) {
+ stamp = str2time (&u, initial_time,
+ set_utc ? 0L : TM_LOCAL_ZONE);
+
/* The head says the file is nonexistent if the timestamp
is the epoch; but the listed time is local time, not UTC,
and POSIX.1 allows local time offset anywhere in the range
- -25:00 < offset < +26:00. Match any time in that
- range by assuming local time is -25:00 and then matching
- any ``local'' time T in the range 0 < T < 25+26 hours. */
- stamp = str2time (&u, initial_time, -25L * 60 * 60);
- if (0 < stamp && stamp < (25 + 26) * 60L * 60)
+ -25:00 < offset < +26:00. Match any time in that range. */
+ if (!(set_time || set_utc)
+ && 25 * 60L * 60 < stamp && stamp < 26 * 60L * 60)
stamp = 0;
- }
-
- if (*u && ! ISSPACE ((unsigned char) *u))
- stamp = (time_t) -1;
+ if (*u && ! ISSPACE ((unsigned char) *u))
+ stamp = (time_t) -1;
+ }
*t = '\0';
break;
}
++++++ format_startcount.diff ++++++
---
util.c | 30 +++++++++++++++++++++++++++---
util.h | 2 ++
2 files changed, 29 insertions(+), 3 deletions(-)
Index: b/util.c
===================================================================
--- a/util.c
+++ b/util.c
@@ -466,10 +466,9 @@ remove_prefix (char *p, size_t prefixlen
continue;
}
-char *
-format_linenum (char numbuf[LINENUM_LENGTH_BOUND + 1], LINENUM n)
+static char *
+__format_linenum (char *p, LINENUM n)
{
- char *p = numbuf + LINENUM_LENGTH_BOUND;
*p = '\0';
if (n < 0)
@@ -490,6 +489,31 @@ format_linenum (char numbuf[LINENUM_LENG
return p;
}
+char *
+format_linenum (char numbuf[LINENUM_LENGTH_BOUND + 1], LINENUM n)
+{
+ return __format_linenum(numbuf + LINENUM_LENGTH_BOUND, n);
+}
+
+char *
+format_startcount (char rangebuf[LINERANGE_LENGTH_BOUND + 1],
+ LINENUM first, LINENUM lines)
+{
+ char *p = rangebuf + LINERANGE_LENGTH_BOUND;
+
+ if (lines == 1)
+ rangebuf = __format_linenum (p, first);
+ else
+ {
+ if (lines == 0 && first == 1)
+ first = 0; /* what diff produces ... */
+ p = __format_linenum(p, lines);
+ rangebuf = __format_linenum(--p, first);
+ *p = ',';
+ }
+ return rangebuf;
+}
+
#if !HAVE_VPRINTF
#define vfprintf my_vfprintf
static int
Index: b/util.h
===================================================================
--- a/util.h
+++ b/util.h
@@ -25,6 +25,7 @@
/* An upper bound on the print length of a signed decimal line number.
Add one for the sign. */
#define LINENUM_LENGTH_BOUND (sizeof (LINENUM) * CHAR_BIT / 3 + 1)
+#define LINERANGE_LENGTH_BOUND (LINENUM_LENGTH_BOUND * 2 + 1)
XTERN enum backup_type backup_type;
@@ -45,6 +46,7 @@ bool version_get (char const *, char con
int create_file (char const *, int, mode_t);
int systemic (char const *);
char *format_linenum (char[LINENUM_LENGTH_BOUND + 1], LINENUM);
+char *format_startcount (char[LINERANGE_LENGTH_BOUND + 1], LINENUM, LINENUM);
void Fseek (FILE *, file_offset, int);
void copy_file (char const *, char const *, int, mode_t);
void exit_with_signal (int) __attribute__ ((noreturn));
++++++ global-reject-file.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -1,44 +1,21 @@
-Index: patch-2.5.9/patch.man
+---
+ patch.c | 33 ++++++++++++++++++++++++++++-----
+ patch.man | 9 +++++++++
+ 2 files changed, 37 insertions(+), 5 deletions(-)
+
+Index: b/patch.c
===================================================================
---- patch-2.5.9.orig/patch.man
-+++ patch-2.5.9/patch.man
-@@ -520,6 +520,15 @@ file.
- \fB\*=reject\-unified\fP
- Produce unified reject files. The default is to produce context type reject files.
- .TP
-+.BI \*=global\-reject\-file= rejectfile
-+Put all rejects into
-+.I rejectfile
-+instead of creating separate reject files for all files that have rejects. The
-+.I rejectfile
-+will contain headers that identify which file each reject refers to. Note that
-+the global reject file is created even if \-\-dry\-run is specified (while
-+non-global reject files will only be created without \-\-dry\-run).
-+.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: patch-2.5.9/patch.c
-===================================================================
---- patch-2.5.9.orig/patch.c
-+++ patch-2.5.9/patch.c
-@@ -67,6 +67,7 @@ static bool similar (char const *, size_
- static bool spew_output (struct outstate *);
- static char const *make_temp (char);
- static int numeric_string (char const *, bool, char const *);
-+static void reject_header (const char *filename);
- static void abort_hunk (void);
- static void cleanup (void);
- static void get_some_switches (void);
-@@ -98,6 +99,7 @@ static int Argc;
+--- a/patch.c
++++ b/patch.c
+@@ -101,6 +101,7 @@ static int Argc;
static char * const *Argv;
static FILE *rejfp; /* reject file pointer */
-+static char *global_reject;
++char *global_reject;
static char const *patchname;
static char *rejname;
-@@ -172,6 +174,10 @@ main (int argc, char **argv)
+@@ -175,6 +176,10 @@ main (int argc, char **argv)
/* Make sure we clean up in case of disaster. */
set_signals (false);
@@ -49,7 +26,7 @@
for (
open_patch_file (patchname);
there_is_another_patch();
-@@ -208,8 +214,9 @@ main (int argc, char **argv)
+@@ -211,8 +216,9 @@ main (int argc, char **argv)
init_output (TMPOUTNAME, exclusive, &outstate);
}
@@ -61,34 +38,7 @@
/* find out where all the lines are */
if (!skip_rest_of_patch)
-@@ -278,6 +285,8 @@ main (int argc, char **argv)
-
- newwhere = pch_newfirst() + last_offset;
- if (skip_rest_of_patch) {
-+ if (!failed)
-+ reject_header(outname);
- abort_hunk();
- failed++;
- if (verbosity == VERBOSE)
-@@ -292,6 +301,8 @@ main (int argc, char **argv)
- say ("Patch attempted to create file %s, which already exists.\n",
- quotearg (inname));
-
-+ if (!failed)
-+ reject_header(outname);
- abort_hunk();
- failed++;
- if (verbosity != SILENT)
-@@ -299,6 +310,8 @@ main (int argc, char **argv)
- format_linenum (numbuf, newwhere));
- }
- else if (! apply_hunk (&outstate, where)) {
-+ if (!failed)
-+ reject_header(outname);
- abort_hunk ();
- failed++;
- if (verbosity != SILENT)
-@@ -332,7 +345,8 @@ main (int argc, char **argv)
+@@ -335,7 +341,8 @@ main (int argc, char **argv)
fclose (outstate.ofp);
outstate.ofp = 0;
}
@@ -98,7 +48,7 @@
continue;
}
-@@ -412,13 +426,13 @@ main (int argc, char **argv)
+@@ -415,13 +422,13 @@ main (int argc, char **argv)
}
}
if (diff_type != ED_DIFF) {
@@ -114,7 +64,7 @@
char *rej = rejname;
if (!rejname) {
rej = xmalloc (strlen (outname) + 5);
-@@ -445,6 +459,20 @@ main (int argc, char **argv)
+@@ -448,6 +455,17 @@ main (int argc, char **argv)
}
set_signals (true);
}
@@ -124,18 +74,15 @@
+ write_fatal ();
+ if (somefailed)
+ {
-+ say (" -- saving rejects to file %s\n", quotearg (global_reject));
-+ /*if (! dry_run)
-+ {*/
-+ move_file (TMPREJNAME, &TMPREJNAME_needs_removal,
-+ global_reject, 0644, false);
-+ /*}*/
++ say (" -- saving rejects to file %s\n", quotearg (global_reject));
++ move_file (TMPREJNAME, &TMPREJNAME_needs_removal,
++ global_reject, 0644, false);
+ }
+ }
if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
write_fatal ();
cleanup ();
-@@ -523,6 +551,7 @@ static struct option const longopts[] =
+@@ -526,6 +544,7 @@ static struct option const longopts[] =
{"posix", no_argument, NULL, CHAR_MAX + 7},
{"quoting-style", required_argument, NULL, CHAR_MAX + 8},
{"unified-reject-files", no_argument, NULL, CHAR_MAX + 9},
@@ -143,7 +90,7 @@
{NULL, no_argument, NULL, 0}
};
-@@ -582,6 +611,7 @@ static char const *const option_help[] =
+@@ -585,6 +604,7 @@ static char const *const option_help[] =
" --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.",
@@ -151,9 +98,9 @@
"",
" -d DIR --directory=DIR Change the working directory to DIR first.",
#if HAVE_SETMODE_DOS
-@@ -784,6 +814,9 @@ get_some_switches (void)
+@@ -787,6 +807,9 @@ get_some_switches (void)
case CHAR_MAX + 9:
- unified_reject_files = true;
+ abort_hunk = abort_hunk_unified;
break;
+ case CHAR_MAX + 10:
+ global_reject = savestr (optarg);
@@ -161,41 +108,23 @@
default:
usage (stderr, 2);
}
-@@ -933,6 +966,37 @@ locate_hunk (LINENUM fuzz)
- }
-
- static char *
-+format_timestamp (char timebuf[37], bool which)
-+{
-+ time_t ts = pch_timestamp(which);
-+ if (ts != -1)
-+ {
-+ struct tm *tm = localtime(&ts);
-+ strftime(timebuf, 37, "\t%Y-%m-%d %H:%M:%S.000000000 %z", tm);
-+ }
-+ else
-+ timebuf[0] = 0;
-+ return timebuf;
-+}
-+
-+/* Write a header in a reject file that combines multiple hunks. */
-+static void
-+reject_header (const char *outname)
-+{
-+ char timebuf0[37], timebuf1[37];
-+ if (!global_reject)
-+ return;
-+ if (diff_type == UNI_DIFF)
-+ fprintf(rejfp, "--- %s.orig%s\n+++ %s%s\n",
-+ outname, format_timestamp(timebuf0, reverse),
-+ outname, format_timestamp(timebuf1, !reverse));
-+ else
-+ fprintf(rejfp, "*** %s.orig%s\n--- %s%s\n",
-+ outname, format_timestamp(timebuf0, reverse),
-+ outname, format_timestamp(timebuf1, !reverse));
-+}
-+
-+static char *
- format_linerange (char rangebuf[LINENUM_LENGTH_BOUND*2 + 2],
- LINENUM first, LINENUM lines)
- {
+Index: b/patch.man
+===================================================================
+--- a/patch.man
++++ b/patch.man
+@@ -520,6 +520,15 @@ file.
+ \fB\*=unified\-reject\-files\fP
+ Produce unified reject files. The default is to produce context type reject files.
+ .TP
++.BI \*=global\-reject\-file= rejectfile
++Put all rejects into
++.I rejectfile
++instead of creating separate reject files for all files that have rejects. The
++.I rejectfile
++will contain headers that identify which file each reject refers to. Note that
++the global reject file is created even if \-\-dry\-run is specified (while
++non-global reject files will only be created without \-\-dry\-run).
++.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
++++++ patch-2.5.9-cat_if_device.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -1,8 +1,14 @@
-Index: patch-2.5.9/patch.c
+---
+ patch.c | 2 +-
+ util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ util.h | 1 +
+ 3 files changed, 52 insertions(+), 1 deletion(-)
+
+Index: b/patch.c
===================================================================
---- patch-2.5.9.orig/patch.c
-+++ patch-2.5.9/patch.c
-@@ -444,7 +444,7 @@ main (int argc, char **argv)
+--- a/patch.c
++++ b/patch.c
+@@ -440,7 +440,7 @@ main (int argc, char **argv)
{
move_file (TMPREJNAME, &TMPREJNAME_needs_removal,
rej, instat.st_mode, false);
@@ -11,10 +17,10 @@
&& (chmod (rej, (instat.st_mode
& ~(S_IXUSR|S_IXGRP|S_IXOTH)))
!= 0))
-Index: patch-2.5.9/util.c
+Index: b/util.c
===================================================================
---- patch-2.5.9.orig/util.c
-+++ patch-2.5.9/util.c
+--- a/util.c
++++ b/util.c
@@ -65,6 +65,49 @@ static bool fid_search (const char *, co
FROM_NEEDS_REMOVAL must be nonnull if FROM is nonnull.
Back up TO if BACKUP is true. */
@@ -79,11 +85,11 @@
if (errno == EXDEV)
{
if (! backup)
-Index: patch-2.5.9/util.h
+Index: b/util.h
===================================================================
---- patch-2.5.9.orig/util.h
-+++ patch-2.5.9/util.h
-@@ -57,3 +57,4 @@ void remove_prefix (char *, size_t);
+--- a/util.h
++++ b/util.h
+@@ -59,3 +59,4 @@ void remove_prefix (char *, size_t);
void removedirs (char *);
void set_signals (bool);
void write_fatal (void) __attribute__ ((noreturn));
++++++ patch-headers-in-reject-files.diff ++++++
---
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
++++++ pch_c_function.diff ++++++
FIXME: free()
---
pch.c | 32 +++++++++++++++++++++++++++++++-
pch.h | 1 +
2 files changed, 32 insertions(+), 1 deletion(-)
Index: b/pch.c
===================================================================
--- a/pch.c
+++ b/pch.c
@@ -68,6 +68,7 @@ static LINENUM p_sline; /* and the lin
static LINENUM p_hunk_beg; /* line number of current hunk */
static LINENUM p_efake = -1; /* end of faked up lines--don't free */
static LINENUM p_bfake = -1; /* beg of faked up lines */
+static char *p_c_function; /* the C function a hunk is in */
enum nametype { OLD, NEW, INDEX, NONE };
@@ -888,6 +889,19 @@ another_hunk (enum diff difftype, bool r
next_intuit_at(line_beginning,p_input_line);
return chars_read == (size_t) -1 ? -1 : 0;
}
+ s = buf;
+ while (*s == '*')
+ s++;
+ if (*s == ' ')
+ {
+ p_c_function = s;
+ while (*s != '\n')
+ s++;
+ *s = '\0';
+ p_c_function = savestr (p_c_function);
+ }
+ else
+ p_c_function = NULL;
p_hunk_beg = p_input_line + 1;
while (p_end < p_max) {
chars_read = get_line ();
@@ -1277,8 +1291,18 @@ another_hunk (enum diff difftype, bool r
else
p_repl_lines = 1;
if (*s == ' ') s++;
- if (*s != '@')
+ if (*s++ != '@')
malformed ();
+ if (*s++ == '@' && *s == ' ' && *s != '\0')
+ {
+ p_c_function = s;
+ while (*s != '\n')
+ s++;
+ *s = '\0';
+ p_c_function = savestr (p_c_function);
+ }
+ else
+ p_c_function = NULL;
if (!p_ptrn_lines)
p_first++; /* do append rather than insert */
if (!p_repl_lines)
@@ -1884,6 +1908,12 @@ pch_hunk_beg (void)
return p_hunk_beg;
}
+char const *
+pch_c_function (void)
+{
+ return p_c_function;
+}
+
/* Is the newline-terminated line a valid `ed' command for patch
input? If so, return the command character; if not, return 0.
This accepts accepts just a subset of the valid commands, but it's
Index: b/pch.h
===================================================================
--- a/pch.h
+++ b/pch.h
@@ -25,6 +25,7 @@
LINENUM pch_end (void);
LINENUM pch_first (void);
LINENUM pch_hunk_beg (void);
+char const *pch_c_function (void);
LINENUM pch_newfirst (void);
LINENUM pch_prefix_context (void);
LINENUM pch_ptrn_lines (void);
++++++ pch_name.diff ++++++
From: Andreas Gruenbacher
Subject: diff3-style merges: pch_name()
Make a pch_name() function available for accessing the old and the new
filename in the patch header.
Signed-off-by: Andreas Gruenbacher
---
pch.c | 88 ++++++++++++++++++++++++++++++++++--------------------------------
pch.h | 3 ++
2 files changed, 49 insertions(+), 42 deletions(-)
Index: b/pch.c
===================================================================
--- a/pch.c
+++ b/pch.c
@@ -43,6 +43,7 @@ static int p_says_nonexistent[2]; /* [0]
1 for existent and probably (but not necessarily) empty,
2 for nonexistent */
static int p_rfc934_nesting; /* RFC 934 nesting level */
+static char *p_name[3]; /* filenames in patch headers */
static time_t p_timestamp[2]; /* timestamps in patch headers */
static off_t p_filesize; /* size of the patch file */
static LINENUM p_first; /* 1st line number */
@@ -70,8 +71,6 @@ static LINENUM p_efake = -1; /* end of
static LINENUM p_bfake = -1; /* beg of faked up lines */
static char *p_c_function; /* the C function a hunk is in */
-enum nametype { OLD, NEW, INDEX, NONE };
-
static char *scan_linenum (char *, LINENUM *);
static enum diff intuit_diff_type (void);
static enum nametype best_name (char * const *, int const *);
@@ -300,13 +299,17 @@ intuit_diff_type (void)
register bool this_is_a_command = false;
register bool stars_this_line = false;
enum nametype i;
- char *name[3];
struct stat st[3];
int stat_errno[3];
int version_controlled[3];
register enum diff retval;
- name[OLD] = name[NEW] = name[INDEX] = 0;
+ for (i = OLD; i <= INDEX; i++)
+ if (p_name[i]) {
+ free (p_name[i]);
+ p_name[i] = 0;
+ }
+
version_controlled[OLD] = -1;
version_controlled[NEW] = -1;
version_controlled[INDEX] = -1;
@@ -365,16 +368,16 @@ intuit_diff_type (void)
p_strip_trailing_cr = strip_trailing_cr;
}
if (!stars_last_line && strnEQ(s, "*** ", 4))
- name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
+ p_name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
else if (strnEQ(s, "+++ ", 4))
{
/* Swap with NEW below. */
- name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
+ p_name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]);
p_strip_trailing_cr = strip_trailing_cr;
}
else if (strnEQ(s, "Index:", 6))
{
- name[INDEX] = fetchname (s+6, strippath, (time_t *) 0);
+ p_name[INDEX] = fetchname (s+6, strippath, (time_t *) 0);
p_strip_trailing_cr = strip_trailing_cr;
}
else if (strnEQ(s, "Prereq:", 7)) {
@@ -410,7 +413,7 @@ intuit_diff_type (void)
if (strnEQ(t, "--- ", 4))
{
time_t timestamp = (time_t) -1;
- name[NEW] = fetchname (t+4, strippath, ×tamp);
+ p_name[NEW] = fetchname (t+4, strippath, ×tamp);
if (timestamp != (time_t) -1)
{
p_timestamp[NEW] = timestamp;
@@ -430,13 +433,13 @@ intuit_diff_type (void)
if ((diff_type == NO_DIFF || diff_type == UNI_DIFF)
&& strnEQ(s, "@@ -", 4)) {
- /* `name' and `p_timestamp' are backwards; swap them. */
+ /* `p_name' and `p_timestamp' are backwards; swap them. */
time_t ti = p_timestamp[OLD];
p_timestamp[OLD] = p_timestamp[NEW];
p_timestamp[NEW] = ti;
- t = name[OLD];
- name[OLD] = name[NEW];
- name[NEW] = t;
+ t = p_name[OLD];
+ p_name[OLD] = p_name[NEW];
+ p_name[NEW] = t;
s += 4;
if (s[0] == '0' && !ISDIGIT (s[1]))
@@ -451,9 +454,9 @@ intuit_diff_type (void)
p_start = this_line;
p_sline = p_input_line;
retval = UNI_DIFF;
- if (! ((name[OLD] || ! p_timestamp[OLD])
- && (name[NEW] || ! p_timestamp[NEW]))
- && ! name[INDEX])
+ if (! ((p_name[OLD] || ! p_timestamp[OLD])
+ && (p_name[NEW] || ! p_timestamp[NEW]))
+ && ! p_name[INDEX])
{
char numbuf[LINENUM_LENGTH_BOUND + 1];
say ("missing header for unified diff at line %s of patch\n",
@@ -492,9 +495,9 @@ intuit_diff_type (void)
next_intuit_at (saved_p_base, saved_p_bline);
}
- if (! ((name[OLD] || ! p_timestamp[OLD])
- && (name[NEW] || ! p_timestamp[NEW]))
- && ! name[INDEX])
+ if (! ((p_name[OLD] || ! p_timestamp[OLD])
+ && (p_name[NEW] || ! p_timestamp[NEW]))
+ && ! p_name[INDEX])
{
char numbuf[LINENUM_LENGTH_BOUND + 1];
say ("missing header for context diff at line %s of patch\n",
@@ -543,23 +546,23 @@ intuit_diff_type (void)
{
enum nametype i0 = NONE;
- if (! posixly_correct && (name[OLD] || name[NEW]) && name[INDEX])
+ if (! posixly_correct && (p_name[OLD] || p_name[NEW]) && p_name[INDEX])
{
- free (name[INDEX]);
- name[INDEX] = 0;
+ free (p_name[INDEX]);
+ p_name[INDEX] = 0;
}
for (i = OLD; i <= INDEX; i++)
- if (name[i])
+ if (p_name[i])
{
- if (i0 != NONE && strcmp (name[i0], name[i]) == 0)
+ if (i0 != NONE && strcmp (p_name[i0], p_name[i]) == 0)
{
/* It's the same name as before; reuse stat results. */
stat_errno[i] = stat_errno[i0];
if (! stat_errno[i])
st[i] = st[i0];
}
- else if (stat (name[i], &st[i]) != 0)
+ else if (stat (p_name[i], &st[i]) != 0)
stat_errno[i] = errno;
else
{
@@ -574,30 +577,30 @@ intuit_diff_type (void)
{
bool is_empty;
- i = best_name (name, stat_errno);
+ i = best_name (p_name, stat_errno);
if (i == NONE && patch_get)
{
enum nametype nope = NONE;
for (i = OLD; i <= INDEX; i++)
- if (name[i])
+ if (p_name[i])
{
char const *cs;
char *getbuf;
char *diffbuf;
bool readonly = (outfile
- && strcmp (outfile, name[i]) != 0);
+ && strcmp (outfile, p_name[i]) != 0);
- if (nope == NONE || strcmp (name[nope], name[i]) != 0)
+ if (nope == NONE || strcmp (p_name[nope], p_name[i]) != 0)
{
cs = (version_controller
- (name[i], readonly, (struct stat *) 0,
+ (p_name[i], readonly, (struct stat *) 0,
&getbuf, &diffbuf));
version_controlled[i] = !! cs;
if (cs)
{
- if (version_get (name[i], cs, false, readonly,
+ if (version_get (p_name[i], cs, false, readonly,
getbuf, &st[i]))
stat_errno[i] = 0;
else
@@ -627,7 +630,7 @@ intuit_diff_type (void)
(i == NONE ? "delete"
: st[i].st_size == 0 ? "empty out"
: "create"),
- quotearg (name[i == NONE || st[i].st_size == 0 ? i0 : i]),
+ quotearg (p_name[i == NONE || st[i].st_size == 0 ? i0 : i]),
(i == NONE ? "does not exist"
: st[i].st_size == 0 ? "is already empty"
: "already exists"));
@@ -640,19 +643,19 @@ intuit_diff_type (void)
int distance_from_minimum[3];
for (i = OLD; i <= INDEX; i++)
- if (name[i])
+ if (p_name[i])
{
- newdirs[i] = (prefix_components (name[i], false)
- - prefix_components (name[i], true));
+ newdirs[i] = (prefix_components (p_name[i], false)
+ - prefix_components (p_name[i], true));
if (newdirs[i] < newdirs_min)
newdirs_min = newdirs[i];
}
for (i = OLD; i <= INDEX; i++)
- if (name[i])
+ if (p_name[i])
distance_from_minimum[i] = newdirs[i] - newdirs_min;
- i = best_name (name, distance_from_minimum);
+ i = best_name (p_name, distance_from_minimum);
}
}
}
@@ -661,17 +664,12 @@ intuit_diff_type (void)
inerrno = -1;
else
{
- inname = name[i];
- name[i] = 0;
+ inname = savestr(p_name[i]);
inerrno = stat_errno[i];
invc = version_controlled[i];
instat = st[i];
}
- for (i = OLD; i <= INDEX; i++)
- if (name[i])
- free (name[i]);
-
return retval;
}
@@ -1800,6 +1798,12 @@ pch_says_nonexistent (bool which)
return p_says_nonexistent[which];
}
+const char *
+pch_name (enum nametype type)
+{
+ return type == NONE ? NULL : p_name[type];
+}
+
/* Return timestamp of patch header for file WHICH (false = old, true = new),
or -1 if there was no timestamp or an error in the timestamp. */
Index: b/pch.h
===================================================================
--- a/pch.h
+++ b/pch.h
@@ -22,6 +22,8 @@
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+enum nametype { OLD, NEW, INDEX, NONE };
+
LINENUM pch_end (void);
LINENUM pch_first (void);
LINENUM pch_hunk_beg (void);
@@ -39,6 +41,7 @@ char pch_char (LINENUM);
int another_hunk (enum diff, bool);
int pch_says_nonexistent (bool);
size_t pch_line_len (LINENUM);
+const char *pch_name(enum nametype);
time_t pch_timestamp (bool);
void do_ed_script (FILE *);
void open_patch_file (char const *);
++++++ preserve-c_function-in-reject-files.diff ++++++
Include the C function names in reject files whenever possible.
---
patch.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: b/patch.c
===================================================================
--- a/patch.c
+++ b/patch.c
@@ -943,8 +943,9 @@ abort_hunk (void)
(int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ****" : "";
char const *minuses =
(int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ----" : " -----";
+ char const *c_function = pch_c_function();
- fprintf(rejfp, "***************\n");
+ fprintf(rejfp, "***************%s\n", c_function ? c_function : "");
for (i=0; i<=pat_end; i++) {
char numbuf0[LINENUM_LENGTH_BOUND + 1];
char numbuf1[LINENUM_LENGTH_BOUND + 1];
++++++ unified-reject-files.diff ++++++
--- /var/tmp/diff_new_pack.d29105/_old 2009-02-26 18:15:44.000000000 +0100
+++ /var/tmp/diff_new_pack.d29105/_new 2009-02-26 18:15:44.000000000 +0100
@@ -1,173 +1,50 @@
-Generate unified diff style reject files. Also include the C function names
-in reject files whenever possible.
+Generate unified diff style reject files.
- $ cat > f.orig
- < a() {
- < 2
- < 3
- <
- < 5
- < 6
- < }
+---
+ patch.c | 104 +++++++++++++++++++++++++++++++++++++--
+ patch.man | 3 +
+ tests/unified-reject-files.shrun | 104 +++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 208 insertions(+), 3 deletions(-)
- $ sed -e 's/5/5a/' f.orig > f
- $ diff -U2 -p f.orig f > f.diff
- $ sed -e 's/5/5a/' -e 's/6/6x/' f.orig > f
- $ ./patch -F0 -s --no-backup-if-mismatch f --reject-unified < 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 /dev/null f.orig > f2.diff
- $ ./patch -F0 -s --no-backup-if-mismatch f --reject-unified < 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
- > +}
-
- $ rm -f f f.orig f.rej f.diff f2.diff
-
-Index: patch-2.5.9/pch.c
-===================================================================
---- patch-2.5.9.orig/pch.c
-+++ patch-2.5.9/pch.c
-@@ -68,6 +68,7 @@ static LINENUM p_sline; /* and the lin
- static LINENUM p_hunk_beg; /* line number of current hunk */
- static LINENUM p_efake = -1; /* end of faked up lines--don't free */
- static LINENUM p_bfake = -1; /* beg of faked up lines */
-+static char *p_c_function; /* the C function a hunk is in */
-
- enum nametype { OLD, NEW, INDEX, NONE };
-
-@@ -888,6 +889,19 @@ another_hunk (enum diff difftype, bool r
- next_intuit_at(line_beginning,p_input_line);
- return chars_read == (size_t) -1 ? -1 : 0;
- }
-+ s = buf;
-+ while (*s == '*')
-+ s++;
-+ if (*s == ' ')
-+ {
-+ p_c_function = s;
-+ while (*s != '\n')
-+ s++;
-+ *s = '\0';
-+ p_c_function = savestr (p_c_function);
-+ }
-+ else
-+ p_c_function = NULL;
- p_hunk_beg = p_input_line + 1;
- while (p_end < p_max) {
- chars_read = get_line ();
-@@ -1277,8 +1291,18 @@ another_hunk (enum diff difftype, bool r
- else
- p_repl_lines = 1;
- if (*s == ' ') s++;
-- if (*s != '@')
-+ if (*s++ != '@')
- malformed ();
-+ if (*s++ == '@' && *s == ' ' && *s != '\0')
-+ {
-+ p_c_function = s;
-+ while (*s != '\n')
-+ s++;
-+ *s = '\0';
-+ p_c_function = savestr (p_c_function);
-+ }
-+ else
-+ p_c_function = NULL;
- if (!p_ptrn_lines)
- p_first++; /* do append rather than insert */
- if (!p_repl_lines)
-@@ -1884,6 +1908,12 @@ pch_hunk_beg (void)
- return p_hunk_beg;
- }
-
-+char const *
-+pch_c_function (void)
-+{
-+ return p_c_function;
-+}
-+
- /* Is the newline-terminated line a valid `ed' command for patch
- input? If so, return the command character; if not, return 0.
- This accepts accepts just a subset of the valid commands, but it's
-Index: patch-2.5.9/pch.h
-===================================================================
---- patch-2.5.9.orig/pch.h
-+++ patch-2.5.9/pch.h
-@@ -25,6 +25,7 @@
- LINENUM pch_end (void);
- LINENUM pch_first (void);
- LINENUM pch_hunk_beg (void);
-+char const *pch_c_function (void);
- LINENUM pch_newfirst (void);
- LINENUM pch_prefix_context (void);
- LINENUM pch_ptrn_lines (void);
-Index: patch-2.5.9/patch.man
+Index: b/patch.man
===================================================================
---- patch-2.5.9.orig/patch.man
-+++ patch-2.5.9/patch.man
+--- a/patch.man
++++ b/patch.man
@@ -517,6 +517,9 @@ instead of the default
.B \&.rej
file.
.TP
-+\fB\*=reject\-unified\fP
++\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: patch-2.5.9/common.h
+Index: b/patch.c
===================================================================
---- patch-2.5.9.orig/common.h
-+++ patch-2.5.9/common.h
-@@ -146,6 +146,7 @@ XTERN int invc;
- XTERN struct stat instat;
- XTERN bool dry_run;
- XTERN bool posixly_correct;
-+XTERN bool unified_reject_files;
+--- 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));
- XTERN char const *origprae;
- XTERN char const *origbase;
-Index: patch-2.5.9/patch.c
-===================================================================
---- patch-2.5.9.orig/patch.c
-+++ patch-2.5.9/patch.c
-@@ -522,6 +522,7 @@ static struct option const longopts[] =
++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},
@@ -175,7 +52,7 @@
{NULL, no_argument, NULL, 0}
};
-@@ -580,6 +581,7 @@ static char const *const option_help[] =
+@@ -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.",
@@ -183,123 +60,236 @@
"",
" -d DIR --directory=DIR Change the working directory to DIR first.",
#if HAVE_SETMODE_DOS
-@@ -779,6 +781,9 @@ get_some_switches (void)
+@@ -779,6 +784,9 @@ get_some_switches (void)
(enum quoting_style) i);
}
break;
+ case CHAR_MAX + 9:
-+ unified_reject_files = true;
++ abort_hunk = abort_hunk_unified;
+ break;
default:
usage (stderr, 2);
}
-@@ -927,6 +932,24 @@ locate_hunk (LINENUM fuzz)
- return 0;
+@@ -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 ();
+ }
}
-+static char *
-+format_linerange (char rangebuf[LINENUM_LENGTH_BOUND*2 + 2],
-+ LINENUM first, LINENUM lines)
++/* Produce unified reject files */
++
++static void
++print_unified(FILE *fp)
+{
-+ if (lines == 1)
-+ rangebuf = format_linenum (rangebuf, first);
-+ else
-+ {
-+ char *rb;
-+ rangebuf = format_linenum (rangebuf + LINENUM_LENGTH_BOUND + 1, lines);
-+ rb = rangebuf-1;
-+ rangebuf = format_linenum (rangebuf - LINENUM_LENGTH_BOUND - 1,
-+ (lines > 0) ? first : 0);
-+ *rb = ',';
-+ }
-+ return rangebuf;
-+}
++ register LINENUM old = 1;
++ register LINENUM lastline = pch_ptrn_lines ();
++ register LINENUM new = lastline + 1;
++ register LINENUM pat_end = pch_end ();
+
- /* We did not find the pattern, dump out the hunk so they can handle it. */
-
- static void
-@@ -943,8 +966,83 @@ abort_hunk (void)
- (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ****" : "";
- char const *minuses =
- (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ----" : " -----";
-+ char const *function = pch_c_function();
-+ if (function == NULL)
-+ function = "";
++ while (pch_char (new) == '=' || pch_char (new) == '\n')
++ new++;
+
-+ if (unified_reject_files)
++ while (old <= lastline)
+ {
-+ /* produce unified reject files */
-+ char rangebuf0[LINENUM_LENGTH_BOUND*2 + 2];
-+ char rangebuf1[LINENUM_LENGTH_BOUND*2 + 2];
-+ LINENUM j;
-+
-+ /* Find the beginning of the remove and insert section. */
-+ for (j = 0; j <= pat_end; j++)
-+ if (pch_char (j) == '=')
-+ break;
-+ for (i = j+1; i <= pat_end; i++)
-+ if (pch_char (i) == '^')
++ if (pch_char (old) == '-')
++ {
++ fputc ('-', fp);
++ pch_write_line (old++, fp);
++ }
++ else if (new > pat_end)
+ break;
-+ if (pch_char (0) != '*' || j > pat_end || i > pat_end+1)
-+ fatal ("internal error in abort_hunk");
-+ i = 1; j++;
-+
-+ /* @@ -from,lines +to,lines @@ */
-+ fprintf (rejfp, "@@ -%s +%s @@%s\n",
-+ format_linerange (rangebuf0, oldfirst, pch_ptrn_lines()),
-+ format_linerange (rangebuf1, newfirst, pch_repl_lines()),
-+ function);
-+
-+ while ( (i <= pat_end && pch_char (i) != '=')
-+ || (j <= pat_end && pch_char (j) != '^'))
++ else if (pch_char (new) == '+')
+ {
-+ if (i <= pat_end
-+ && (pch_char (i) == '-' || pch_char (i) == '!'))
-+ {
-+ fputc('-', rejfp);
-+ pch_write_line (i++, rejfp);
-+ }
-+ else if (j <= pat_end
-+ && (pch_char (j) == '+' || pch_char (j) == '!'))
-+ {
-+ fputc('+', rejfp);
-+ pch_write_line (j++, rejfp);
-+ }
-+ else if ((i <= pat_end
-+ && (pch_char (i) == ' ' || pch_char (i) == '\n')) &&
-+ (j > pat_end
-+ || (pch_char (j) == ' ' || pch_char (j) == '\n')))
++ 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
+ {
-+ /* Unless j is already past the end, lines i and j
-+ must be equal here. */
-+
-+ if (pch_char (i) == ' ')
-+ fputc(' ', rejfp);
-+ pch_write_line (i++, rejfp);
-+ if (j <= pat_end)
-+ j++;
++ fputc ('-', fp);
++ pch_write_line (old++, fp);
+ }
-+ else if ((j <= pat_end &&
-+ (pch_char (j) == ' ' || pch_char (j) == '\n')) &&
-+ (pch_char (i) == '='))
++ while (pch_char (old) == '!');
++ do
+ {
-+ if (pch_char (j) == ' ')
-+ fputc(' ', rejfp);
-+ pch_write_line (j++, rejfp);
++ fputc ('+', fp);
++ pch_write_line (new++, fp);
+ }
-+ else
-+ fatal ("internal error in abort_hunk");
++ while (pch_char (new) == '!');
+ }
-+
-+ if (ferror (rejfp))
-+ write_fatal ();
-+ return;
++ 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. */
-- fprintf(rejfp, "***************\n");
-+ /* produce context type reject files */
-+
-+ fprintf(rejfp, "***************%s\n", function);
- for (i=0; i<=pat_end; i++) {
- char numbuf0[LINENUM_LENGTH_BOUND + 1];
- char numbuf1[LINENUM_LENGTH_BOUND + 1];
+ 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
++> +}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org