diff options
author | Rob Landley <rob@landley.net> | 2010-08-13 15:50:26 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-08-13 15:50:26 +0200 |
commit | 1bbc0cd7f293aac5e15d6c1e16bee9f1484c6fbf (patch) | |
tree | a2a5ba8d9508982f80b702a99c2e10d1644ae40e /editors/patch_toybox.c | |
parent | dcaed97e0f44d0cd285fb590ec6ec80d0d73e738 (diff) | |
download | busybox-w32-1bbc0cd7f293aac5e15d6c1e16bee9f1484c6fbf.tar.gz busybox-w32-1bbc0cd7f293aac5e15d6c1e16bee9f1484c6fbf.tar.bz2 busybox-w32-1bbc0cd7f293aac5e15d6c1e16bee9f1484c6fbf.zip |
patch: replace it with toybox's implementation
Signed-off-by: Rob Landley <rob@landley.net>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'editors/patch_toybox.c')
-rw-r--r-- | editors/patch_toybox.c | 164 |
1 files changed, 98 insertions, 66 deletions
diff --git a/editors/patch_toybox.c b/editors/patch_toybox.c index 0e5c070e2..7f3234e66 100644 --- a/editors/patch_toybox.c +++ b/editors/patch_toybox.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* Adapted from toybox's patch. Currently unused */ | 1 | /* Adapted from toybox's patch. */ |
2 | 2 | ||
3 | /* vi: set sw=4 ts=4: | 3 | /* vi: set sw=4 ts=4: |
4 | * | 4 | * |
@@ -23,7 +23,7 @@ | |||
23 | * -F fuzz (number, default 2) | 23 | * -F fuzz (number, default 2) |
24 | * [file] which file to patch | 24 | * [file] which file to patch |
25 | 25 | ||
26 | USE_PATCH(NEWTOY(patch, "up#i:R", TOYFLAG_USR|TOYFLAG_BIN)) | 26 | USE_PATCH(NEWTOY(patch, USE_TOYBOX_DEBUG("x")"up#i:R", TOYFLAG_USR|TOYFLAG_BIN)) |
27 | 27 | ||
28 | config PATCH | 28 | config PATCH |
29 | bool "patch" | 29 | bool "patch" |
@@ -223,15 +223,16 @@ void delete_tempfile(int fdin, int fdout, char **tempname) | |||
223 | 223 | ||
224 | 224 | ||
225 | struct globals { | 225 | struct globals { |
226 | struct double_list *plines; | 226 | char *infile; |
227 | long linenum; | 227 | long prefix; |
228 | int context; | 228 | |
229 | int hunknum; | 229 | struct double_list *current_hunk; |
230 | int filein; | 230 | long oldline, oldlen, newline, newlen, linenum; |
231 | int fileout; | 231 | int context, state, filein, fileout, filepatch, hunknum; |
232 | int state; | ||
233 | char *tempname; | 232 | char *tempname; |
234 | smallint exitval; | 233 | |
234 | // was toys.foo: | ||
235 | int exitval; | ||
235 | }; | 236 | }; |
236 | #define TT (*ptr_to_globals) | 237 | #define TT (*ptr_to_globals) |
237 | #define INIT_TT() do { \ | 238 | #define INIT_TT() do { \ |
@@ -240,12 +241,14 @@ struct globals { | |||
240 | 241 | ||
241 | 242 | ||
242 | //bbox had: "p:i:RN" | 243 | //bbox had: "p:i:RN" |
243 | #define FLAG_STR "Rup:i:" | 244 | #define FLAG_STR "Rup:i:x" |
244 | /* FLAG_REVERSE must be == 1! Code uses this fact. */ | 245 | /* FLAG_REVERSE must be == 1! Code uses this fact. */ |
245 | #define FLAG_REVERSE (1 << 0) | 246 | #define FLAG_REVERSE (1 << 0) |
246 | #define FLAG_u (1 << 1) | 247 | #define FLAG_u (1 << 1) |
247 | #define FLAG_PATHLEN (1 << 2) | 248 | #define FLAG_PATHLEN (1 << 2) |
248 | #define FLAG_INPUT (1 << 3) | 249 | #define FLAG_INPUT (1 << 3) |
250 | //non-standard: | ||
251 | #define FLAG_DEBUG (1 << 4) | ||
249 | 252 | ||
250 | // Dispose of a line of input, either by writing it out or discarding it. | 253 | // Dispose of a line of input, either by writing it out or discarding it. |
251 | 254 | ||
@@ -254,6 +257,8 @@ struct globals { | |||
254 | // state = 3: write whole line to fileout | 257 | // state = 3: write whole line to fileout |
255 | // state > 3: write line+1 to fileout when *line != state | 258 | // state > 3: write line+1 to fileout when *line != state |
256 | 259 | ||
260 | #define PATCH_DEBUG (option_mask32 & FLAG_DEBUG) | ||
261 | |||
257 | static void do_line(void *data) | 262 | static void do_line(void *data) |
258 | { | 263 | { |
259 | struct double_list *dlist = (struct double_list *)data; | 264 | struct double_list *dlist = (struct double_list *)data; |
@@ -262,6 +267,8 @@ static void do_line(void *data) | |||
262 | fdprintf(TT.state == 2 ? 2 : TT.fileout, | 267 | fdprintf(TT.state == 2 ? 2 : TT.fileout, |
263 | "%s\n", dlist->data+(TT.state>3 ? 1 : 0)); | 268 | "%s\n", dlist->data+(TT.state>3 ? 1 : 0)); |
264 | 269 | ||
270 | if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); | ||
271 | |||
265 | free(dlist->data); | 272 | free(dlist->data); |
266 | free(data); | 273 | free(data); |
267 | } | 274 | } |
@@ -274,94 +281,118 @@ static void finish_oldfile(void) | |||
274 | 281 | ||
275 | static void fail_hunk(void) | 282 | static void fail_hunk(void) |
276 | { | 283 | { |
277 | if (!TT.plines) return; | 284 | if (!TT.current_hunk) return; |
278 | TT.plines->prev->next = 0; | 285 | TT.current_hunk->prev->next = 0; |
279 | 286 | ||
280 | fdprintf(2, "Hunk %d FAILED.\n", TT.hunknum); | 287 | fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", TT.hunknum, TT.oldline, TT.newline); |
281 | TT.exitval = 1; | 288 | TT.exitval = 1; |
282 | 289 | ||
283 | // If we got to this point, we've seeked to the end. Discard changes to | 290 | // If we got to this point, we've seeked to the end. Discard changes to |
284 | // this file and advance to next file. | 291 | // this file and advance to next file. |
285 | 292 | ||
286 | TT.state = 2; | 293 | TT.state = 2; |
287 | TOY_llist_free(TT.plines, do_line); | 294 | TOY_llist_free(TT.current_hunk, do_line); |
288 | TT.plines = NULL; | 295 | TT.current_hunk = NULL; |
289 | delete_tempfile(TT.filein, TT.fileout, &TT.tempname); | 296 | delete_tempfile(TT.filein, TT.fileout, &TT.tempname); |
290 | TT.state = 0; | 297 | TT.state = 0; |
291 | } | 298 | } |
292 | 299 | ||
293 | static int apply_hunk(void) | 300 | // Given a hunk of a unified diff, make the appropriate change to the file. |
301 | // This does not use the location information, but instead treats a hunk | ||
302 | // as a sort of regex. Copies data from input to output until it finds | ||
303 | // the change to be made, then outputs the changed data and returns. | ||
304 | // (Finding EOF first is an error.) This is a single pass operation, so | ||
305 | // multiple hunks must occur in order in the file. | ||
306 | |||
307 | static int apply_one_hunk(void) | ||
294 | { | 308 | { |
295 | struct double_list *plist, *buf = NULL, *check; | 309 | struct double_list *plist, *buf = NULL, *check; |
296 | int i = 0, backwards = 0, matcheof = 0, | 310 | int matcheof = 0, reverse = option_mask32 & FLAG_REVERSE, backwarn = 0; |
297 | reverse = option_mask32 & FLAG_REVERSE; | ||
298 | 311 | ||
299 | // Break doubly linked list so we can use singly linked traversal function. | 312 | // Break doubly linked list so we can use singly linked traversal function. |
300 | TT.plines->prev->next = NULL; | 313 | TT.current_hunk->prev->next = NULL; |
301 | 314 | ||
302 | // Match EOF if there aren't as many ending context lines as beginning | 315 | // Match EOF if there aren't as many ending context lines as beginning |
303 | for (plist = TT.plines; plist; plist = plist->next) { | 316 | for (plist = TT.current_hunk; plist; plist = plist->next) { |
304 | if (plist->data[0]==' ') i++; | 317 | if (plist->data[0]==' ') matcheof++; |
305 | else i = 0; | 318 | else matcheof = 0; |
319 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); | ||
306 | } | 320 | } |
307 | if (i < TT.context) matcheof++; | 321 | matcheof = matcheof < TT.context; |
308 | 322 | ||
309 | // Search for a place to apply this hunk. Match all context lines and | 323 | if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); |
310 | // lines to be removed. | ||
311 | plist = TT.plines; | ||
312 | buf = NULL; | ||
313 | i = 0; | ||
314 | 324 | ||
315 | // Start of for loop | 325 | // Loop through input data searching for this hunk. Match all context |
326 | // lines and all lines to be removed until we've found the end of a | ||
327 | // complete hunk. | ||
328 | plist = TT.current_hunk; | ||
329 | buf = NULL; | ||
316 | if (TT.context) for (;;) { | 330 | if (TT.context) for (;;) { |
317 | char *data = get_line(TT.filein); | 331 | char *data = get_line(TT.filein); |
318 | 332 | ||
319 | TT.linenum++; | 333 | TT.linenum++; |
320 | 334 | ||
321 | // Skip lines of the hunk we'd be adding. | 335 | // Figure out which line of hunk to compare with next. (Skip lines |
336 | // of the hunk we'd be adding.) | ||
322 | while (plist && *plist->data == "+-"[reverse]) { | 337 | while (plist && *plist->data == "+-"[reverse]) { |
323 | if (data && !strcmp(data, plist->data+1)) { | 338 | if (data && !strcmp(data, plist->data+1)) { |
324 | if (++backwards == TT.context) | 339 | if (!backwarn) { |
325 | fdprintf(2,"Possibly reversed hunk %d at %ld\n", | 340 | fdprintf(2,"Possibly reversed hunk %d at %ld\n", |
326 | TT.hunknum, TT.linenum); | 341 | TT.hunknum, TT.linenum); |
327 | } else backwards=0; | 342 | backwarn++; |
343 | } | ||
344 | } | ||
328 | plist = plist->next; | 345 | plist = plist->next; |
329 | } | 346 | } |
330 | 347 | ||
331 | // Is this EOF? | 348 | // Is this EOF? |
332 | if (!data) { | 349 | if (!data) { |
350 | if (PATCH_DEBUG) fdprintf(2, "INEOF\n"); | ||
351 | |||
333 | // Does this hunk need to match EOF? | 352 | // Does this hunk need to match EOF? |
334 | if (!plist && matcheof) break; | 353 | if (!plist && matcheof) break; |
335 | 354 | ||
336 | // File ended before we found a place for this hunk. | 355 | // File ended before we found a place for this hunk. |
337 | fail_hunk(); | 356 | fail_hunk(); |
338 | goto done; | 357 | goto done; |
339 | } | 358 | } else if (PATCH_DEBUG) fdprintf(2, "IN: %s\n", data); |
340 | check = dlist_add(&buf, data); | 359 | check = dlist_add(&buf, data); |
341 | 360 | ||
361 | // Compare this line with next expected line of hunk. | ||
342 | // todo: teach the strcmp() to ignore whitespace. | 362 | // todo: teach the strcmp() to ignore whitespace. |
343 | 363 | ||
344 | for (;;) { | 364 | // A match can fail because the next line doesn't match, or because |
345 | // If we hit the end of a hunk that needed EOF and this isn't EOF, | 365 | // we hit the end of a hunk that needed EOF, and this isn't EOF. |
346 | // or next line doesn't match, flush first line of buffered data and | 366 | |
347 | // recheck match until we find a new match or run out of buffer. | 367 | // If match failed, flush first line of buffered data and |
368 | // recheck buffered data for a new match until we find one or run | ||
369 | // out of buffer. | ||
348 | 370 | ||
371 | for (;;) { | ||
349 | if (!plist || strcmp(check->data, plist->data+1)) { | 372 | if (!plist || strcmp(check->data, plist->data+1)) { |
350 | // First line isn't a match, write it out. | 373 | // Match failed. Write out first line of buffered data and |
374 | // recheck remaining buffered data for a new match. | ||
375 | |||
376 | if (PATCH_DEBUG) | ||
377 | fdprintf(2, "NOT: %s\n", plist->data); | ||
378 | |||
351 | TT.state = 3; | 379 | TT.state = 3; |
352 | check = TOY_llist_pop(&buf); | 380 | check = TOY_llist_pop(&buf); |
353 | check->prev->next = buf; | 381 | check->prev->next = buf; |
354 | buf->prev = check->prev; | 382 | buf->prev = check->prev; |
355 | do_line(check); | 383 | do_line(check); |
356 | plist = TT.plines; | 384 | plist = TT.current_hunk; |
357 | 385 | ||
358 | // Out of buffered lines? | 386 | // If we've reached the end of the buffer without confirming a |
387 | // match, read more lines. | ||
359 | if (check==buf) { | 388 | if (check==buf) { |
360 | buf = 0; | 389 | buf = 0; |
361 | break; | 390 | break; |
362 | } | 391 | } |
363 | check = buf; | 392 | check = buf; |
364 | } else { | 393 | } else { |
394 | if (PATCH_DEBUG) | ||
395 | fdprintf(2, "MAYBE: %s\n", plist->data); | ||
365 | // This line matches. Advance plist, detect successful match. | 396 | // This line matches. Advance plist, detect successful match. |
366 | plist = plist->next; | 397 | plist = plist->next; |
367 | if (!plist && !matcheof) goto out; | 398 | if (!plist && !matcheof) goto out; |
@@ -371,10 +402,10 @@ static int apply_hunk(void) | |||
371 | } | 402 | } |
372 | } | 403 | } |
373 | out: | 404 | out: |
374 | // Got it. Emit changed data. | 405 | // We have a match. Emit changed data. |
375 | TT.state = "-+"[reverse]; | 406 | TT.state = "-+"[reverse]; |
376 | TOY_llist_free(TT.plines, do_line); | 407 | TOY_llist_free(TT.current_hunk, do_line); |
377 | TT.plines = NULL; | 408 | TT.current_hunk = NULL; |
378 | TT.state = 1; | 409 | TT.state = 1; |
379 | done: | 410 | done: |
380 | if (buf) { | 411 | if (buf) { |
@@ -385,6 +416,9 @@ done: | |||
385 | return TT.state; | 416 | return TT.state; |
386 | } | 417 | } |
387 | 418 | ||
419 | // Read a patch file and find hunks, opening/creating/deleting files. | ||
420 | // Call apply_one_hunk() on each hunk. | ||
421 | |||
388 | // state 0: Not in a hunk, look for +++. | 422 | // state 0: Not in a hunk, look for +++. |
389 | // state 1: Found +++ file indicator, look for @@ | 423 | // state 1: Found +++ file indicator, look for @@ |
390 | // state 2: In hunk: counting initial context lines | 424 | // state 2: In hunk: counting initial context lines |
@@ -397,24 +431,20 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
397 | int reverse, state = 0; | 431 | int reverse, state = 0; |
398 | char *oldname = NULL, *newname = NULL; | 432 | char *oldname = NULL, *newname = NULL; |
399 | char *opt_p, *opt_i; | 433 | char *opt_p, *opt_i; |
400 | int prefix; | ||
401 | |||
402 | long oldline = 0, oldlen = 0, newline = 0, newlen = 0; | ||
403 | 434 | ||
404 | INIT_TT(); | 435 | INIT_TT(); |
405 | 436 | ||
406 | opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i); | 437 | opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i); |
407 | reverse = opts & FLAG_REVERSE; | 438 | reverse = opts & FLAG_REVERSE; |
408 | 439 | TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative! | |
409 | if (opts & FLAG_INPUT) xmove_fd(xopen(opt_i, O_RDONLY), STDIN_FILENO); | 440 | if (opts & FLAG_INPUT) TT.filepatch = xopen(opt_i, O_RDONLY); |
410 | prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative! | ||
411 | TT.filein = TT.fileout = -1; | 441 | TT.filein = TT.fileout = -1; |
412 | 442 | ||
413 | // Loop through the lines in the patch | 443 | // Loop through the lines in the patch |
414 | for(;;) { | 444 | for(;;) { |
415 | char *patchline; | 445 | char *patchline; |
416 | 446 | ||
417 | patchline = get_line(STDIN_FILENO); | 447 | patchline = get_line(TT.filepatch); |
418 | if (!patchline) break; | 448 | if (!patchline) break; |
419 | 449 | ||
420 | // Other versions of patch accept damaged patches, | 450 | // Other versions of patch accept damaged patches, |
@@ -427,17 +457,18 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
427 | // Are we assembling a hunk? | 457 | // Are we assembling a hunk? |
428 | if (state >= 2) { | 458 | if (state >= 2) { |
429 | if (*patchline==' ' || *patchline=='+' || *patchline=='-') { | 459 | if (*patchline==' ' || *patchline=='+' || *patchline=='-') { |
430 | dlist_add(&TT.plines, patchline); | 460 | dlist_add(&TT.current_hunk, patchline); |
431 | 461 | ||
432 | if (*patchline != '+') oldlen--; | 462 | if (*patchline != '+') TT.oldlen--; |
433 | if (*patchline != '-') newlen--; | 463 | if (*patchline != '-') TT.newlen--; |
434 | 464 | ||
435 | // Context line? | 465 | // Context line? |
436 | if (*patchline==' ' && state==2) TT.context++; | 466 | if (*patchline==' ' && state==2) TT.context++; |
437 | else state=3; | 467 | else state=3; |
438 | 468 | ||
439 | // If we've consumed all expected hunk lines, apply the hunk. | 469 | // If we've consumed all expected hunk lines, apply the hunk. |
440 | if (!oldlen && !newlen) state = apply_hunk(); | 470 | |
471 | if (!TT.oldlen && !TT.newlen) state = apply_one_hunk(); | ||
441 | continue; | 472 | continue; |
442 | } | 473 | } |
443 | fail_hunk(); | 474 | fail_hunk(); |
@@ -447,11 +478,11 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
447 | 478 | ||
448 | // Open a new file? | 479 | // Open a new file? |
449 | if (!strncmp("--- ", patchline, 4) || !strncmp("+++ ", patchline, 4)) { | 480 | if (!strncmp("--- ", patchline, 4) || !strncmp("+++ ", patchline, 4)) { |
450 | char *s, **name = &oldname; | 481 | char *s, **name = reverse ? &newname : &oldname; |
451 | int i; | 482 | int i; |
452 | 483 | ||
453 | if (*patchline == '+') { | 484 | if (*patchline == '+') { |
454 | name = &newname; | 485 | name = reverse ? &oldname : &newname; |
455 | state = 1; | 486 | state = 1; |
456 | } | 487 | } |
457 | 488 | ||
@@ -462,7 +493,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
462 | for (s = patchline+4; *s && *s!='\t'; s++) | 493 | for (s = patchline+4; *s && *s!='\t'; s++) |
463 | if (*s=='\\' && s[1]) s++; | 494 | if (*s=='\\' && s[1]) s++; |
464 | i = atoi(s); | 495 | i = atoi(s); |
465 | if (i && i<=1970) | 496 | if (i>1900 && i<=1970) |
466 | *name = xstrdup("/dev/null"); | 497 | *name = xstrdup("/dev/null"); |
467 | else { | 498 | else { |
468 | *s = 0; | 499 | *s = 0; |
@@ -478,8 +509,8 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
478 | } else if (state == 1 && !strncmp("@@ -", patchline, 4)) { | 509 | } else if (state == 1 && !strncmp("@@ -", patchline, 4)) { |
479 | int i; | 510 | int i; |
480 | 511 | ||
481 | i = sscanf(patchline+4, "%ld,%ld +%ld,%ld", | 512 | i = sscanf(patchline+4, "%ld,%ld +%ld,%ld", &TT.oldline, |
482 | &oldline, &oldlen, &newline, &newlen); | 513 | &TT.oldlen, &TT.newline, &TT.newlen); |
483 | if (i != 4) | 514 | if (i != 4) |
484 | bb_error_msg_and_die("corrupt hunk %d at %ld", TT.hunknum, TT.linenum); | 515 | bb_error_msg_and_die("corrupt hunk %d at %ld", TT.hunknum, TT.linenum); |
485 | 516 | ||
@@ -491,22 +522,22 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
491 | int oldsum, newsum, del = 0; | 522 | int oldsum, newsum, del = 0; |
492 | char *s, *name; | 523 | char *s, *name; |
493 | 524 | ||
494 | oldsum = oldline + oldlen; | 525 | oldsum = TT.oldline + TT.oldlen; |
495 | newsum = newline + newlen; | 526 | newsum = TT.newline + TT.newlen; |
496 | 527 | ||
497 | name = reverse ? oldname : newname; | 528 | name = reverse ? oldname : newname; |
498 | 529 | ||
499 | // We're deleting oldname if new file is /dev/null (before -p) | 530 | // We're deleting oldname if new file is /dev/null (before -p) |
500 | // or if new hunk is empty (zero context) after patching | 531 | // or if new hunk is empty (zero context) after patching |
501 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { | 532 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) |
533 | { | ||
502 | name = reverse ? newname : oldname; | 534 | name = reverse ? newname : oldname; |
503 | del++; | 535 | del++; |
504 | } | 536 | } |
505 | 537 | ||
506 | // handle -p path truncation. | 538 | // handle -p path truncation. |
507 | for (i=0, s = name; *s;) { | 539 | for (i=0, s = name; *s;) { |
508 | if ((option_mask32 & FLAG_PATHLEN) && prefix == i) | 540 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; |
509 | break; | ||
510 | if (*(s++)=='/') { | 541 | if (*(s++)=='/') { |
511 | name = s; | 542 | name = s; |
512 | i++; | 543 | i++; |
@@ -518,7 +549,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
518 | xunlink(name); | 549 | xunlink(name); |
519 | state = 0; | 550 | state = 0; |
520 | // If we've got a file to open, do so. | 551 | // If we've got a file to open, do so. |
521 | } else if (!(option_mask32 & FLAG_PATHLEN) || i <= prefix) { | 552 | } else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) { |
522 | // If the old file was null, we're creating a new one. | 553 | // If the old file was null, we're creating a new one. |
523 | if (!strcmp(oldname, "/dev/null") || !oldsum) { | 554 | if (!strcmp(oldname, "/dev/null") || !oldsum) { |
524 | printf("creating %s\n", name); | 555 | printf("creating %s\n", name); |
@@ -551,6 +582,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
551 | finish_oldfile(); | 582 | finish_oldfile(); |
552 | 583 | ||
553 | if (ENABLE_FEATURE_CLEAN_UP) { | 584 | if (ENABLE_FEATURE_CLEAN_UP) { |
585 | close(TT.filepatch); | ||
554 | free(oldname); | 586 | free(oldname); |
555 | free(newname); | 587 | free(newname); |
556 | } | 588 | } |