wok-current view busybox/stuff/busybox-1.10.3-patch.u @ rev 2953

Fix: Mitter (category)
author Claudinei Pereira <claudinei@slitaz.org>
date Fri May 08 11:59:03 2009 +0000 (2009-05-08)
parents
children
line source
1 --- busybox-1.10.3/editors/patch.c 2008-03-24 15:46:20.000000000 +0100
2 +++ busybox-1.10.3/editors/patch.c 2008-03-24 15:46:20.000000000 +0100
3 @@ -19,15 +19,11 @@
4 * - Reject file isnt saved
5 */
7 -#include <getopt.h>
8 -
9 #include "libbb.h"
11 -static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, const unsigned int lines_count)
12 +static unsigned copy_lines(FILE *src_stream, FILE *dest_stream, unsigned lines_count)
13 {
14 - unsigned int i = 0;
15 -
16 - while (src_stream && (i < lines_count)) {
17 + while (src_stream && lines_count) {
18 char *line;
19 line = xmalloc_fgets(src_stream);
20 if (line == NULL) {
21 @@ -37,60 +33,70 @@
22 bb_perror_msg_and_die("error writing to new file");
23 }
24 free(line);
25 -
26 - i++;
27 + lines_count--;
28 }
29 - return i;
30 + return lines_count;
31 }
33 /* If patch_level is -1 it will remove all directory names
34 * char *line must be greater than 4 chars
35 * returns NULL if the file doesnt exist or error
36 * returns malloc'ed filename
37 + * NB: frees 1st argument!
38 */
40 -static char *extract_filename(char *line, int patch_level)
41 +static char *extract_filename(char *line, unsigned patch_level, const char *pat)
42 {
43 - char *temp, *filename_start_ptr = line + 4;
44 - int i;
45 + char *temp = NULL, *filename_start_ptr = line + 4;
47 - /* Terminate string at end of source filename */
48 - temp = strchrnul(filename_start_ptr, '\t');
49 - *temp = '\0';
50 -
51 - /* Skip over (patch_level) number of leading directories */
52 - if (patch_level == -1)
53 - patch_level = INT_MAX;
54 - for (i = 0; i < patch_level; i++) {
55 - temp = strchr(filename_start_ptr, '/');
56 - if (!temp)
57 - break;
58 - filename_start_ptr = temp + 1;
59 + if (strncmp(line, pat, 4) == 0) {
60 + /* Terminate string at end of source filename */
61 + line[strcspn(line,"\t\n\r")] = '\0';
62 +
63 + /* Skip over (patch_level) number of leading directories */
64 + while (patch_level--) {
65 + temp = strchr(filename_start_ptr, '/');
66 + if (!temp)
67 + break;
68 + filename_start_ptr = temp + 1;
69 + }
70 + temp = xstrdup(filename_start_ptr);
71 }
72 -
73 - return xstrdup(filename_start_ptr);
74 + free(line);
75 + return temp;
76 }
78 int patch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
79 int patch_main(int argc ATTRIBUTE_UNUSED, char **argv)
80 {
81 - int patch_level = -1;
82 - char *patch_line;
83 - int ret;
84 - FILE *patch_file = NULL;
85 struct stat saved_stat;
86 -
87 + char *patch_line;
88 + FILE *patch_file;
89 + int patch_level;
90 + int ret = 0;
91 +#define ENABLE_FEATURE_PATCH_REVERSE 1
92 +#if ENABLE_FEATURE_PATCH_REVERSE
93 + char minus = '-';
94 + char plus = '+';
95 +#else
96 + const char minus = '-';
97 + const char plus = '+';
98 +#endif
99 +
100 + xfunc_error_retval = 2;
101 {
102 - char *p, *i;
103 - ret = getopt32(argv, "p:i:", &p, &i);
104 - if (ret & 1)
105 - patch_level = xatol_range(p, -1, USHRT_MAX);
106 - if (ret & 2) {
107 - patch_file = xfopen(i, "r");
108 - } else {
109 - patch_file = stdin;
110 - }
111 - ret = 0;
112 + const char *p = "-1";
113 + const char *i = "-"; /* compat */
114 +#if ENABLE_FEATURE_PATCH_REVERSE
115 + if (getopt32(argv, "p:i:R", &p, &i) & 4) {
116 + minus = '+';
117 + plus = '-';
118 + }
119 +#else
120 + getopt32(argv, "p:i:", &p, &i);
121 +#endif
122 + patch_level = xatoi(p); /* can be negative! */
123 + patch_file = xfopen_stdin(i);
124 }
126 patch_line = xmalloc_getline(patch_file);
127 @@ -100,38 +106,38 @@
128 char *original_filename;
129 char *new_filename;
130 char *backup_filename;
131 - unsigned int src_cur_line = 1;
132 - unsigned int dest_cur_line = 0;
133 - unsigned int dest_beg_line;
134 - unsigned int bad_hunk_count = 0;
135 - unsigned int hunk_count = 0;
136 - char copy_trailing_lines_flag = 0;
137 + unsigned src_cur_line = 1;
138 + unsigned dest_cur_line = 0;
139 + unsigned dest_beg_line;
140 + unsigned bad_hunk_count = 0;
141 + unsigned hunk_count = 0;
142 + smallint copy_trailing_lines_flag = 0;
144 /* Skip everything upto the "---" marker
145 * No need to parse the lines "Only in <dir>", and "diff <args>"
146 */
147 - while (patch_line && strncmp(patch_line, "--- ", 4) != 0) {
148 - free(patch_line);
149 + do {
150 + /* Extract the filename used before the patch was generated */
151 + original_filename = extract_filename(patch_line, patch_level, "--- ");
152 patch_line = xmalloc_getline(patch_file);
153 - }
154 - /* FIXME: patch_line NULL check?? */
155 + if (!patch_line) goto quit;
156 + } while (!original_filename);
158 - /* Extract the filename used before the patch was generated */
159 - original_filename = extract_filename(patch_line, patch_level);
160 - free(patch_line);
161 -
162 - patch_line = xmalloc_getline(patch_file);
163 - /* FIXME: NULL check?? */
164 - if (strncmp(patch_line, "+++ ", 4) != 0) {
165 - ret = 2;
166 - bb_error_msg("invalid patch");
167 - continue;
168 + new_filename = extract_filename(patch_line, patch_level, "+++ ");
169 + if (!new_filename) {
170 + bb_error_msg_and_die("invalid patch");
171 + }
172 +#if ENABLE_FEATURE_PATCH_REVERSE
173 + if (plus != '+') {
174 + /* reverse patch */
175 + char *tmp = original_filename;
176 + original_filename = new_filename;
177 + new_filename = tmp;
178 }
179 - new_filename = extract_filename(patch_line, patch_level);
180 - free(patch_line);
181 +#endif
183 /* Get access rights from the file to be patched, -1 file does not exist */
184 - if (stat(new_filename, &saved_stat)) {
185 + if (stat(new_filename, &saved_stat) != 0) {
186 char *line_ptr;
187 /* Create leading directories */
188 line_ptr = strrchr(new_filename, '/');
189 @@ -140,132 +146,137 @@
190 bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
191 *line_ptr = '/';
192 }
193 - dst_stream = xfopen(new_filename, "w+");
194 backup_filename = NULL;
195 + saved_stat.st_mode = 0644;
196 } else {
197 - backup_filename = xmalloc(strlen(new_filename) + 6);
198 - strcpy(backup_filename, new_filename);
199 - strcat(backup_filename, ".orig");
200 + backup_filename = xasprintf("%s.orig", new_filename);
201 xrename(new_filename, backup_filename);
202 - dst_stream = xfopen(new_filename, "w");
203 - fchmod(fileno(dst_stream), saved_stat.st_mode);
204 }
205 -
206 - if ((backup_filename == NULL) || stat(original_filename, &saved_stat)) {
207 - src_stream = NULL;
208 - } else {
209 - if (strcmp(original_filename, new_filename) == 0) {
210 - src_stream = xfopen(backup_filename, "r");
211 - } else {
212 - src_stream = xfopen(original_filename, "r");
213 - }
214 + dst_stream = xfopen(new_filename, "w");
215 + fchmod(fileno(dst_stream), saved_stat.st_mode);
216 + src_stream = NULL;
217 +
218 + if (backup_filename && !stat(original_filename, &saved_stat)) {
219 + src_stream = xfopen((strcmp(original_filename, new_filename)) ?
220 + original_filename : backup_filename, "r");
221 }
223 printf("patching file %s\n", new_filename);
225 - /* Handle each hunk */
226 + /* Handle all hunks for this file */
227 patch_line = xmalloc_fgets(patch_file);
228 while (patch_line) {
229 - unsigned int count;
230 - unsigned int src_beg_line;
231 - unsigned int unused;
232 - unsigned int hunk_offset_start = 0;
233 - int hunk_error = 0;
234 -
235 - /* This bit should be improved */
236 - if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) &&
237 - (sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) &&
238 - (sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) {
239 + unsigned count;
240 + unsigned src_beg_line;
241 + unsigned hunk_offset_start;
242 + unsigned src_last_line = 1;
243 +#if ENABLE_FEATURE_PATCH_REVERSE
244 + unsigned dst_last_line = 1;
245 +
246 + if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dest_beg_line, &dst_last_line) < 3) &&
247 + (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dest_beg_line, &dst_last_line) < 2)) {
248 /* No more hunks for this file */
249 break;
250 }
251 - free(patch_line);
252 + if (plus != '+') {
253 + /* reverse patch */
254 + unsigned tmp = src_last_line;
255 + src_last_line = dst_last_line;
256 + dst_last_line = tmp;
257 + tmp = src_beg_line;
258 + src_beg_line = dest_beg_line;
259 + dest_beg_line = tmp;
260 + }
261 +#else
262 +
263 + if ((sscanf(patch_line, "@@ -%d,%d +%d", &src_beg_line, &src_last_line, &dest_beg_line) != 3) &&
264 + (sscanf(patch_line, "@@ -%d +%d", &src_beg_line, &dest_beg_line) != 2)) {
265 + /* No more hunks for this file */
266 + break;
267 + }
268 +#endif
269 hunk_count++;
271 if (src_beg_line && dest_beg_line) {
272 /* Copy unmodified lines upto start of hunk */
273 - /* src_beg_line will be 0 if its a new file */
274 + /* src_beg_line will be 0 if it's a new file */
275 count = src_beg_line - src_cur_line;
276 - if (copy_lines(src_stream, dst_stream, count) != count) {
277 + if (copy_lines(src_stream, dst_stream, count)) {
278 bb_error_msg_and_die("bad src file");
279 }
280 src_cur_line += count;
281 dest_cur_line += count;
282 copy_trailing_lines_flag = 1;
283 }
284 - hunk_offset_start = src_cur_line;
285 -
286 - while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
287 - if ((*patch_line == '-') || (*patch_line == ' ')) {
288 + src_last_line += hunk_offset_start = src_cur_line;
289 +#if ENABLE_FEATURE_PATCH_REVERSE
290 + dst_last_line += dest_cur_line;
291 +#endif
292 + while (1) {
293 + free(patch_line);
294 + patch_line = xmalloc_fgets(patch_file);
295 + if (patch_line == NULL) break;
296 + if ((*patch_line == minus) || (*patch_line == ' ')) {
297 char *src_line = NULL;
298 + if (src_cur_line == src_last_line) break;
299 if (src_stream) {
300 src_line = xmalloc_fgets(src_stream);
301 - if (!src_line) {
302 - hunk_error++;
303 - break;
304 - } else {
305 + if (src_line) {
306 + int diff = strcmp(src_line, patch_line + 1);
307 src_cur_line++;
308 + free(src_line);
309 + if (diff) src_line = NULL;
310 }
311 - if (strcmp(src_line, patch_line + 1) != 0) {
312 - bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
313 - hunk_error++;
314 - free(patch_line);
315 - /* Probably need to find next hunk, etc... */
316 - /* but for now we just bail out */
317 - patch_line = NULL;
318 - break;
319 - }
320 - free(src_line);
321 }
322 - if (*patch_line == ' ') {
323 - fputs(patch_line + 1, dst_stream);
324 - dest_cur_line++;
325 + if (!src_line) {
326 + bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
327 + bad_hunk_count++;
328 + break;
329 }
330 - } else if (*patch_line == '+') {
331 - fputs(patch_line + 1, dst_stream);
332 - dest_cur_line++;
333 - } else {
334 + if (*patch_line != ' ') {
335 + continue;
336 + }
337 + } else if (*patch_line != plus) {
338 break;
339 }
340 - free(patch_line);
341 - }
342 - if (hunk_error) {
343 - bad_hunk_count++;
344 - }
345 - }
346 +#if ENABLE_FEATURE_PATCH_REVERSE
347 + if (dest_cur_line == dst_last_line) break;
348 +#endif
349 + fputs(patch_line + 1, dst_stream);
350 + dest_cur_line++;
351 + } /* end of while loop handling one hunk */
352 + } /* end of while loop handling one file */
354 /* Cleanup last patched file */
355 if (copy_trailing_lines_flag) {
356 - copy_lines(src_stream, dst_stream, -1);
357 + copy_lines(src_stream, dst_stream, (unsigned)(-1));
358 }
359 if (src_stream) {
360 fclose(src_stream);
361 }
362 - if (dst_stream) {
363 - fclose(dst_stream);
364 - }
365 + fclose(dst_stream);
366 if (bad_hunk_count) {
367 - if (!ret) {
368 - ret = 1;
369 - }
370 - bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count);
371 + ret = 1;
372 + bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
373 } else {
374 /* It worked, we can remove the backup */
375 if (backup_filename) {
376 unlink(backup_filename);
377 + free(backup_filename);
378 }
379 if ((dest_cur_line == 0) || (dest_beg_line == 0)) {
380 /* The new patched file is empty, remove it */
381 xunlink(new_filename);
382 - if (strcmp(new_filename, original_filename) != 0)
383 - xunlink(original_filename);
384 + /* original_filename and new_filename may be the same file */
385 + unlink(original_filename);
386 }
387 }
388 - }
389 + } /* end of "while there are patch lines" */
390 +quit:
392 /* 0 = SUCCESS
393 * 1 = Some hunks failed
394 - * 2 = More serious problems
395 + * 2 = More serious problems (exited earlier)
396 */
397 return ret;
398 }
400 --- busybox-1.10.3/include/usage.h 2008-03-24 16:20:43.000000000 +0100
401 +++ busybox-1.10.3/include/usage.h 2008-03-24 16:22:06.000000000 +0100
402 @@ -2837,8 +2837,9 @@
403 )
405 #define patch_trivial_usage \
406 - "[-p NUM] [-i DIFF]"
407 + "[-R] [-p NUM] [-i DIFF]"
408 #define patch_full_usage \
409 + " -R Reverse patch\n" \
410 " -p NUM Strip NUM leading components from file names" \
411 "\n -i DIFF Read DIFF instead of stdin" \