patch: simplify double list helpers
function old new delta dlist_free - 29 +29 fail_hunk 130 132 +2 patch_main 1987 1982 -5 dlist_add 59 54 -5 TOY_llist_pop 9 - -9 TOY_llist_free 54 - -54 ------------------------------------------------------------------------------ (add/remove: 1/2 grow/shrink: 1/2 up/down: 31/-73) Total: -42 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
b82ae98ea4
commit
400ff226c2
@ -56,75 +56,64 @@
|
||||
|
||||
#include "libbb.h"
|
||||
|
||||
|
||||
// libbb candidate?
|
||||
|
||||
struct double_list {
|
||||
struct double_list *next;
|
||||
struct double_list *prev;
|
||||
char *data;
|
||||
};
|
||||
|
||||
// Return the first item from the list, advancing the list (which must be called
|
||||
// as &list)
|
||||
static
|
||||
void *TOY_llist_pop(void *list)
|
||||
{
|
||||
// I'd use a void ** for the argument, and even accept the typecast in all
|
||||
// callers as documentation you need the &, except the stupid compiler
|
||||
// would then scream about type-punned pointers. Screw it.
|
||||
void **llist = (void **)list;
|
||||
void **next = (void **)*llist;
|
||||
*llist = *next;
|
||||
|
||||
return (void *)next;
|
||||
}
|
||||
|
||||
// Free all the elements of a linked list
|
||||
// if freeit!=NULL call freeit() on each element before freeing it.
|
||||
// Call freeit() on each element before freeing it.
|
||||
static
|
||||
void TOY_llist_free(void *list, void (*freeit)(void *data))
|
||||
void dlist_free(struct double_list *list, void (*freeit)(void *data))
|
||||
{
|
||||
while (list) {
|
||||
void *pop = TOY_llist_pop(&list);
|
||||
if (freeit) freeit(pop);
|
||||
else free(pop);
|
||||
|
||||
// End doubly linked list too.
|
||||
if (list==pop) break;
|
||||
void *pop = list;
|
||||
list = list->next;
|
||||
freeit(pop);
|
||||
// Bail out also if list is circular.
|
||||
if (list == pop) break;
|
||||
}
|
||||
}
|
||||
//Override bbox's names
|
||||
#define llist_pop TOY_llist_pop
|
||||
#define llist_free TOY_llist_free
|
||||
|
||||
// Add an entry to the end off a doubly linked list
|
||||
// Add an entry before "list" element in (circular) doubly linked list
|
||||
static
|
||||
struct double_list *dlist_add(struct double_list **list, char *data)
|
||||
{
|
||||
struct double_list *line = xmalloc(sizeof(struct double_list));
|
||||
struct double_list *llist;
|
||||
struct double_list *line = xmalloc(sizeof(*line));
|
||||
|
||||
line->data = data;
|
||||
if (*list) {
|
||||
line->next = *list;
|
||||
line->prev = (*list)->prev;
|
||||
(*list)->prev->next = line;
|
||||
(*list)->prev = line;
|
||||
} else *list = line->next = line->prev = line;
|
||||
llist = *list;
|
||||
if (llist) {
|
||||
struct double_list *p;
|
||||
line->next = llist;
|
||||
p = line->prev = llist->prev;
|
||||
// (list is circular, we assume p is never NULL)
|
||||
p->next = line;
|
||||
llist->prev = line;
|
||||
} else
|
||||
*list = line->next = line->prev = line;
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct globals {
|
||||
char *infile;
|
||||
long prefix;
|
||||
|
||||
struct double_list *current_hunk;
|
||||
|
||||
long oldline, oldlen, newline, newlen;
|
||||
long linenum;
|
||||
int context, state, filein, fileout, hunknum;
|
||||
int context, state, hunknum;
|
||||
int filein, fileout;
|
||||
char *tempname;
|
||||
|
||||
// was toys.foo:
|
||||
int exitval;
|
||||
};
|
||||
#define TT (*ptr_to_globals)
|
||||
@ -193,7 +182,6 @@ static void finish_oldfile(void)
|
||||
static void fail_hunk(void)
|
||||
{
|
||||
if (!TT.current_hunk) return;
|
||||
TT.current_hunk->prev->next = NULL;
|
||||
|
||||
fdprintf(2, "Hunk %d FAILED %ld/%ld.\n", TT.hunknum, TT.oldline, TT.newline);
|
||||
TT.exitval = 1;
|
||||
@ -202,7 +190,8 @@ static void fail_hunk(void)
|
||||
// this file and advance to next file.
|
||||
|
||||
TT.state = 2;
|
||||
llist_free(TT.current_hunk, do_line);
|
||||
TT.current_hunk->prev->next = NULL;
|
||||
dlist_free(TT.current_hunk, do_line);
|
||||
TT.current_hunk = NULL;
|
||||
|
||||
// Abort the copy and delete the temporary file.
|
||||
@ -308,7 +297,8 @@ static int apply_one_hunk(void)
|
||||
fdprintf(2, "NOT: %s\n", plist->data);
|
||||
|
||||
TT.state = 3;
|
||||
check = llist_pop(&buf);
|
||||
check = buf;
|
||||
buf = buf->next;
|
||||
check->prev->next = buf;
|
||||
buf->prev = check->prev;
|
||||
do_line(check);
|
||||
@ -335,13 +325,13 @@ static int apply_one_hunk(void)
|
||||
out:
|
||||
// We have a match. Emit changed data.
|
||||
TT.state = "-+"[reverse ^ dummy_revert];
|
||||
llist_free(TT.current_hunk, do_line);
|
||||
dlist_free(TT.current_hunk, do_line);
|
||||
TT.current_hunk = NULL;
|
||||
TT.state = 1;
|
||||
done:
|
||||
if (buf) {
|
||||
buf->prev->next = NULL;
|
||||
llist_free(buf, do_line);
|
||||
dlist_free(buf, do_line);
|
||||
}
|
||||
|
||||
return TT.state;
|
||||
|
Loading…
Reference in New Issue
Block a user