summaryrefslogtreecommitdiff
path: root/packages/patch/patch-2.5.9/global-reject-file.diff
blob: 66065fcbf54f914ba58051c376e016b6d49f84df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
Index: patch-2.5.9/patch.man
===================================================================
--- 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;
 static char * const *Argv;
 
 static FILE *rejfp;  /* reject file pointer */
+static char *global_reject;
 
 static char const *patchname;
 static char *rejname;
@@ -172,6 +174,10 @@ main (int argc, char **argv)
     /* Make sure we clean up in case of disaster.  */
     set_signals (false);
 
+    /* initialize global reject file */
+    if (global_reject)
+      init_reject ();
+
     for (
 	open_patch_file (patchname);
 	there_is_another_patch();
@@ -208,8 +214,9 @@ main (int argc, char **argv)
 	    init_output (TMPOUTNAME, exclusive, &outstate);
 	  }
 
-	/* initialize reject file */
-	init_reject ();
+	/* initialize per-patch reject file */
+	if (!global_reject)
+	  init_reject ();
 
 	/* 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)
 		    fclose (outstate.ofp);
 		    outstate.ofp = 0;
 		  }
-		fclose (rejfp);
+		if (!global_reject)
+		  fclose (rejfp);
 		continue;
 	      }
 
@@ -412,13 +426,13 @@ main (int argc, char **argv)
 	    }
       }
       if (diff_type != ED_DIFF) {
-	if (fclose (rejfp) != 0)
+	if (!global_reject && fclose (rejfp) != 0)
 	    write_fatal ();
 	if (failed) {
 	    somefailed = true;
 	    say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1),
 		 skip_rest_of_patch ? "ignored" : "FAILED");
-	    if (outname) {
+	    if (!global_reject && outname) {
 		char *rej = rejname;
 		if (!rejname) {
 		    rej = xmalloc (strlen (outname) + 5);
@@ -445,6 +459,20 @@ main (int argc, char **argv)
       }
       set_signals (true);
     }
+    if (global_reject)
+      {
+	if (fclose (rejfp) != 0)
+	  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);
+	    /*}*/
+	  }
+      }
     if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0))
       write_fatal ();
     cleanup ();
@@ -523,6 +551,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},
+  {"global-reject-file", required_argument, NULL, CHAR_MAX + 10},
   {NULL, no_argument, NULL, 0}
 };
 
@@ -582,6 +611,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.",
+"  --global-reject-file=file  Put all rejects into one file.",
 "",
 "  -d DIR  --directory=DIR  Change the working directory to DIR first.",
 #if HAVE_SETMODE_DOS
@@ -784,6 +814,9 @@ get_some_switches (void)
 	    case CHAR_MAX + 9:
 		unified_reject_files = true;
 		break;
+	    case CHAR_MAX + 10:
+		global_reject = savestr (optarg);
+		break;
 	    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)
 {