[pacman-dev] Problems with alpm_list_remove(_node)
Dan McGee
dpmcgee at gmail.com
Sun Nov 11 11:45:36 EST 2007
On Nov 9, 2007 3:25 PM, Aaron Griffin <aaronmgriffin at gmail.com> wrote:
>
> On Nov 9, 2007 3:20 PM, Dan McGee <dpmcgee at gmail.com> wrote:
> > On Nov 9, 2007 2:55 PM, Xavier <shiningxc at gmail.com> wrote:
> > > On Fri, Nov 09, 2007 at 08:54:52PM +0100, Nagy Gabor wrote:
> > > > Some more issues:
> > > > 1. You simply forgot about resetting the tail pointer when you remove
> > > > the last element with alpm_list_remove.
> > >
> > > Yep, that's what explains the requiredby problem I noticed :
> > > http://www.archlinux.org/pipermail/pacman-dev/2007-November/009919.html
> > > Good catch :)
> >
> > This should fix it.
> >
> > diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c
> > index 6f6ee8f..f2e57c0 100644
> > --- a/lib/libalpm/alpm_list.c
> > +++ b/lib/libalpm/alpm_list.c
> > @@ -311,6 +311,9 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystac
> > k, const void *needl
> > /* Normal case, non-head node */
> > if(i->next) {
> > i->next->prev = i->prev;
> > + } else {
> > + /* We are on the tail node, need to upda
> > te the back ref */
> > + haystack->prev = i->prev;
> > }
> > if(i->prev) {
> > i->prev->next = i->next;
>
> Be careful here - the special cases or head nodes typically needed to
> be added after the "if next" and "if prev" stuff already there, as
> they never took the terminal nodes to be any different. By that, I
> mean
>
> if(next) { do stuff }
> if(prev) { do stuff }
> if(!next) { tail node }
>
> I'm sure it could be restructured, but I'll leave that for the CS students 8)
OK, try 2. :)
diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c
index d3a7951..465c1a8 100644
--- a/lib/libalpm/alpm_list.c
+++ b/lib/libalpm/alpm_list.c
@@ -301,14 +301,22 @@ alpm_list_t SYMEXPORT
*alpm_list_remove(alpm_list_t *haystack, const void *needl
if(i == haystack) {
/* Special case: removing the head
node which has a back reference to
* the tail node */
- /* The item found is the first in the chain */
haystack = i->next;
if(haystack) {
haystack->prev = i->prev;
}
i->prev = NULL;
+ } else if(i == haystack->prev) {
+ /* Special case: removing the tail
node, so we need to fix the back
+ * reference on the head node. We also
know tail != head. */
+ if(i->prev) {
+ /* i->next should always be null */
+ i->prev->next = i->next;
+ haystack->prev = i->prev;
+ i->prev = NULL;
+ }
} else {
- /* Normal case, non-head node */
+ /* Normal case, non-head and non-tail node */
if(i->next) {
i->next->prev = i->prev;
}
More information about the pacman-dev
mailing list