wok-current rev 498

Busybox: add patch -R
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon Mar 24 15:49:00 2008 +0000 (2008-03-24)
parents 1b37a413afd5
children 20068c6f5109
files busybox/stuff/busybox-1.10.0-patch.u
line diff
     1.1 --- a/busybox/stuff/busybox-1.10.0-patch.u	Sun Mar 23 20:55:19 2008 +0100
     1.2 +++ b/busybox/stuff/busybox-1.10.0-patch.u	Mon Mar 24 15:49:00 2008 +0000
     1.3 @@ -1,11 +1,15 @@
     1.4 ---- busybox-1.10.0/editors/patch.c	Sat Mar 22 02:31:52 2008
     1.5 -+++ busybox-1.10.0/editors/patch.c	Sat Mar 22 02:31:52 2008
     1.6 -@@ -23,11 +23,9 @@
     1.7 +--- busybox-1.10.0/editors/patch.c	2008-03-24 15:46:20.000000000 +0100
     1.8 ++++ busybox-1.10.0/editors/patch.c	2008-03-24 15:46:20.000000000 +0100
     1.9 +@@ -19,15 +19,11 @@
    1.10 +  *   - Reject file isnt saved
    1.11 +  */
    1.12   
    1.13 +-#include <getopt.h>
    1.14 +-
    1.15   #include "libbb.h"
    1.16   
    1.17  -static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, const unsigned int lines_count)
    1.18 -+static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, unsigned int lines_count)
    1.19 ++static unsigned copy_lines(FILE *src_stream, FILE *dest_stream, unsigned lines_count)
    1.20   {
    1.21  -	unsigned int i = 0;
    1.22  -
    1.23 @@ -14,10 +18,11 @@
    1.24   		char *line;
    1.25   		line = xmalloc_fgets(src_stream);
    1.26   		if (line == NULL) {
    1.27 -@@ -38,9 +36,9 @@
    1.28 +@@ -37,60 +33,70 @@
    1.29 + 			bb_perror_msg_and_die("error writing to new file");
    1.30   		}
    1.31   		free(line);
    1.32 - 
    1.33 +-
    1.34  -		i++;
    1.35  +		lines_count--;
    1.36   	}
    1.37 @@ -26,82 +31,162 @@
    1.38   }
    1.39   
    1.40   /* If patch_level is -1 it will remove all directory names
    1.41 -@@ -49,26 +47,24 @@
    1.42 +  * char *line must be greater than 4 chars
    1.43 +  * returns NULL if the file doesnt exist or error
    1.44    * returns malloc'ed filename
    1.45 ++ * NB: frees 1st argument!
    1.46    */
    1.47   
    1.48  -static char *extract_filename(char *line, int patch_level)
    1.49 -+static char *extract_filename(char *line, unsigned int patch_level)
    1.50 ++static char *extract_filename(char *line, unsigned patch_level, const char *pat)
    1.51   {
    1.52 - 	char *temp, *filename_start_ptr = line + 4;
    1.53 +-	char *temp, *filename_start_ptr = line + 4;
    1.54  -	int i;
    1.55 ++	char *temp = NULL, *filename_start_ptr = line + 4;
    1.56   
    1.57 - 	/* Terminate string at end of source filename */
    1.58 +-	/* Terminate string at end of source filename */
    1.59  -	temp = strchrnul(filename_start_ptr, '\t');
    1.60  -	*temp = '\0';
    1.61 -+	line[strcspn(line,"\t\n")] = '\0';
    1.62 - 
    1.63 - 	/* Skip over (patch_level) number of leading directories */
    1.64 +-
    1.65 +-	/* Skip over (patch_level) number of leading directories */
    1.66  -	if (patch_level == -1)
    1.67  -		patch_level = INT_MAX;
    1.68  -	for (i = 0; i < patch_level; i++) {
    1.69 -+	while (patch_level--) {
    1.70 - 		temp = strchr(filename_start_ptr, '/');
    1.71 - 		if (!temp)
    1.72 - 			break;
    1.73 - 		filename_start_ptr = temp + 1;
    1.74 +-		temp = strchr(filename_start_ptr, '/');
    1.75 +-		if (!temp)
    1.76 +-			break;
    1.77 +-		filename_start_ptr = temp + 1;
    1.78 ++	if (strncmp(line, pat, 4) == 0) {
    1.79 ++		/* Terminate string at end of source filename */
    1.80 ++		line[strcspn(line,"\t\n\r")] = '\0';
    1.81 ++
    1.82 ++		/* Skip over (patch_level) number of leading directories */
    1.83 ++		while (patch_level--) {
    1.84 ++			temp = strchr(filename_start_ptr, '/');
    1.85 ++			if (!temp)
    1.86 ++				break;
    1.87 ++			filename_start_ptr = temp + 1;
    1.88 ++		}
    1.89 ++		temp = xstrdup(filename_start_ptr);
    1.90   	}
    1.91 - 
    1.92 +-
    1.93  -	return xstrdup(filename_start_ptr);
    1.94 -+	temp = xstrdup(filename_start_ptr);
    1.95  +	free(line);
    1.96  +	return temp;
    1.97   }
    1.98   
    1.99   int patch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
   1.100 -@@ -77,7 +73,7 @@
   1.101 - 	int patch_level = -1;
   1.102 - 	char *patch_line;
   1.103 - 	int ret;
   1.104 + int patch_main(int argc ATTRIBUTE_UNUSED, char **argv)
   1.105 + {
   1.106 +-	int patch_level = -1;
   1.107 +-	char *patch_line;
   1.108 +-	int ret;
   1.109  -	FILE *patch_file = NULL;
   1.110 -+	FILE *patch_file = stdin;
   1.111   	struct stat saved_stat;
   1.112 - 	
   1.113 +-	
   1.114 ++	char *patch_line;
   1.115 ++	FILE *patch_file;
   1.116 ++	int patch_level;
   1.117 ++	int ret = 0;
   1.118 ++#define ENABLE_FEATURE_PATCH_REVERSE 1
   1.119 ++#if ENABLE_FEATURE_PATCH_REVERSE
   1.120 ++	char minus = '-';
   1.121 ++	char plus = '+';
   1.122 ++#else
   1.123 ++	const char minus = '-';
   1.124 ++	const char plus = '+';
   1.125 ++#endif
   1.126 ++
   1.127 ++	xfunc_error_retval = 2;	
   1.128   	{
   1.129 -@@ -87,12 +83,11 @@
   1.130 - 			patch_level = xatol_range(p, -1, USHRT_MAX);
   1.131 - 		if (ret & 2) {
   1.132 - 			patch_file = xfopen(i, "r");
   1.133 +-		char *p, *i;
   1.134 +-		ret = getopt32(argv, "p:i:", &p, &i);
   1.135 +-		if (ret & 1)
   1.136 +-			patch_level = xatol_range(p, -1, USHRT_MAX);
   1.137 +-		if (ret & 2) {
   1.138 +-			patch_file = xfopen(i, "r");
   1.139  -		} else {
   1.140  -			patch_file = stdin;
   1.141 - 		}
   1.142 - 		ret = 0;
   1.143 +-		}
   1.144 +-		ret = 0;
   1.145 ++		const char *p = "-1";
   1.146 ++		const char *i = "-"; /* compat */
   1.147 ++#if ENABLE_FEATURE_PATCH_REVERSE
   1.148 ++		if (getopt32(argv, "p:i:R", &p, &i) & 4) {
   1.149 ++			minus = '+';
   1.150 ++			plus = '-';
   1.151 ++		}
   1.152 ++#else
   1.153 ++		getopt32(argv, "p:i:", &p, &i);
   1.154 ++#endif
   1.155 ++		patch_level = xatoi(p); /* can be negative! */
   1.156 ++		patch_file = xfopen_stdin(i);
   1.157   	}
   1.158   
   1.159 -+	//xfunc_error_retval = 2;
   1.160   	patch_line = xmalloc_getline(patch_file);
   1.161 - 	while (patch_line) {
   1.162 - 		FILE *src_stream;
   1.163 -@@ -118,17 +113,13 @@
   1.164 +@@ -100,38 +106,38 @@
   1.165 + 		char *original_filename;
   1.166 + 		char *new_filename;
   1.167 + 		char *backup_filename;
   1.168 +-		unsigned int src_cur_line = 1;
   1.169 +-		unsigned int dest_cur_line = 0;
   1.170 +-		unsigned int dest_beg_line;
   1.171 +-		unsigned int bad_hunk_count = 0;
   1.172 +-		unsigned int hunk_count = 0;
   1.173 +-		char copy_trailing_lines_flag = 0;
   1.174 ++		unsigned src_cur_line = 1;
   1.175 ++		unsigned dest_cur_line = 0;
   1.176 ++		unsigned dest_beg_line;
   1.177 ++		unsigned bad_hunk_count = 0;
   1.178 ++		unsigned hunk_count = 0;
   1.179 ++		smallint copy_trailing_lines_flag = 0;
   1.180   
   1.181 - 		/* Extract the filename used before the patch was generated */
   1.182 - 		original_filename = extract_filename(patch_line, patch_level);
   1.183 + 		/* Skip everything upto the "---" marker
   1.184 + 		 * No need to parse the lines "Only in <dir>", and "diff <args>"
   1.185 + 		 */
   1.186 +-		while (patch_line && strncmp(patch_line, "--- ", 4) != 0) {
   1.187 +-			free(patch_line);
   1.188 ++		do {
   1.189 ++			/* Extract the filename used before the patch was generated */
   1.190 ++			original_filename = extract_filename(patch_line, patch_level, "--- ");
   1.191 + 			patch_line = xmalloc_getline(patch_file);
   1.192 +-		}
   1.193 +-		/* FIXME: patch_line NULL check?? */
   1.194 ++			if (!patch_line) goto quit;
   1.195 ++		} while (!original_filename);
   1.196 + 
   1.197 +-		/* Extract the filename used before the patch was generated */
   1.198 +-		original_filename = extract_filename(patch_line, patch_level);
   1.199  -		free(patch_line);
   1.200 - 
   1.201 - 		patch_line = xmalloc_getline(patch_file);
   1.202 - 		/* FIXME: NULL check?? */
   1.203 - 		if (strncmp(patch_line, "+++ ", 4) != 0) {
   1.204 +-
   1.205 +-		patch_line = xmalloc_getline(patch_file);
   1.206 +-		/* FIXME: NULL check?? */
   1.207 +-		if (strncmp(patch_line, "+++ ", 4) != 0) {
   1.208  -			ret = 2;
   1.209  -			bb_error_msg("invalid patch");
   1.210  -			continue;
   1.211 -+			bb_error_msg_and_die("invalid patch: %s\n",patch_line);
   1.212 ++		new_filename = extract_filename(patch_line, patch_level, "+++ ");
   1.213 ++		if (!new_filename) {
   1.214 ++			bb_error_msg_and_die("invalid patch");
   1.215 ++		}
   1.216 ++#if ENABLE_FEATURE_PATCH_REVERSE
   1.217 ++		if (plus != '+') {
   1.218 ++			/* reverse patch */
   1.219 ++			char *tmp = original_filename;
   1.220 ++			original_filename = new_filename;
   1.221 ++			new_filename = tmp;
   1.222   		}
   1.223 - 		new_filename = extract_filename(patch_line, patch_level);
   1.224 +-		new_filename = extract_filename(patch_line, patch_level);
   1.225  -		free(patch_line);
   1.226 ++#endif
   1.227   		
   1.228   		/* Get access rights from the file to be patched, -1 file does not exist */
   1.229 - 		if (stat(new_filename, &saved_stat)) {
   1.230 -@@ -140,20 +131,19 @@
   1.231 +-		if (stat(new_filename, &saved_stat)) {
   1.232 ++		if (stat(new_filename, &saved_stat) != 0) {
   1.233 + 			char *line_ptr;
   1.234 + 			/* Create leading directories */
   1.235 + 			line_ptr = strrchr(new_filename, '/');
   1.236 +@@ -140,132 +146,137 @@
   1.237   				bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
   1.238   				*line_ptr = '/';
   1.239   			}
   1.240 @@ -109,54 +194,84 @@
   1.241   			backup_filename = NULL;
   1.242  +			saved_stat.st_mode = 0644;
   1.243   		} else {
   1.244 - 			backup_filename = xmalloc(strlen(new_filename) + 6);
   1.245 - 			strcpy(backup_filename, new_filename);
   1.246 - 			strcat(backup_filename, ".orig");
   1.247 +-			backup_filename = xmalloc(strlen(new_filename) + 6);
   1.248 +-			strcpy(backup_filename, new_filename);
   1.249 +-			strcat(backup_filename, ".orig");
   1.250 ++			backup_filename = xasprintf("%s.orig", new_filename);
   1.251   			xrename(new_filename, backup_filename);
   1.252  -			dst_stream = xfopen(new_filename, "w");
   1.253  -			fchmod(fileno(dst_stream), saved_stat.st_mode);
   1.254   		}
   1.255 - 
   1.256 +-
   1.257  -		if ((backup_filename == NULL) || stat(original_filename, &saved_stat)) {
   1.258  -			src_stream = NULL;
   1.259  -		} else {
   1.260 +-			if (strcmp(original_filename, new_filename) == 0) {
   1.261 +-				src_stream = xfopen(backup_filename, "r");
   1.262 +-			} else {
   1.263 +-				src_stream = xfopen(original_filename, "r");
   1.264 +-			}
   1.265  +		dst_stream = xfopen(new_filename, "w");
   1.266  +		fchmod(fileno(dst_stream), saved_stat.st_mode);
   1.267  +		src_stream = NULL;
   1.268 ++
   1.269  +		if (backup_filename && !stat(original_filename, &saved_stat)) {
   1.270 - 			if (strcmp(original_filename, new_filename) == 0) {
   1.271 - 				src_stream = xfopen(backup_filename, "r");
   1.272 - 			} else {
   1.273 -@@ -168,54 +158,57 @@
   1.274 ++			src_stream = xfopen((strcmp(original_filename, new_filename)) ? 
   1.275 ++							    original_filename : backup_filename, "r");
   1.276 + 		}
   1.277 + 
   1.278 + 		printf("patching file %s\n", new_filename);
   1.279 + 
   1.280 +-		/* Handle each hunk */
   1.281 ++		/* Handle all hunks for this file */
   1.282 + 		patch_line = xmalloc_fgets(patch_file);
   1.283   		while (patch_line) {
   1.284 - 			unsigned int count;
   1.285 - 			unsigned int src_beg_line;
   1.286 -+			unsigned int src_last_line = 1;
   1.287 - 			unsigned int unused;
   1.288 - 			unsigned int hunk_offset_start = 0;
   1.289 - 			int hunk_error = 0;
   1.290 - 
   1.291 - 			/* This bit should be improved */
   1.292 +-			unsigned int count;
   1.293 +-			unsigned int src_beg_line;
   1.294 +-			unsigned int unused;
   1.295 +-			unsigned int hunk_offset_start = 0;
   1.296 +-			int hunk_error = 0;
   1.297 +-
   1.298 +-			/* This bit should be improved */
   1.299  -			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) &&
   1.300  -				(sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) &&
   1.301  -				(sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) {
   1.302 -+			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, 
   1.303 -+						&src_last_line, &dest_beg_line, &unused) != 4) &&
   1.304 -+				(sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, 
   1.305 -+						&src_last_line, &dest_beg_line) != 3) &&
   1.306 -+				(sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line,
   1.307 -+						&dest_beg_line, &unused) != 3) &&
   1.308 -+				(sscanf(patch_line, "@@ -%d +%d @@", &src_beg_line,
   1.309 -+						&dest_beg_line) != 2)) {
   1.310 ++			unsigned count;
   1.311 ++			unsigned src_beg_line;
   1.312 ++			unsigned hunk_offset_start;
   1.313 ++			unsigned src_last_line = 1;
   1.314 ++#if ENABLE_FEATURE_PATCH_REVERSE
   1.315 ++			unsigned dst_last_line = 1;
   1.316 ++
   1.317 ++			if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dest_beg_line, &dst_last_line) < 3) &&
   1.318 ++				(sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dest_beg_line, &dst_last_line) < 2)) {
   1.319   				/* No more hunks for this file */
   1.320   				break;
   1.321   			}
   1.322  -			free(patch_line);
   1.323 ++			if (plus != '+') { 
   1.324 ++				/* reverse patch */
   1.325 ++				unsigned tmp = src_last_line;
   1.326 ++				src_last_line = dst_last_line;
   1.327 ++				dst_last_line = tmp;
   1.328 ++				tmp = src_beg_line;
   1.329 ++				src_beg_line = dest_beg_line;
   1.330 ++				dest_beg_line = tmp;
   1.331 ++			}
   1.332 ++#else
   1.333 ++
   1.334 ++			if ((sscanf(patch_line, "@@ -%d,%d +%d", &src_beg_line, &src_last_line, &dest_beg_line) != 3) &&
   1.335 ++				(sscanf(patch_line, "@@ -%d +%d", &src_beg_line, &dest_beg_line) != 2)) {
   1.336 ++				/* No more hunks for this file */
   1.337 ++				break;
   1.338 ++			}
   1.339 ++#endif
   1.340   			hunk_count++;
   1.341   
   1.342   			if (src_beg_line && dest_beg_line) {
   1.343   				/* Copy unmodified lines upto start of hunk */
   1.344 - 				/* src_beg_line will be 0 if its a new file */
   1.345 +-				/* src_beg_line will be 0 if its a new file */
   1.346 ++				/* src_beg_line will be 0 if it's a new file */
   1.347   				count = src_beg_line - src_cur_line;
   1.348  -				if (copy_lines(src_stream, dst_stream, count) != count) {
   1.349  +				if (copy_lines(src_stream, dst_stream, count)) {
   1.350 @@ -167,11 +282,18 @@
   1.351   				copy_trailing_lines_flag = 1;
   1.352   			}
   1.353  -			hunk_offset_start = src_cur_line;
   1.354 +-
   1.355 +-			while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
   1.356 +-				if ((*patch_line == '-') || (*patch_line == ' ')) {
   1.357  +			src_last_line += hunk_offset_start = src_cur_line;
   1.358 - 
   1.359 --			while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
   1.360 -+			while (free(patch_line), (patch_line = xmalloc_fgets(patch_file)) != NULL) {
   1.361 - 				if ((*patch_line == '-') || (*patch_line == ' ')) {
   1.362 ++#if ENABLE_FEATURE_PATCH_REVERSE
   1.363 ++			dst_last_line += dest_cur_line;
   1.364 ++#endif
   1.365 ++			while (1) {
   1.366 ++				free(patch_line);
   1.367 ++			        patch_line = xmalloc_fgets(patch_file);
   1.368 ++				if (patch_line == NULL) break;
   1.369 ++				if ((*patch_line == minus) || (*patch_line == ' ')) {
   1.370   					char *src_line = NULL;
   1.371  +					if (src_cur_line == src_last_line) break;
   1.372   					if (src_stream) {
   1.373 @@ -184,29 +306,107 @@
   1.374  +							int diff = strcmp(src_line, patch_line + 1);
   1.375   							src_cur_line++;
   1.376  +							free(src_line);
   1.377 -+							if (diff) {
   1.378 -+								src_line = NULL;
   1.379 -+							}
   1.380 ++							if (diff) src_line = NULL;
   1.381   						}
   1.382  -						if (strcmp(src_line, patch_line + 1) != 0) {
   1.383 -+						if (!src_line) {
   1.384 - 							bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
   1.385 - 							hunk_error++;
   1.386 +-							bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
   1.387 +-							hunk_error++;
   1.388  -							free(patch_line);
   1.389  -							/* Probably need to find next hunk, etc... */
   1.390  -							/* but for now we just bail out */
   1.391  -							patch_line = NULL;
   1.392 - 							break;
   1.393 - 						}
   1.394 +-							break;
   1.395 +-						}
   1.396  -						free(src_line);
   1.397   					}
   1.398 - 					if (*patch_line == ' ') {
   1.399 - 						fputs(patch_line + 1, dst_stream);
   1.400 -@@ -227,7 +220,6 @@
   1.401 - 				} else {
   1.402 +-					if (*patch_line == ' ') {
   1.403 +-						fputs(patch_line + 1, dst_stream);
   1.404 +-						dest_cur_line++;
   1.405 ++					if (!src_line) {
   1.406 ++						bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start);
   1.407 ++						bad_hunk_count++;
   1.408 ++						break;
   1.409 + 					}
   1.410 +-				} else if (*patch_line == '+') {
   1.411 +-					fputs(patch_line + 1, dst_stream);
   1.412 +-					dest_cur_line++;
   1.413 +-				} else {
   1.414 ++					if (*patch_line != ' ') {
   1.415 ++						continue;
   1.416 ++					}
   1.417 ++				} else if (*patch_line != plus) {
   1.418   					break;
   1.419   				}
   1.420  -				free(patch_line);
   1.421 +-			}
   1.422 +-			if (hunk_error) {
   1.423 +-				bad_hunk_count++;
   1.424 +-			}
   1.425 +-		}
   1.426 ++#if ENABLE_FEATURE_PATCH_REVERSE
   1.427 ++				if (dest_cur_line == dst_last_line) break;
   1.428 ++#endif
   1.429 ++				fputs(patch_line + 1, dst_stream);
   1.430 ++				dest_cur_line++;
   1.431 ++			} /* end of while loop handling one hunk */
   1.432 ++		} /* end of while loop handling one file */
   1.433 + 
   1.434 + 		/* Cleanup last patched file */
   1.435 + 		if (copy_trailing_lines_flag) {
   1.436 +-			copy_lines(src_stream, dst_stream, -1);
   1.437 ++			copy_lines(src_stream, dst_stream, (unsigned)(-1));
   1.438 + 		}
   1.439 + 		if (src_stream) {
   1.440 + 			fclose(src_stream);
   1.441 + 		}
   1.442 +-		if (dst_stream) {
   1.443 +-			fclose(dst_stream);
   1.444 +-		}
   1.445 ++		fclose(dst_stream);
   1.446 + 		if (bad_hunk_count) {
   1.447 +-			if (!ret) {
   1.448 +-				ret = 1;
   1.449 +-			}
   1.450 +-			bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count);
   1.451 ++			ret = 1;
   1.452 ++			bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count);
   1.453 + 		} else {
   1.454 + 			/* It worked, we can remove the backup */
   1.455 + 			if (backup_filename) {
   1.456 + 				unlink(backup_filename);
   1.457 ++				free(backup_filename);
   1.458   			}
   1.459 - 			if (hunk_error) {
   1.460 - 				bad_hunk_count++;
   1.461 + 			if ((dest_cur_line == 0) || (dest_beg_line == 0)) {
   1.462 + 				/* The new patched file is empty, remove it */
   1.463 + 				xunlink(new_filename);
   1.464 +-				if (strcmp(new_filename, original_filename) != 0)
   1.465 +-					xunlink(original_filename);
   1.466 ++				/* original_filename and new_filename may be the same file */
   1.467 ++				unlink(original_filename);
   1.468 + 			}
   1.469 + 		}
   1.470 +-	}
   1.471 ++	} /* end of "while there are patch lines" */
   1.472 ++quit:
   1.473 + 
   1.474 + 	/* 0 = SUCCESS
   1.475 + 	 * 1 = Some hunks failed
   1.476 +-	 * 2 = More serious problems
   1.477 ++	 * 2 = More serious problems (exited earlier)
   1.478 + 	 */
   1.479 + 	return ret;
   1.480 + }
   1.481 +
   1.482 +--- busybox-1.10.0/include/usage.h	2008-03-24 16:20:43.000000000 +0100
   1.483 ++++ busybox-1.10.0/include/usage.h	2008-03-24 16:22:06.000000000 +0100
   1.484 +@@ -2833,8 +2833,9 @@
   1.485 + 	)
   1.486 + 
   1.487 + #define patch_trivial_usage \
   1.488 +-       "[-p NUM] [-i DIFF]"
   1.489 ++       "[-R] [-p NUM] [-i DIFF]"
   1.490 + #define patch_full_usage \
   1.491 ++       "	-R    	Reverse patch\n" \
   1.492 +        "	-p NUM	Strip NUM leading components from file names" \
   1.493 +      "\n	-i DIFF	Read DIFF instead of stdin" \
   1.494 +