Fix insert_object to remove from old parent before inserting
The old code inserted the object into the new parent first, then tried to remove it from the old parent. This corrupted the sibling chain because the object's sibling pointer was already modified. The Z-spec says "if O already has a parent, it is first removed." Now delegates to remove_object() before inserting.
This commit is contained in:
parent
e61dcc3ac4
commit
38e60ae40c
1 changed files with 8 additions and 27 deletions
|
|
@ -330,40 +330,21 @@ class ZObjectParser:
|
|||
self.set_sibling(objectnum, 0)
|
||||
|
||||
def insert_object(self, parent_object, new_child):
|
||||
"""Prepend object NEW_CHILD to the list of PARENT_OBJECT's children."""
|
||||
"""Prepend object NEW_CHILD to the list of PARENT_OBJECT's children.
|
||||
|
||||
# Remember all the original pointers within the new_child
|
||||
[p, s, c] = self._get_parent_sibling_child(new_child)
|
||||
Per the Z-spec: if new_child already has a parent, it is first
|
||||
removed from that parent's child list, then made the first child
|
||||
of parent_object."""
|
||||
|
||||
# First insert new_child intto the parent_object
|
||||
# Remove from old parent first (spec says "first removed")
|
||||
self.remove_object(new_child)
|
||||
|
||||
# Now insert as first child of parent_object
|
||||
original_child = self.get_child(parent_object)
|
||||
self.set_sibling(new_child, original_child)
|
||||
self.set_parent(new_child, parent_object)
|
||||
self.set_child(parent_object, new_child)
|
||||
|
||||
if p == 0: # no need to 'remove' new_child, since it wasn't in a tree
|
||||
return
|
||||
|
||||
# Hunt down and remove the new_child from its old location
|
||||
item = self.get_child(p)
|
||||
if item == 0:
|
||||
# new_object claimed to have parent p, but p has no children!?
|
||||
raise ZObjectMalformedTree
|
||||
elif item == new_child: # done! new_object was head of list
|
||||
self.set_child(p, s) # note that s might be 0, that's fine.
|
||||
else: # walk across list of sibling links
|
||||
prev = item
|
||||
current = self.get_sibling(item)
|
||||
while current != 0:
|
||||
if current == new_child:
|
||||
self.set_sibling(prev, s) # s might be 0, that's fine.
|
||||
break
|
||||
prev = current
|
||||
current = self.get_sibling(current)
|
||||
else:
|
||||
# we reached the end of the list, never got a match
|
||||
raise ZObjectMalformedTree
|
||||
|
||||
def get_shortname(self, objectnum):
|
||||
"""Return 'short name' of object number OBJECTNUM as ascii string."""
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue