rev |
line source |
pascal@287
|
1 --- busybox-1.7.3/editors/patch.c
|
pascal@287
|
2 +++ busybox-1.7.3/editors/patch.c
|
pascal@287
|
3 @@ -23,11 +23,9 @@
|
pascal@287
|
4
|
pascal@287
|
5 #include "libbb.h"
|
pascal@287
|
6
|
pascal@287
|
7 -static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, const unsigned int lines_count)
|
pascal@287
|
8 +static unsigned int copy_lines(FILE *src_stream, FILE *dest_stream, unsigned int lines_count)
|
pascal@287
|
9 {
|
pascal@287
|
10 - unsigned int i = 0;
|
pascal@287
|
11 -
|
pascal@287
|
12 - while (src_stream && (i < lines_count)) {
|
pascal@287
|
13 + while (src_stream && lines_count) {
|
pascal@287
|
14 char *line;
|
pascal@287
|
15 line = xmalloc_fgets(src_stream);
|
pascal@287
|
16 if (line == NULL) {
|
pascal@287
|
17 @@ -37,10 +35,9 @@
|
pascal@287
|
18 bb_perror_msg_and_die("error writing to new file");
|
pascal@287
|
19 }
|
pascal@287
|
20 free(line);
|
pascal@287
|
21 -
|
pascal@287
|
22 - i++;
|
pascal@287
|
23 + lines_count--;
|
pascal@287
|
24 }
|
pascal@287
|
25 - return i;
|
pascal@287
|
26 + return lines_count;
|
pascal@287
|
27 }
|
pascal@287
|
28
|
pascal@287
|
29 /* If patch_level is -1 it will remove all directory names
|
pascal@287
|
30 @@ -49,26 +46,24 @@
|
pascal@287
|
31 * returns malloc'ed filename
|
pascal@287
|
32 */
|
pascal@287
|
33
|
pascal@287
|
34 -static char *extract_filename(char *line, int patch_level)
|
pascal@287
|
35 +static char *extract_filename(char *line, unsigned int patch_level)
|
pascal@287
|
36 {
|
pascal@287
|
37 char *temp, *filename_start_ptr = line + 4;
|
pascal@287
|
38 - int i;
|
pascal@287
|
39
|
pascal@287
|
40 /* Terminate string at end of source filename */
|
pascal@287
|
41 - temp = strchrnul(filename_start_ptr, '\t');
|
pascal@287
|
42 - *temp = '\0';
|
pascal@287
|
43 + line[strcspn(line,"\t\n")] = '\0';
|
pascal@287
|
44
|
pascal@287
|
45 /* Skip over (patch_level) number of leading directories */
|
pascal@287
|
46 - if (patch_level == -1)
|
pascal@287
|
47 - patch_level = INT_MAX;
|
pascal@287
|
48 - for (i = 0; i < patch_level; i++) {
|
pascal@287
|
49 + while (patch_level--) {
|
pascal@287
|
50 temp = strchr(filename_start_ptr, '/');
|
pascal@287
|
51 if (!temp)
|
pascal@287
|
52 break;
|
pascal@287
|
53 filename_start_ptr = temp + 1;
|
pascal@287
|
54 }
|
pascal@287
|
55
|
pascal@287
|
56 - return xstrdup(filename_start_ptr);
|
pascal@287
|
57 + temp = xstrdup(filename_start_ptr);
|
pascal@287
|
58 + free(line);
|
pascal@287
|
59 + return temp;
|
pascal@287
|
60 }
|
pascal@287
|
61
|
pascal@287
|
62 static int file_doesnt_exist(const char *filename)
|
pascal@287
|
63 @@ -82,22 +77,19 @@
|
pascal@287
|
64 {
|
pascal@287
|
65 int patch_level = -1;
|
pascal@287
|
66 char *patch_line;
|
pascal@287
|
67 - int ret;
|
pascal@287
|
68 - FILE *patch_file = NULL;
|
pascal@287
|
69 + FILE *patch_file = stdin;
|
pascal@287
|
70
|
pascal@287
|
71 {
|
pascal@287
|
72 char *p, *i;
|
pascal@287
|
73 - ret = getopt32(argv, "p:i:", &p, &i);
|
pascal@287
|
74 + int ret = getopt32(argv, "p:i:", &p, &i);
|
pascal@287
|
75 if (ret & 1)
|
pascal@287
|
76 patch_level = xatol_range(p, -1, USHRT_MAX);
|
pascal@287
|
77 if (ret & 2) {
|
pascal@287
|
78 patch_file = xfopen(i, "r");
|
pascal@287
|
79 - } else {
|
pascal@287
|
80 - patch_file = stdin;
|
pascal@287
|
81 }
|
pascal@287
|
82 - ret = 0;
|
pascal@287
|
83 }
|
pascal@287
|
84
|
pascal@287
|
85 + xfunc_error_retval = 2;
|
pascal@287
|
86 patch_line = xmalloc_getline(patch_file);
|
pascal@287
|
87 while (patch_line) {
|
pascal@287
|
88 FILE *src_stream;
|
pascal@287
|
89 @@ -122,18 +114,14 @@
|
pascal@287
|
90 /* FIXME: patch_line NULL check?? */
|
pascal@287
|
91
|
pascal@287
|
92 /* Extract the filename used before the patch was generated */
|
pascal@287
|
93 - original_filename = extract_filename(patch_line, patch_level);
|
pascal@287
|
94 - free(patch_line);
|
pascal@287
|
95 + original_filename = extract_filename(patch_line, (unsigned int) patch_level);
|
pascal@287
|
96
|
pascal@287
|
97 patch_line = xmalloc_getline(patch_file);
|
pascal@287
|
98 /* FIXME: NULL check?? */
|
pascal@287
|
99 if (strncmp(patch_line, "+++ ", 4) != 0) {
|
pascal@287
|
100 - ret = 2;
|
pascal@287
|
101 - bb_error_msg("invalid patch");
|
pascal@287
|
102 - continue;
|
pascal@287
|
103 + bb_error_msg_and_die("invalid patch: %s\n",patch_line);
|
pascal@287
|
104 }
|
pascal@287
|
105 - new_filename = extract_filename(patch_line, patch_level);
|
pascal@287
|
106 - free(patch_line);
|
pascal@287
|
107 + new_filename = extract_filename(patch_line, (unsigned int) patch_level);
|
pascal@287
|
108
|
pascal@287
|
109 if (file_doesnt_exist(new_filename)) {
|
pascal@287
|
110 char *line_ptr;
|
pascal@287
|
111 @@ -144,7 +132,6 @@
|
pascal@287
|
112 bb_make_directory(new_filename, -1, FILEUTILS_RECUR);
|
pascal@287
|
113 *line_ptr = '/';
|
pascal@287
|
114 }
|
pascal@287
|
115 - dst_stream = xfopen(new_filename, "w+");
|
pascal@287
|
116 backup_filename = NULL;
|
pascal@287
|
117 } else {
|
pascal@287
|
118 backup_filename = xmalloc(strlen(new_filename) + 6);
|
pascal@287
|
119 @@ -154,12 +141,11 @@
|
pascal@287
|
120 bb_perror_msg_and_die("cannot create file %s",
|
pascal@287
|
121 backup_filename);
|
pascal@287
|
122 }
|
pascal@287
|
123 - dst_stream = xfopen(new_filename, "w");
|
pascal@287
|
124 }
|
pascal@287
|
125
|
pascal@287
|
126 - if ((backup_filename == NULL) || file_doesnt_exist(original_filename)) {
|
pascal@287
|
127 - src_stream = NULL;
|
pascal@287
|
128 - } else {
|
pascal@287
|
129 + dst_stream = xfopen(new_filename, "w");
|
pascal@287
|
130 + src_stream = NULL;
|
pascal@338
|
131 + if (!file_doesnt_exist(original_filename) && backup_filename) {
|
pascal@287
|
132 if (strcmp(original_filename, new_filename) == 0) {
|
pascal@287
|
133 src_stream = xfopen(backup_filename, "r");
|
pascal@287
|
134 } else {
|
pascal@287
|
135 @@ -174,54 +160,59 @@
|
pascal@287
|
136 while (patch_line) {
|
pascal@287
|
137 unsigned int count;
|
pascal@287
|
138 unsigned int src_beg_line;
|
pascal@287
|
139 + unsigned int src_last_line = 1;
|
pascal@287
|
140 unsigned int unused;
|
pascal@287
|
141 unsigned int hunk_offset_start = 0;
|
pascal@287
|
142 - int hunk_error = 0;
|
pascal@287
|
143
|
pascal@287
|
144 /* This bit should be improved */
|
pascal@287
|
145 - if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line, &unused, &dest_beg_line, &unused) != 4) &&
|
pascal@287
|
146 - (sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line, &unused, &dest_beg_line) != 3) &&
|
pascal@287
|
147 - (sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line, &dest_beg_line, &unused) != 3)) {
|
pascal@287
|
148 + if ((sscanf(patch_line, "@@ -%d,%d +%d,%d @@", &src_beg_line,
|
pascal@287
|
149 + &src_last_line, &dest_beg_line, &unused) != 4) &&
|
pascal@287
|
150 + (sscanf(patch_line, "@@ -%d,%d +%d @@", &src_beg_line,
|
pascal@287
|
151 + &src_last_line, &dest_beg_line) != 3) &&
|
pascal@287
|
152 + (sscanf(patch_line, "@@ -%d +%d,%d @@", &src_beg_line,
|
pascal@287
|
153 + &dest_beg_line, &unused) != 3) &&
|
pascal@287
|
154 + (sscanf(patch_line, "@@ -%d +%d @@", &src_beg_line,
|
pascal@287
|
155 + &dest_beg_line) != 2)) {
|
pascal@287
|
156 /* No more hunks for this file */
|
pascal@287
|
157 break;
|
pascal@287
|
158 }
|
pascal@287
|
159 - free(patch_line);
|
pascal@287
|
160 hunk_count++;
|
pascal@287
|
161
|
pascal@287
|
162 if (src_beg_line && dest_beg_line) {
|
pascal@287
|
163 /* Copy unmodified lines upto start of hunk */
|
pascal@287
|
164 /* src_beg_line will be 0 if its a new file */
|
pascal@287
|
165 count = src_beg_line - src_cur_line;
|
pascal@287
|
166 - if (copy_lines(src_stream, dst_stream, count) != count) {
|
pascal@287
|
167 + if (copy_lines(src_stream, dst_stream, count)) {
|
pascal@287
|
168 bb_error_msg_and_die("bad src file");
|
pascal@287
|
169 }
|
pascal@287
|
170 src_cur_line += count;
|
pascal@287
|
171 dest_cur_line += count;
|
pascal@287
|
172 copy_trailing_lines_flag = 1;
|
pascal@287
|
173 }
|
pascal@287
|
174 - hunk_offset_start = src_cur_line;
|
pascal@287
|
175 + src_last_line += hunk_offset_start = src_cur_line;
|
pascal@287
|
176
|
pascal@287
|
177 - while ((patch_line = xmalloc_fgets(patch_file)) != NULL) {
|
pascal@287
|
178 + for (free(patch_line);
|
pascal@287
|
179 + (patch_line = xmalloc_fgets(patch_file)) != NULL;
|
pascal@287
|
180 + free(patch_line)) {
|
pascal@287
|
181 if ((*patch_line == '-') || (*patch_line == ' ')) {
|
pascal@287
|
182 char *src_line = NULL;
|
pascal@287
|
183 + if (src_cur_line == src_last_line) break;
|
pascal@287
|
184 if (src_stream) {
|
pascal@287
|
185 src_line = xmalloc_fgets(src_stream);
|
pascal@287
|
186 - if (!src_line) {
|
pascal@287
|
187 - hunk_error++;
|
pascal@287
|
188 - break;
|
pascal@287
|
189 - } else {
|
pascal@287
|
190 + if (src_line) {
|
pascal@287
|
191 + int diff = strcmp(src_line, patch_line + 1);
|
pascal@287
|
192 src_cur_line++;
|
pascal@287
|
193 + free(src_line);
|
pascal@287
|
194 + if (diff) {
|
pascal@287
|
195 + src_line = NULL;
|
pascal@287
|
196 + }
|
pascal@287
|
197 }
|
pascal@287
|
198 - if (strcmp(src_line, patch_line + 1) != 0) {
|
pascal@287
|
199 - bb_error_msg("hunk #%d FAILED at %d", hunk_count, hunk_offset_start);
|
pascal@287
|
200 - hunk_error++;
|
pascal@287
|
201 - free(patch_line);
|
pascal@287
|
202 - /* Probably need to find next hunk, etc... */
|
pascal@287
|
203 - /* but for now we just bail out */
|
pascal@287
|
204 - patch_line = NULL;
|
pascal@287
|
205 + if (!src_line) {
|
pascal@287
|
206 + bb_error_msg("hunk #%d FAILED at %d",
|
pascal@287
|
207 + hunk_count, hunk_offset_start);
|
pascal@287
|
208 + bad_hunk_count++;
|
pascal@287
|
209 break;
|
pascal@287
|
210 }
|
pascal@287
|
211 - free(src_line);
|
pascal@287
|
212 }
|
pascal@287
|
213 if (*patch_line == ' ') {
|
pascal@287
|
214 fputs(patch_line + 1, dst_stream);
|
pascal@287
|
215 @@ -233,16 +224,12 @@
|
pascal@287
|
216 } else {
|
pascal@287
|
217 break;
|
pascal@287
|
218 }
|
pascal@287
|
219 - free(patch_line);
|
pascal@287
|
220 - }
|
pascal@287
|
221 - if (hunk_error) {
|
pascal@287
|
222 - bad_hunk_count++;
|
pascal@287
|
223 }
|
pascal@287
|
224 }
|
pascal@287
|
225
|
pascal@287
|
226 /* Cleanup last patched file */
|
pascal@287
|
227 if (copy_trailing_lines_flag) {
|
pascal@287
|
228 - copy_lines(src_stream, dst_stream, -1);
|
pascal@287
|
229 + copy_lines(src_stream, dst_stream, (unsigned int) -1);
|
pascal@287
|
230 }
|
pascal@287
|
231 if (src_stream) {
|
pascal@287
|
232 fclose(src_stream);
|
pascal@287
|
233 @@ -251,16 +238,14 @@
|
pascal@287
|
234 fclose(dst_stream);
|
pascal@287
|
235 }
|
pascal@287
|
236 if (bad_hunk_count) {
|
pascal@287
|
237 - if (!ret) {
|
pascal@287
|
238 - ret = 1;
|
pascal@287
|
239 - }
|
pascal@287
|
240 bb_error_msg("%d out of %d hunk FAILED", bad_hunk_count, hunk_count);
|
pascal@287
|
241 + return 1;
|
pascal@287
|
242 } else {
|
pascal@287
|
243 /* It worked, we can remove the backup */
|
pascal@287
|
244 if (backup_filename) {
|
pascal@287
|
245 unlink(backup_filename);
|
pascal@287
|
246 }
|
pascal@287
|
247 - if ((dest_cur_line == 0) || (dest_beg_line == 0)) {
|
pascal@287
|
248 + if (dest_cur_line == 0) {
|
pascal@287
|
249 /* The new patched file is empty, remove it */
|
pascal@287
|
250 xunlink(new_filename);
|
pascal@287
|
251 if (strcmp(new_filename, original_filename) != 0)
|
pascal@287
|
252 @@ -273,5 +258,5 @@
|
pascal@287
|
253 * 1 = Some hunks failed
|
pascal@287
|
254 * 2 = More serious problems
|
pascal@287
|
255 */
|
pascal@287
|
256 - return ret;
|
pascal@287
|
257 + return 0;
|
pascal@287
|
258 }
|