Mercurial > hg > toybox
annotate toys/patch.c @ 241:4121825716b8
Fix crash when running unknown command via symlink.
(The error message was trying to print an uninitialied field. Oops.)
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 22 Jan 2008 15:33:50 -0600 |
parents | 630b2e12db16 |
children | d1a548bbd0dd |
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 |
234
163498bf547b
Move NEWTOY() list from end of toylist.h to generated/newtoys.h.
Rob Landley <rob@landley.net>
parents:
233
diff
changeset
|
24 USE_PATCH(NEWTOY(patch, "up#i:R", TOYFLAG_USR|TOYFLAG_BIN)) |
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 |
d4176f3f3835
Zap toys/Config.in and instead create generated/Config.in from contents of
Rob Landley <rob@landley.net>
parents:
219
diff
changeset
|
43 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
|
44 */ |
209 | 45 |
46 #include "toys.h" | |
47 | |
237
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
48 DEFINE_GLOBALS( |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
49 char *infile; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
50 long prefix; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
51 |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
52 struct double_list *plines, *flines; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
53 long oldline, oldlen, newline, newlen, linenum; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
54 int context, state, filein, fileout, filepatch; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
55 char *tempname, *oldname; |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
56 ) |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
57 |
7cb15eae1664
Zap toylist.h, moving contents of global structures into DEFINE_GLOBALS()
Rob Landley <rob@landley.net>
parents:
234
diff
changeset
|
58 #define TT this.patch |
209 | 59 |
60 #define FLAG_REVERSE 1 | |
61 #define FLAG_PATHLEN 4 | |
62 | |
63 static void do_line(void *data) | |
64 { | |
65 struct double_list *dlist = (struct double_list *)data; | |
66 | |
67 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
|
68 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
|
69 "%s\n", dlist->data+(TT.state>2 ? 1 : 0)); |
209 | 70 free(dlist->data); |
71 } | |
72 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
73 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
|
74 { |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
75 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
|
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 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
78 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
|
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 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
|
81 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
|
82 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
83 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
|
84 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
|
85 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
86 // 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
|
87 // 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
|
88 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
89 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
|
90 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
|
91 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
|
92 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
|
93 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
|
94 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
95 |
209 | 96 static void apply_hunk(void) |
97 { | |
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 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
|
99 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
|
100 reverse = toys.optflags & FLAG_REVERSE; |
209 | 101 |
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 // Break doubly linked list so we can use singly linked traversal function. |
209 | 103 TT.plines->prev->next = NULL; |
104 | |
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 // Match EOF if there aren't as many ending context lines as beginning |
209 | 106 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
|
107 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
|
108 else i = 0; |
209 | 109 } |
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 if (i < TT.context) matcheof++; |
209 | 111 |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
112 // 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
|
113 // lines to be removed. |
209 | 114 plist = TT.plines; |
115 buf = NULL; | |
116 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
|
117 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
118 // 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
|
119 if (TT.context) for (;;) { |
209 | 120 char *data = get_line(TT.filein); |
121 TT.linenum++; | |
122 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
123 // 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
|
124 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
|
125 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
|
126 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
|
127 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
|
128 } |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
129 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
|
130 } |
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 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
|
133 // 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
|
134 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
|
135 // 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
|
136 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
|
137 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
|
138 } |
209 | 139 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
|
140 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
141 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
|
142 // 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
|
143 // so far. |
209 | 144 |
145 buf->prev->next = NULL; | |
146 TT.state = 1; | |
147 llist_free(buf, do_line); | |
148 buf = NULL; | |
149 plist = TT.plines; | |
150 } 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
|
151 // Match, advance plist. |
209 | 152 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
|
153 if (!plist && !matcheof) break; |
209 | 154 } |
155 } | |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
156 |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
157 // 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
|
158 TT.state = "-+"[reverse]; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
159 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
|
160 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
|
161 done: |
216
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
162 TT.state = 0; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
163 if (buf) { |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
164 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
|
165 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
|
166 } |
209 | 167 } |
168 | |
169 // state 0: Not in a hunk, look for +++. | |
170 // state 1: Found +++ file indicator, look for @@ | |
171 // state 2: In hunk: counting initial context lines | |
172 // state 3: In hunk: getting body | |
173 | |
174 void patch_main(void) | |
175 { | |
176 if (TT.infile) TT.filepatch = xopen(TT.infile, O_RDONLY); | |
177 TT.filein = TT.fileout = -1; | |
178 | |
179 // Loop through the lines in the patch | |
180 for(;;) { | |
181 char *patchline; | |
182 | |
183 patchline = get_line(TT.filepatch); | |
184 if (!patchline) break; | |
185 | |
186 // Are we processing a hunk? | |
187 if (TT.state >= 2) { | |
188 if (*patchline==' ' || *patchline=='+' || *patchline=='-') { | |
189 dlist_add(&TT.plines, patchline); | |
190 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
191 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
|
192 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
|
193 |
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
194 // Context line? |
209 | 195 if (*patchline==' ' && TT.state==2) TT.context++; |
196 else TT.state=3; | |
197 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
198 if (!TT.oldlen && !TT.newlen) apply_hunk(); |
209 | 199 continue; |
200 } | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
201 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
|
202 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
|
203 continue; |
209 | 204 } |
205 | |
206 // Open a new file? | |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
207 if (!strncmp("--- ", patchline, 4)) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
208 char *s; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
209 free(TT.oldname); |
209 | 210 |
211 // Trim date from end of filename (if any). We don't care. | |
212 for (s = patchline+4; *s && *s!='\t'; s++) | |
213 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
|
214 *s = 0; |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
215 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
216 TT.oldname = xstrdup(patchline+4); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
217 } else if (!strncmp("+++ ", patchline, 4)) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
218 int i = 0, del = 0; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
219 char *s, *start; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
220 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
221 finish_oldfile(); |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
222 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
223 // 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
|
224 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
|
225 if (*s=='\\' && s[1]) s++; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
226 *s = 0; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
227 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
228 |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
229 // 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
|
230 start = patchline+4; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
231 if (!strcmp(start, "/dev/null")) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
232 start = TT.oldname; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
233 del++; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
234 } else start = patchline+4; |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
235 |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
236 // handle -p path truncation. |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
237 for (s = start; *s;) { |
209 | 238 if ((toys.optflags & FLAG_PATHLEN) && TT.prefix == i) break; |
239 if (*(s++)=='/') { | |
240 start = s; | |
241 i++; | |
242 } | |
243 } | |
244 | |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
245 if (del) xunlink(TT.oldname); |
209 | 246 // 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
|
247 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
|
248 // 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
|
249 if (!strcmp(TT.oldname, "/dev/null")) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
250 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
|
251 s = strrchr(start, '/'); |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
252 if (s) { |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
253 *s = 0; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
254 xmkpath(start, -1); |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
255 *s = '/'; |
5697a3f7c8cf
Make patch's file add actually work, including directory creating and
Rob Landley <rob@landley.net>
parents:
214
diff
changeset
|
256 } |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
257 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
|
258 } else { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
259 printf("patching %s\n", start); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
260 TT.filein = xopen(start, O_RDWR); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
261 } |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
262 TT.fileout = copy_tempfile(TT.filein, start, &TT.tempname); |
209 | 263 TT.state = 1; |
264 TT.context = 0; | |
265 TT.linenum = 0; | |
266 } | |
267 | |
268 // 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
|
269 // 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
|
270 } 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
|
271 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
|
272 &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
|
273 { |
209 | 274 TT.context = 0; |
275 TT.state = 2; | |
276 continue; | |
277 } | |
278 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
279 // If we didn't continue above, discard this line. |
209 | 280 free(patchline); |
281 } | |
282 | |
219
cfa11e043e2b
Fix patch to use @@ values and match EOF when fewer trailing than starting
Rob Landley <rob@landley.net>
parents:
216
diff
changeset
|
283 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
|
284 |
214
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
285 if (CFG_TOYBOX_FREE) { |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
286 close(TT.filepatch); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
287 free(TT.oldname); |
98820d1eaa79
Upgrade patch to understand creating and deleting files.
Rob Landley <rob@landley.net>
parents:
209
diff
changeset
|
288 } |
209 | 289 } |