Mercurial > hg > toybox
annotate toys/patch.c @ 389:5e9c1d73c84a
Implement nohup.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 20 Nov 2011 21:13:47 -0600 |
parents | 15ca7e49b6ff |
children | 56d07d82e691 |
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 | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
78 if (TT.state>1 && *dlist->data != TT.state) |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
79 fdprintf(TT.state == 2 ? 2 : TT.fileout, |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
80 "%s\n", dlist->data+(TT.state>3 ? 1 : 0)); |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
81 |
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
|
82 if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); |
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
|
83 |
209 | 84 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
|
85 free(data); |
209 | 86 } |
87 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
88 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
|
89 { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
90 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
|
91 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
|
92 } |
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 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
|
95 { |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
96 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
|
97 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
|
98 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
99 fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", 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
|
100 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
|
101 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
102 // 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
|
103 // 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
|
104 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
105 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
|
106 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
|
107 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
|
108 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
|
109 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
|
110 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
111 |
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
|
112 // 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
|
113 // 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
|
114 // 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
|
115 // 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
|
116 // (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
|
117 // 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
|
118 |
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 static int apply_one_hunk(void) |
209 | 120 { |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
121 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
|
122 int matcheof = 0, reverse = toys.optflags & FLAG_REVERSE, backwarn = 0; |
209 | 123 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
124 // 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
|
125 TT.current_hunk->prev->next = NULL; |
209 | 126 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
127 // 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
|
128 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
|
129 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
|
130 else matcheof = 0; |
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
|
131 if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); |
209 | 132 } |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
133 matcheof = matcheof < TT.context; |
209 | 134 |
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
|
135 if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); |
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
|
136 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
137 // 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
|
138 // 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
|
139 // complete hunk. |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
140 plist = TT.current_hunk; |
209 | 141 buf = NULL; |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
142 if (TT.context) for (;;) { |
209 | 143 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
|
144 |
209 | 145 TT.linenum++; |
146 | |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
147 // 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
|
148 // 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
|
149 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
|
150 if (data && !strcmp(data, plist->data+1)) { |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
151 if (!backwarn) { |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
152 fdprintf(2,"Possibly reversed hunk %d at %ld\n", |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
153 TT.hunknum, 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
|
154 backwarn++; |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
155 } |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
156 } |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
157 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
|
158 } |
209 | 159 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
160 // 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
|
161 if (!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
|
162 if (PATCH_DEBUG) fdprintf(2, "INEOF\n"); |
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
|
163 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
164 // 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
|
165 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
|
166 |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
167 // 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
|
168 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
|
169 goto done; |
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
|
170 } else if (PATCH_DEBUG) fdprintf(2, "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
|
171 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
|
172 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
173 // 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
|
174 // todo: teach the strcmp() to ignore whitespace. |
209 | 175 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
176 // 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
|
177 // 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
|
178 |
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
179 // 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
|
180 // 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
|
181 // 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
|
182 |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
183 for (;;) { |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
184 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
|
185 // 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
|
186 // 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
|
187 |
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
|
188 if (PATCH_DEBUG) |
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
|
189 fdprintf(2, "NOT: %s\n", plist->data); |
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
|
190 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
191 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
|
192 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
|
193 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
|
194 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
|
195 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
|
196 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
|
197 |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
198 // 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
|
199 // 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
|
200 if (check==buf) { |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
201 buf = 0; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
202 break; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
203 } |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
204 check = buf; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
205 } 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
|
206 if (PATCH_DEBUG) |
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
|
207 fdprintf(2, "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
|
208 // 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
|
209 plist = plist->next; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
210 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
|
211 check = check->next; |
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
212 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
|
213 } |
209 | 214 } |
215 } | |
315
aaac01796688
Upgrade patch to detect hunks that start after a false start.
Rob Landley <rob@landley.net>
parents:
280
diff
changeset
|
216 out: |
362
d15520819347
Fix reversed patch detection logic, remove unused variables, rename variables, better comments.
Rob Landley <rob@landley.net>
parents:
351
diff
changeset
|
217 // 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
|
218 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
|
219 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
|
220 TT.current_hunk = NULL; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
221 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
|
222 done: |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
223 if (buf) { |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
224 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
|
225 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
|
226 } |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
227 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
228 return TT.state; |
209 | 229 } |
230 | |
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
|
231 // 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
|
232 // 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
|
233 |
209 | 234 // state 0: Not in a hunk, look for +++. |
235 // state 1: Found +++ file indicator, look for @@ | |
236 // state 2: In hunk: counting initial context lines | |
237 // state 3: In hunk: getting body | |
238 | |
239 void patch_main(void) | |
240 { | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
241 int reverse = toys.optflags & FLAG_REVERSE, state = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
242 char *oldname = NULL, *newname = NULL; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
243 |
209 | 244 if (TT.infile) TT.filepatch = xopen(TT.infile, O_RDONLY); |
245 TT.filein = TT.fileout = -1; | |
246 | |
247 // Loop through the lines in the patch | |
248 for(;;) { | |
249 char *patchline; | |
250 | |
251 patchline = get_line(TT.filepatch); | |
252 if (!patchline) break; | |
253 | |
351 | 254 // Other versions of patch accept damaged patches, |
255 // so we need to also. | |
256 if (!*patchline) { | |
257 free(patchline); | |
258 patchline = xstrdup(" "); | |
259 } | |
260 | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
261 // Are we assembling a hunk? |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
262 if (state >= 2) { |
209 | 263 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
|
264 dlist_add(&TT.current_hunk, patchline); |
209 | 265 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
266 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
|
267 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
|
268 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
269 // Context line? |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
270 if (*patchline==' ' && state==2) TT.context++; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
271 else state=3; |
209 | 272 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
273 // 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
|
274 |
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
|
275 if (!TT.oldlen && !TT.newlen) state = apply_one_hunk(); |
209 | 276 continue; |
277 } | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
278 fail_hunk(); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
279 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
|
280 continue; |
209 | 281 } |
282 | |
283 // Open a new file? | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
284 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
|
285 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
|
286 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
|
287 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
288 if (*patchline == '+') { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
289 name = &newname; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
290 state = 1; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
291 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
292 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
293 free(*name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
294 finish_oldfile(); |
209 | 295 |
296 // Trim date from end of filename (if any). We don't care. | |
297 for (s = patchline+4; *s && *s!='\t'; s++) | |
298 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
|
299 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
|
300 if (i>1900 && i<=1970) |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
301 *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
|
302 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
|
303 *s = 0; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
304 *name = xstrdup(patchline+4); |
335
556c10abdff6
Make patch work with -R when deleting files.
Rob Landley <rob@landley.net>
parents:
331
diff
changeset
|
305 } |
556c10abdff6
Make patch work with -R when deleting files.
Rob Landley <rob@landley.net>
parents:
331
diff
changeset
|
306 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
307 // 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
|
308 // 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
|
309 // 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
|
310 // and _guess_. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
311 |
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
|
312 // 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
|
313 // 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
|
314 } 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
|
315 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
|
316 char *s = patchline+4; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
317 |
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
|
318 // 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
|
319 |
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
|
320 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
|
321 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
|
322 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
|
323 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
|
324 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
|
325 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
326 TT.context = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
327 state = 2; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
328 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
329 // 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
|
330 if (TT.filein == -1) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
331 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
|
332 char *name; |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
333 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
334 oldsum = TT.oldline + TT.oldlen; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
335 newsum = TT.newline + TT.newlen; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
336 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
337 name = reverse ? oldname : newname; |
335
556c10abdff6
Make patch work with -R when deleting files.
Rob Landley <rob@landley.net>
parents:
331
diff
changeset
|
338 |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
339 // 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
|
340 // 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
|
341 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
|
342 { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
343 name = reverse ? newname : oldname; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
344 del++; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
345 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
346 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
347 // handle -p path truncation. |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
348 for (i=0, s = name; *s;) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
349 if ((toys.optflags & FLAG_PATHLEN) && TT.prefix == i) break; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
350 if (*(s++)=='/') { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
351 name = s; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
352 i++; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
353 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
354 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
355 |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
356 if (del) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
357 printf("removing %s\n", name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
358 xunlink(name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
359 state = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
360 // 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
|
361 } 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
|
362 // 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
|
363 if (!strcmp(oldname, "/dev/null") || !oldsum) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
364 printf("creating %s\n", name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
365 s = strrchr(name, '/'); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
366 if (s) { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
367 *s = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
368 xmkpath(name, -1); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
369 *s = '/'; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
370 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
371 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
|
372 } else { |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
373 printf("patching %s\n", name); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
374 TT.filein = xopen(name, O_RDWR); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
375 } |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
376 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
|
377 TT.linenum = 0; |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
378 TT.hunknum = 0; |
209 | 379 } |
380 } | |
381 | |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
382 TT.hunknum++; |
209 | 383 |
384 continue; | |
385 } | |
386 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
387 // If we didn't continue above, discard this line. |
209 | 388 free(patchline); |
389 } | |
390 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
391 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
|
392 |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
393 if (CFG_TOYBOX_FREE) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
394 close(TT.filepatch); |
348
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
395 free(oldname); |
c7143968cea6
Rearchitect patch to handle more darn corner cases.
Rob Landley <rob@landley.net>
parents:
335
diff
changeset
|
396 free(newname); |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
397 } |
209 | 398 } |