Mercurial > hg > toybox
annotate toys/patch.c @ 233:d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
toys/*.c. Move relevant info into comment at the top of each toys/*.c. Also
convert more of Makefile into a thin wrapper around shell scripts that actually
do the work. (Makefile is only still there for the user interface.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 19 Jan 2008 17:08:39 -0600 |
parents | cfa11e043e2b |
children | 163498bf547b |
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 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
24 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
|
25 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
|
26 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
|
27 help |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
28 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
|
29 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
30 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
|
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 -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
|
33 -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
|
34 -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
|
35 -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
|
36 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
37 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
|
38 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
|
39 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
|
40 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
41 A file compared against /dev/null is created/deleted as appropriate. |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
42 */ |
209 | 43 |
44 #include "toys.h" | |
45 | |
46 #define TT toy.patch | |
47 | |
48 #define FLAG_REVERSE 1 | |
49 #define FLAG_PATHLEN 4 | |
50 | |
51 static void do_line(void *data) | |
52 { | |
53 struct double_list *dlist = (struct double_list *)data; | |
54 | |
55 if (TT.state && *dlist->data != TT.state) | |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
56 fdprintf(TT.state == 2 ? 2: TT.fileout, |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
57 "%s\n", dlist->data+(TT.state>2 ? 1 : 0)); |
209 | 58 free(dlist->data); |
59 } | |
60 | |
61 | |
62 static void dlist_add(struct double_list **list, char *data) | |
63 { | |
64 struct double_list *line = xmalloc(sizeof(struct double_list)); | |
65 | |
66 line->data = data; | |
67 if (*list) { | |
68 line->next = *list; | |
69 line->prev = (*list)->prev; | |
70 (*list)->prev->next = line; | |
71 (*list)->prev = line; | |
72 } else *list = line->next = line->prev = line; | |
73 } | |
74 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
75 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
|
76 { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
77 if (TT.tempname) replace_tempfile(TT.filein, TT.fileout, &TT.tempname); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
78 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
79 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
80 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
|
81 { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
82 if (!TT.plines) return; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
83 TT.plines->prev->next = 0; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
84 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
85 printf("Hunk FAILED.\n"); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
86 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
|
87 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
88 // 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
|
89 // 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
|
90 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
91 TT.state = 2; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
92 llist_free(TT.plines, do_line); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
93 TT.plines = NULL; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
94 delete_tempfile(TT.filein, TT.fileout, &TT.tempname); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
95 TT.filein = -1; |
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 |
209 | 98 static void apply_hunk(void) |
99 { | |
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 struct double_list *plist, *buf = NULL; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
101 int i = 0, backwards = 0, matcheof = 0, |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
102 reverse = toys.optflags & FLAG_REVERSE; |
209 | 103 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
104 // Break doubly linked list so we can use singly linked traversal function. |
209 | 105 TT.plines->prev->next = NULL; |
106 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
107 // Match EOF if there aren't as many ending context lines as beginning |
209 | 108 for (plist = TT.plines; plist; plist = plist->next) { |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
109 if (plist->data[0]==' ') i++; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
110 else i = 0; |
209 | 111 } |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
112 if (i < TT.context) matcheof++; |
209 | 113 |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
114 // Search for a place to apply this hunk. Match all context lines and |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
115 // lines to be removed. |
209 | 116 plist = TT.plines; |
117 buf = NULL; | |
118 i = 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
|
119 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
120 // Start of for loop |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
121 if (TT.context) for (;;) { |
209 | 122 char *data = get_line(TT.filein); |
123 TT.linenum++; | |
124 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
125 // Skip lines we'd add. |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
126 while (plist && *plist->data == "+-"[reverse]) { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
127 if (data && !backwards && !strcmp(data, plist->data+1)) { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
128 backwards = 1; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
129 fdprintf(2,"Possibly reversed hunk at %ld\n", TT.linenum); |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
130 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
131 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
|
132 } |
209 | 133 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
134 if (!data) { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
135 // Matched EOF? |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
136 if (!plist && matcheof) break; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
137 // File ended before we found a home for this hunk? |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
138 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
|
139 goto done; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
140 } |
209 | 141 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
|
142 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
143 if (!plist || strcmp(data, plist->data+1)) { // Ignore whitespace? |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
144 // Match failed, hunk doesn't go here. Flush accumulated buffer |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
145 // so far. |
209 | 146 |
147 buf->prev->next = NULL; | |
148 TT.state = 1; | |
149 llist_free(buf, do_line); | |
150 buf = NULL; | |
151 plist = TT.plines; | |
152 } else { | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
153 // Match, advance plist. |
209 | 154 plist = plist->next; |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
155 if (!plist && !matcheof) break; |
209 | 156 } |
157 } | |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
158 |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
159 // Got it. Emit changed data. |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
160 TT.state = "-+"[reverse]; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
161 llist_free(TT.plines, do_line); |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
162 TT.plines = 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
|
163 done: |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
164 TT.state = 0; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
165 if (buf) { |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
166 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
|
167 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
|
168 } |
209 | 169 } |
170 | |
171 // state 0: Not in a hunk, look for +++. | |
172 // state 1: Found +++ file indicator, look for @@ | |
173 // state 2: In hunk: counting initial context lines | |
174 // state 3: In hunk: getting body | |
175 | |
176 void patch_main(void) | |
177 { | |
178 if (TT.infile) TT.filepatch = xopen(TT.infile, O_RDONLY); | |
179 TT.filein = TT.fileout = -1; | |
180 | |
181 // Loop through the lines in the patch | |
182 for(;;) { | |
183 char *patchline; | |
184 | |
185 patchline = get_line(TT.filepatch); | |
186 if (!patchline) break; | |
187 | |
188 // Are we processing a hunk? | |
189 if (TT.state >= 2) { | |
190 if (*patchline==' ' || *patchline=='+' || *patchline=='-') { | |
191 dlist_add(&TT.plines, patchline); | |
192 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
193 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
|
194 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
|
195 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
196 // Context line? |
209 | 197 if (*patchline==' ' && TT.state==2) TT.context++; |
198 else TT.state=3; | |
199 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
200 if (!TT.oldlen && !TT.newlen) apply_hunk(); |
209 | 201 continue; |
202 } | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
203 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
|
204 TT.state = 0; |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
205 continue; |
209 | 206 } |
207 | |
208 // Open a new file? | |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
209 if (!strncmp("--- ", patchline, 4)) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
210 char *s; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
211 free(TT.oldname); |
209 | 212 |
213 // Trim date from end of filename (if any). We don't care. | |
214 for (s = patchline+4; *s && *s!='\t'; s++) | |
215 if (*s=='\\' && s[1]) s++; | |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
216 *s = 0; |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
217 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
218 TT.oldname = xstrdup(patchline+4); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
219 } else if (!strncmp("+++ ", patchline, 4)) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
220 int i = 0, del = 0; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
221 char *s, *start; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
222 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
223 finish_oldfile(); |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
224 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
225 // Trim date from end of filename (if any). We don't care. |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
226 for (s = patchline+4; *s && *s!='\t'; s++) |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
227 if (*s=='\\' && s[1]) s++; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
228 *s = 0; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
229 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
230 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
231 // If new file is /dev/null (before -p), we're deleting oldname |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
232 start = patchline+4; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
233 if (!strcmp(start, "/dev/null")) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
234 start = TT.oldname; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
235 del++; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
236 } else start = patchline+4; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
237 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
238 // handle -p path truncation. |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
239 for (s = start; *s;) { |
209 | 240 if ((toys.optflags & FLAG_PATHLEN) && TT.prefix == i) break; |
241 if (*(s++)=='/') { | |
242 start = s; | |
243 i++; | |
244 } | |
245 } | |
246 | |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
247 if (del) xunlink(TT.oldname); |
209 | 248 // If we've got a file to open, do so. |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
249 else if (!(toys.optflags & FLAG_PATHLEN) || i <= TT.prefix) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
250 // If the old file was null, we're creating a new one. |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
251 if (!strcmp(TT.oldname, "/dev/null")) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
252 printf("creating %s\n", start); |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
253 s = strrchr(start, '/'); |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
254 if (s) { |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
255 *s = 0; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
256 xmkpath(start, -1); |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
257 *s = '/'; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
258 } |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
259 TT.filein = xcreate(start, O_CREAT|O_RDWR, 0666); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
260 } else { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
261 printf("patching %s\n", start); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
262 TT.filein = xopen(start, O_RDWR); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
263 } |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
264 TT.fileout = copy_tempfile(TT.filein, start, &TT.tempname); |
209 | 265 TT.state = 1; |
266 TT.context = 0; | |
267 TT.linenum = 0; | |
268 } | |
269 | |
270 // Start a new 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
|
271 // Test filein rather than state to report only the first failed hunk. |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
272 } else if (TT.filein!=-1 && !strncmp("@@ -", patchline, 4) && |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
273 4 == sscanf(patchline+4, "%ld,%ld +%ld,%ld", &TT.oldline, |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
274 &TT.oldlen, &TT.newline, &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
|
275 { |
209 | 276 TT.context = 0; |
277 TT.state = 2; | |
278 continue; | |
279 } | |
280 | |
219
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 we didn't continue above, discard this line. |
209 | 282 free(patchline); |
283 } | |
284 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
285 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
|
286 |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
287 if (CFG_TOYBOX_FREE) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
288 close(TT.filepatch); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
289 free(TT.oldname); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
290 } |
209 | 291 } |