aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--editors/patch.c74
1 files changed, 32 insertions, 42 deletions
diff --git a/editors/patch.c b/editors/patch.c
index 4fadbb8fe..1d4a2554e 100644
--- a/editors/patch.c
+++ b/editors/patch.c
@@ -56,75 +56,64 @@
56 56
57#include "libbb.h" 57#include "libbb.h"
58 58
59
60// libbb candidate?
61
59struct double_list { 62struct double_list {
60 struct double_list *next; 63 struct double_list *next;
61 struct double_list *prev; 64 struct double_list *prev;
62 char *data; 65 char *data;
63}; 66};
64 67
65// Return the first item from the list, advancing the list (which must be called
66// as &list)
67static
68void *TOY_llist_pop(void *list)
69{
70 // I'd use a void ** for the argument, and even accept the typecast in all
71 // callers as documentation you need the &, except the stupid compiler
72 // would then scream about type-punned pointers. Screw it.
73 void **llist = (void **)list;
74 void **next = (void **)*llist;
75 *llist = *next;
76
77 return (void *)next;
78}
79
80// Free all the elements of a linked list 68// Free all the elements of a linked list
81// if freeit!=NULL call freeit() on each element before freeing it. 69// Call freeit() on each element before freeing it.
82static 70static
83void TOY_llist_free(void *list, void (*freeit)(void *data)) 71void dlist_free(struct double_list *list, void (*freeit)(void *data))
84{ 72{
85 while (list) { 73 while (list) {
86 void *pop = TOY_llist_pop(&list); 74 void *pop = list;
87 if (freeit) freeit(pop); 75 list = list->next;
88 else free(pop); 76 freeit(pop);
89 77 // Bail out also if list is circular.
90 // End doubly linked list too. 78 if (list == pop) break;
91 if (list==pop) break;
92 } 79 }
93} 80}
94//Override bbox's names
95#define llist_pop TOY_llist_pop
96#define llist_free TOY_llist_free
97 81
98// Add an entry to the end off a doubly linked list 82// Add an entry before "list" element in (circular) doubly linked list
99static 83static
100struct double_list *dlist_add(struct double_list **list, char *data) 84struct double_list *dlist_add(struct double_list **list, char *data)
101{ 85{
102 struct double_list *line = xmalloc(sizeof(struct double_list)); 86 struct double_list *llist;
87 struct double_list *line = xmalloc(sizeof(*line));
103 88
104 line->data = data; 89 line->data = data;
105 if (*list) { 90 llist = *list;
106 line->next = *list; 91 if (llist) {
107 line->prev = (*list)->prev; 92 struct double_list *p;
108 (*list)->prev->next = line; 93 line->next = llist;
109 (*list)->prev = line; 94 p = line->prev = llist->prev;
110 } else *list = line->next = line->prev = line; 95 // (list is circular, we assume p is never NULL)
96 p->next = line;
97 llist->prev = line;
98 } else
99 *list = line->next = line->prev = line;
111 100
112 return line; 101 return line;
113} 102}
114 103
115 104
116
117struct globals { 105struct globals {
118 char *infile; 106 char *infile;
119 long prefix; 107 long prefix;
120 108
121 struct double_list *current_hunk; 109 struct double_list *current_hunk;
110
122 long oldline, oldlen, newline, newlen; 111 long oldline, oldlen, newline, newlen;
123 long linenum; 112 long linenum;
124 int context, state, filein, fileout, hunknum; 113 int context, state, hunknum;
114 int filein, fileout;
125 char *tempname; 115 char *tempname;
126 116
127 // was toys.foo:
128 int exitval; 117 int exitval;
129}; 118};
130#define TT (*ptr_to_globals) 119#define TT (*ptr_to_globals)
@@ -193,7 +182,6 @@ static void finish_oldfile(void)
193static void fail_hunk(void) 182static void fail_hunk(void)
194{ 183{
195 if (!TT.current_hunk) return; 184 if (!TT.current_hunk) return;
196 TT.current_hunk->prev->next = NULL;
197 185
198 fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", TT.hunknum, TT.oldline, TT.newline); 186 fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", TT.hunknum, TT.oldline, TT.newline);
199 TT.exitval = 1; 187 TT.exitval = 1;
@@ -202,7 +190,8 @@ static void fail_hunk(void)
202 // this file and advance to next file. 190 // this file and advance to next file.
203 191
204 TT.state = 2; 192 TT.state = 2;
205 llist_free(TT.current_hunk, do_line); 193 TT.current_hunk->prev->next = NULL;
194 dlist_free(TT.current_hunk, do_line);
206 TT.current_hunk = NULL; 195 TT.current_hunk = NULL;
207 196
208 // Abort the copy and delete the temporary file. 197 // Abort the copy and delete the temporary file.
@@ -308,7 +297,8 @@ static int apply_one_hunk(void)
308 fdprintf(2, "NOT: %s\n", plist->data); 297 fdprintf(2, "NOT: %s\n", plist->data);
309 298
310 TT.state = 3; 299 TT.state = 3;
311 check = llist_pop(&buf); 300 check = buf;
301 buf = buf->next;
312 check->prev->next = buf; 302 check->prev->next = buf;
313 buf->prev = check->prev; 303 buf->prev = check->prev;
314 do_line(check); 304 do_line(check);
@@ -335,13 +325,13 @@ static int apply_one_hunk(void)
335out: 325out:
336 // We have a match. Emit changed data. 326 // We have a match. Emit changed data.
337 TT.state = "-+"[reverse ^ dummy_revert]; 327 TT.state = "-+"[reverse ^ dummy_revert];
338 llist_free(TT.current_hunk, do_line); 328 dlist_free(TT.current_hunk, do_line);
339 TT.current_hunk = NULL; 329 TT.current_hunk = NULL;
340 TT.state = 1; 330 TT.state = 1;
341done: 331done:
342 if (buf) { 332 if (buf) {
343 buf->prev->next = NULL; 333 buf->prev->next = NULL;
344 llist_free(buf, do_line); 334 dlist_free(buf, do_line);
345 } 335 }
346 336
347 return TT.state; 337 return TT.state;