Mercurial > hg > toybox
annotate toys/patch.c @ 614:2b40588a3d25
Minor cleanups and refactoring. Make FLAG macros closer to what should eventually be generated for us by the build infrastructure.
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 26 Jun 2012 20:47:01 -0500 |
parents | b2194045c40e |
children | 1e8b9acdafeb |
rev | line source |
---|---|
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
1 /* vi: set sw=4 ts=4: |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
2 * |
209 | 3 * patch.c - Apply a "universal" diff. |
4 * | |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
5 * Copyright 2007 Rob Landley <rob@landley.net> |
209 | 6 * |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
7 * see http://www.opengroup.org/onlinepubs/009695399/utilities/patch.html |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
8 * (But only does -u, because who still cares about "ed"?) |
209 | 9 * |
10 * TODO: | |
11 * -b backup | |
12 * -l treat all whitespace as a single space | |
13 * -N ignore already applied | |
14 * -d chdir first | |
15 * -D define wrap #ifdef and #ifndef around changes | |
16 * -o outfile output here instead of in place | |
17 * -r rejectfile write rejected hunks to this file | |
18 * | |
19 * -E remove empty files --remove-empty-files | |
20 * -f force (no questions asked) | |
21 * -F fuzz (number, default 2) | |
22 * [file] which file to patch | |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
23 |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
24 USE_PATCH(NEWTOY(patch, USE_TOYBOX_DEBUG("x")"up#i:R", TOYFLAG_USR|TOYFLAG_BIN)) |
234
163498bf547b
Move NEWTOY() list from end of toylist.h to generated/newtoys.h.
Rob Landley <rob@landley.net>
parents:
233
diff
changeset
|
25 |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
26 config PATCH |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
27 bool "patch" |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
28 default y |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
29 help |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
30 usage: patch [-i file] [-p depth] [-Ru] |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
31 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
32 Apply a unified diff to one or more files. |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
33 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
34 -i Input file (defaults=stdin) |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
35 -p number of '/' to strip from start of file paths (default=all) |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
36 -R Reverse patch. |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
37 -u Ignored (only handles "unified" diffs) |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
38 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
39 This version of patch only handles unified diffs, and only modifies |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
40 a file when all all hunks to that file apply. Patch prints failed |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
41 hunks to stderr, and exits with nonzero status if any hunks fail. |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
42 |
325
5d0fbdb2fc86
The epoch can also show up as 1970-01-01 (depending on timezone), so treat any year >0 and <= 1970 as meaning "file does not exist".
Rob Landley <rob@landley.net>
parents:
315
diff
changeset
|
43 A file compared against /dev/null (or with a date <= the epoch) is |
280
d1a548bbd0dd
Teach patch that a file dated 1969-12-31 means doesn't exist, and to fail
Rob Landley <rob@landley.net>
parents:
238
diff
changeset
|
44 created/deleted as appropriate. |
233
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
45 */ |
209 | 46 |
47 #include "toys.h" | |
48 | |
237
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
49 DEFINE_GLOBALS( |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
50 char *infile; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
51 long prefix; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
52 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
53 struct double_list *current_hunk; |
377
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
54 long oldline, oldlen, newline, newlen; |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
55 long linenum; |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
56 int context, state, filein, fileout, filepatch, hunknum; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
57 char *tempname; |
237
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
58 ) |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
59 |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
60 #define TT this.patch |
209 | 61 |
62 #define FLAG_REVERSE 1 | |
63 #define FLAG_PATHLEN 4 | |
64 | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
65 // Dispose of a line of input, either by writing it out or discarding it. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
66 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
67 // state < 2: just free |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
68 // state = 2: write whole line to stderr |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
69 // state = 3: write whole line to fileout |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
70 // state > 3: write line+1 to fileout when *line != state |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
71 |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
72 #define PATCH_DEBUG (CFG_TOYBOX_DEBUG && (toys.optflags & 16)) |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
73 |
209 | 74 static void do_line(void *data) |
75 { | |
76 struct double_list *dlist = (struct double_list *)data; | |
77 | |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
78 if (TT.state>1 && *dlist->data != TT.state) { |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
79 char *s = dlist->data+(TT.state>3 ? 1 : 0); |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
80 int i = TT.state == 2 ? 2 : TT.fileout; |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
81 |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
82 xwrite(i, s, strlen(s)); |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
83 xwrite(i, "\n", 1); |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
84 } |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
85 |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
86 if (PATCH_DEBUG) fprintf(stderr, "DO %d: %s\n", TT.state, dlist->data); |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
87 |
209 | 88 free(dlist->data); |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
89 free(data); |
209 | 90 } |
91 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
92 static void finish_oldfile(void) |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
93 { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
94 if (TT.tempname) replace_tempfile(TT.filein, TT.fileout, &TT.tempname); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
95 TT.fileout = TT.filein = -1; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
96 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
97 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
98 static void fail_hunk(void) |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
99 { |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
100 if (!TT.current_hunk) return; |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
101 TT.current_hunk->prev->next = 0; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
102 |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
103 fprintf(stderr, "Hunk %d FAILED %ld/%ld.\n", |
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
104 TT.hunknum, TT.oldline, TT.newline); |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
105 toys.exitval = 1; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
106 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
107 // If we got to this point, we've seeked to the end. Discard changes to |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
108 // this file and advance to next file. |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
109 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
110 TT.state = 2; |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
111 llist_free(TT.current_hunk, do_line); |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
112 TT.current_hunk = NULL; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
113 delete_tempfile(TT.filein, TT.fileout, &TT.tempname); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
114 TT.state = 0; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
115 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
116 |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
117 // Given a hunk of a unified diff, make the appropriate change to the file. |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
118 // This does not use the location information, but instead treats a hunk |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
119 // as a sort of regex. Copies data from input to output until it finds |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
120 // the change to be made, then outputs the changed data and returns. |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
121 // (Finding EOF first is an error.) This is a single pass operation, so |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
122 // multiple hunks must occur in order in the file. |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
123 |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
124 static int apply_one_hunk(void) |
209 | 125 { |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
126 struct double_list *plist, *buf = NULL, *check; |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
127 int matcheof = 0, reverse = toys.optflags & FLAG_REVERSE, backwarn = 0; |
209 | 128 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
129 // Break doubly linked list so we can use singly linked traversal function. |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
130 TT.current_hunk->prev->next = NULL; |
209 | 131 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
132 // Match EOF if there aren't as many ending context lines as beginning |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
133 for (plist = TT.current_hunk; plist; plist = plist->next) { |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
134 if (plist->data[0]==' ') matcheof++; |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
135 else matcheof = 0; |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
136 if (PATCH_DEBUG) fprintf(stderr, "HUNK:%s\n", plist->data); |
209 | 137 } |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
138 matcheof = matcheof < TT.context; |
209 | 139 |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
140 if (PATCH_DEBUG) fprintf(stderr,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
141 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
142 // Loop through input data searching for this hunk. Match all context |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
143 // lines and all lines to be removed until we've found the end of a |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
144 // complete hunk. |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
145 plist = TT.current_hunk; |
209 | 146 buf = NULL; |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
147 if (TT.context) for (;;) { |
209 | 148 char *data = get_line(TT.filein); |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
149 |
209 | 150 TT.linenum++; |
151 | |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
152 // Figure out which line of hunk to compare with next. (Skip lines |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
153 // of the hunk we'd be adding.) |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
154 while (plist && *plist->data == "+-"[reverse]) { |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
155 if (data && !strcmp(data, plist->data+1)) { |
391
56d07d82e691
Don't complain about "possibly reversed" hunks that merely moved later in the file, just give a potential reason if it failed to apply.
Rob Landley <rob@landley.net>
parents:
377
diff
changeset
|
156 if (!backwarn) backwarn = TT.linenum; |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
157 } |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
158 plist = plist->next; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
159 } |
209 | 160 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
161 // Is this EOF? |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
162 if (!data) { |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
163 if (PATCH_DEBUG) fprintf(stderr, "INEOF\n"); |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
164 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
165 // Does this hunk need to match EOF? |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
166 if (!plist && matcheof) break; |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
167 |
391
56d07d82e691
Don't complain about "possibly reversed" hunks that merely moved later in the file, just give a potential reason if it failed to apply.
Rob Landley <rob@landley.net>
parents:
377
diff
changeset
|
168 if (backwarn) |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
169 fprintf(stderr, "Possibly reversed hunk %d at %ld\n", |
391
56d07d82e691
Don't complain about "possibly reversed" hunks that merely moved later in the file, just give a potential reason if it failed to apply.
Rob Landley <rob@landley.net>
parents:
377
diff
changeset
|
170 TT.hunknum, TT.linenum); |
56d07d82e691
Don't complain about "possibly reversed" hunks that merely moved later in the file, just give a potential reason if it failed to apply.
Rob Landley <rob@landley.net>
parents:
377
diff
changeset
|
171 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
172 // File ended before we found a place for this hunk. |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
173 fail_hunk(); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
174 goto done; |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
175 } else if (PATCH_DEBUG) fprintf(stderr, "IN: %s\n", data); |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
176 check = dlist_add(&buf, data); |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
177 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
178 // Compare this line with next expected line of hunk. |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
179 // todo: teach the strcmp() to ignore whitespace. |
209 | 180 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
181 // A match can fail because the next line doesn't match, or because |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
182 // we hit the end of a hunk that needed EOF, and this isn't EOF. |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
183 |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
184 // If match failed, flush first line of buffered data and |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
185 // recheck buffered data for a new match until we find one or run |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
186 // out of buffer. |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
187 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
188 for (;;) { |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
189 if (!plist || strcmp(check->data, plist->data+1)) { |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
190 // Match failed. Write out first line of buffered data and |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
191 // recheck remaining buffered data for a new match. |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
192 |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
193 if (PATCH_DEBUG) |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
194 fprintf(stderr, "NOT: %s\n", plist->data); |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
195 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
196 TT.state = 3; |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
197 check = llist_pop(&buf); |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
198 check->prev->next = buf; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
199 buf->prev = check->prev; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
200 do_line(check); |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
201 plist = TT.current_hunk; |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
202 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
203 // If we've reached the end of the buffer without confirming a |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
204 // match, read more lines. |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
205 if (check==buf) { |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
206 buf = 0; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
207 break; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
208 } |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
209 check = buf; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
210 } else { |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
211 if (PATCH_DEBUG) |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
212 fprintf(stderr, "MAYBE: %s\n", plist->data); |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
213 // This line matches. Advance plist, detect successful match. |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
214 plist = plist->next; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
215 if (!plist && !matcheof) goto out; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
216 check = check->next; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
217 if (check == buf) break; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
218 } |
209 | 219 } |
220 } | |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
221 out: |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
222 // We have a match. Emit changed data. |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
223 TT.state = "-+"[reverse]; |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
224 llist_free(TT.current_hunk, do_line); |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
225 TT.current_hunk = NULL; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
226 TT.state = 1; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
227 done: |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
228 if (buf) { |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
229 buf->prev->next = NULL; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
230 llist_free(buf, do_line); |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
231 } |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
232 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
233 return TT.state; |
209 | 234 } |
235 | |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
236 // Read a patch file and find hunks, opening/creating/deleting files. |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
237 // Call apply_one_hunk() on each hunk. |
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
238 |
209 | 239 // state 0: Not in a hunk, look for +++. |
240 // state 1: Found +++ file indicator, look for @@ | |
241 // state 2: In hunk: counting initial context lines | |
242 // state 3: In hunk: getting body | |
243 | |
244 void patch_main(void) | |
245 { | |
412
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
246 int reverse = toys.optflags&FLAG_REVERSE, state = 0, patchlinenum = 0, |
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
247 strip = 0; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
248 char *oldname = NULL, *newname = NULL; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
249 |
209 | 250 if (TT.infile) TT.filepatch = xopen(TT.infile, O_RDONLY); |
251 TT.filein = TT.fileout = -1; | |
252 | |
253 // Loop through the lines in the patch | |
412
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
254 for (;;) { |
209 | 255 char *patchline; |
256 | |
257 patchline = get_line(TT.filepatch); | |
258 if (!patchline) break; | |
259 | |
351 | 260 // Other versions of patch accept damaged patches, |
261 // so we need to also. | |
412
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
262 if (strip || !patchlinenum++) { |
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
263 int len = strlen(patchline); |
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
264 if (patchline[len-1] == '\r') { |
550
b2194045c40e
Remove "feature test macros", replace non-portable fdprintf() with standard fprintf().
Rob Landley <rob@landley.net>
parents:
500
diff
changeset
|
265 if (!strip) fprintf(stderr, "Removing DOS newlines\n"); |
412
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
266 strip = 1; |
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
267 patchline[len-1]=0; |
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
268 } |
2b521c791e4e
Patch shouldn't be bothered by DOS newlines.
Rob Landley <rob@landley.net>
parents:
391
diff
changeset
|
269 } |
351 | 270 if (!*patchline) { |
271 free(patchline); | |
272 patchline = xstrdup(" "); | |
273 } | |
274 | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
275 // Are we assembling a hunk? |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
276 if (state >= 2) { |
209 | 277 if (*patchline==' ' || *patchline=='+' || *patchline=='-') { |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
278 dlist_add(&TT.current_hunk, patchline); |
209 | 279 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
280 if (*patchline != '+') TT.oldlen--; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
281 if (*patchline != '-') TT.newlen--; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
282 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
283 // Context line? |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
284 if (*patchline==' ' && state==2) TT.context++; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
285 else state=3; |
209 | 286 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
287 // If we've consumed all expected hunk lines, apply the hunk. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
288 |
376
35c8beb54800
For CFG_TOYBOX_DEBUG add -x option to patch to dump lots of debug output about the search and match.
Rob Landley <rob@landley.net>
parents:
375
diff
changeset
|
289 if (!TT.oldlen && !TT.newlen) state = apply_one_hunk(); |
209 | 290 continue; |
291 } | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
292 fail_hunk(); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
293 state = 0; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
294 continue; |
209 | 295 } |
296 | |
297 // Open a new file? | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
298 if (!strncmp("--- ", patchline, 4) || !strncmp("+++ ", patchline, 4)) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
299 char *s, **name = &oldname; |
325
5d0fbdb2fc86
The epoch can also show up as 1970-01-01 (depending on timezone), so treat any year >0 and <= 1970 as meaning "file does not exist".
Rob Landley <rob@landley.net>
parents:
315
diff
changeset
|
300 int i; |
5d0fbdb2fc86
The epoch can also show up as 1970-01-01 (depending on timezone), so treat any year >0 and <= 1970 as meaning "file does not exist".
Rob Landley <rob@landley.net>
parents:
315
diff
changeset
|
301 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
302 if (*patchline == '+') { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
303 name = &newname; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
304 state = 1; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
305 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
306 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
307 free(*name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
308 finish_oldfile(); |
209 | 309 |
310 // Trim date from end of filename (if any). We don't care. | |
311 for (s = patchline+4; *s && *s!='\t'; s++) | |
312 if (*s=='\\' && s[1]) s++; | |
325
5d0fbdb2fc86
The epoch can also show up as 1970-01-01 (depending on timezone), so treat any year >0 and <= 1970 as meaning "file does not exist".
Rob Landley <rob@landley.net>
parents:
315
diff
changeset
|
313 i = atoi(s); |
375
9f4e5e15597c
One more little tweak to patch: unrecognized date format != delete file.
Rob Landley <rob@landley.net>
parents:
362
diff
changeset
|
314 if (i>1900 && i<=1970) |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
315 *name = xstrdup("/dev/null"); |
280
d1a548bbd0dd
Teach patch that a file dated 1969-12-31 means doesn't exist, and to fail
Rob Landley <rob@landley.net>
parents:
238
diff
changeset
|
316 else { |
d1a548bbd0dd
Teach patch that a file dated 1969-12-31 means doesn't exist, and to fail
Rob Landley <rob@landley.net>
parents:
238
diff
changeset
|
317 *s = 0; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
318 *name = xstrdup(patchline+4); |
335
556c10abdff6
Make patch work with -R when deleting files.
Rob Landley <rob@landley.net>
parents:
331
diff
changeset
|
319 } |
556c10abdff6
Make patch work with -R when deleting files.
Rob Landley <rob@landley.net>
parents:
331
diff
changeset
|
320 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
321 // We defer actually opening the file because svn produces broken |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
322 // patches that don't signal they want to create a new file the |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
323 // way the patch man page says, so you have to read the first hunk |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
324 // and _guess_. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
325 |
377
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
326 // Start a new hunk? Usually @@ -oldline,oldlen +newline,newlen @@ |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
327 // but a missing ,value means the value is 1. |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
328 } else if (state == 1 && !strncmp("@@ -", patchline, 4)) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
329 int i; |
377
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
330 char *s = patchline+4; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
331 |
377
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
332 // Read oldline[,oldlen] +newline[,newlen] |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
333 |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
334 TT.oldlen = TT.newlen = 1; |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
335 TT.oldline = strtol(s, &s, 10); |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
336 if (*s == ',') TT.oldlen=strtol(s+1, &s, 10); |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
337 TT.newline = strtol(s+2, &s, 10); |
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
338 if (*s == ',') TT.newlen = strtol(s+1, &s, 10); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
339 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
340 TT.context = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
341 state = 2; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
342 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
343 // If this is the first hunk, open the file. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
344 if (TT.filein == -1) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
345 int oldsum, newsum, del = 0; |
377
15ca7e49b6ff
The @@ -1,2 +3,4 @@ lines treat ,1 as implied, so the format isn't regular.
Rob Landley <rob@landley.net>
parents:
376
diff
changeset
|
346 char *name; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
347 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
348 oldsum = TT.oldline + TT.oldlen; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
349 newsum = TT.newline + TT.newlen; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
350 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
351 name = reverse ? oldname : newname; |
335
556c10abdff6
Make patch work with -R when deleting files.
Rob Landley <rob@landley.net>
parents:
331
diff
changeset
|
352 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
353 // We're deleting oldname if new file is /dev/null (before -p) |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
354 // or if new hunk is empty (zero context) after patching |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
355 if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
356 { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
357 name = reverse ? newname : oldname; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
358 del++; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
359 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
360 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
361 // handle -p path truncation. |
500
cd70270dbc51
Teach patch -p that consecutive /// counts as one path component.
Rob Landley <rob@landley.net>
parents:
412
diff
changeset
|
362 for (i = 0, s = name; *s;) { |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
363 if ((toys.optflags & FLAG_PATHLEN) && TT.prefix == i) break; |
500
cd70270dbc51
Teach patch -p that consecutive /// counts as one path component.
Rob Landley <rob@landley.net>
parents:
412
diff
changeset
|
364 if (*s++ != '/') continue; |
cd70270dbc51
Teach patch -p that consecutive /// counts as one path component.
Rob Landley <rob@landley.net>
parents:
412
diff
changeset
|
365 while (*s == '/') s++; |
cd70270dbc51
Teach patch -p that consecutive /// counts as one path component.
Rob Landley <rob@landley.net>
parents:
412
diff
changeset
|
366 name = s; |
cd70270dbc51
Teach patch -p that consecutive /// counts as one path component.
Rob Landley <rob@landley.net>
parents:
412
diff
changeset
|
367 i++; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
368 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
369 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
370 if (del) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
371 printf("removing %s\n", name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
372 xunlink(name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
373 state = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
374 // If we've got a file to open, do so. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
375 } else if (!(toys.optflags & FLAG_PATHLEN) || i <= TT.prefix) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
376 // If the old file was null, we're creating a new one. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
377 if (!strcmp(oldname, "/dev/null") || !oldsum) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
378 printf("creating %s\n", name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
379 s = strrchr(name, '/'); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
380 if (s) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
381 *s = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
382 xmkpath(name, -1); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
383 *s = '/'; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
384 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
385 TT.filein = xcreate(name, O_CREAT|O_EXCL|O_RDWR, 0666); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
386 } else { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
387 printf("patching %s\n", name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
388 TT.filein = xopen(name, O_RDWR); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
389 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
390 TT.fileout = copy_tempfile(TT.filein, name, &TT.tempname); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
391 TT.linenum = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
392 TT.hunknum = 0; |
209 | 393 } |
394 } | |
395 | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
396 TT.hunknum++; |
209 | 397 |
398 continue; | |
399 } | |
400 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
401 // If we didn't continue above, discard this line. |
209 | 402 free(patchline); |
403 } | |
404 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
405 finish_oldfile(); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
406 |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
407 if (CFG_TOYBOX_FREE) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
408 close(TT.filepatch); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
409 free(oldname); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
410 free(newname); |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
411 } |
209 | 412 } |