1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-12-22 23:14:36 +02:00

When moving a vector, the list order could get confused, resulting in a

segfault, failure to update the screen content, and assigning of invalid 
references.

- gui_tools.c: removed duplicate (harmless) line 
- inst.c: when moving a vector to a new base, we may have to reorder the list
  so that the assertion vectors always follow their bases is still maintained.



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5713 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-11-27 16:23:35 +00:00
parent b6e5c6d20a
commit 2dffbfeaa9
3 changed files with 56 additions and 1 deletions

View File

@ -917,7 +917,6 @@ void tool_drag(struct coord to)
void tool_cancel_drag(void)
{
if (drag.anchors_n && drag.inst->ops->end_drag_move)
if (drag.anchors_n && drag.inst->ops->end_drag_move)
drag.inst->ops->end_drag_move();
drag.new = NULL;

53
inst.c
View File

@ -612,6 +612,58 @@ static int vec_op_anchors(struct inst *inst, struct vec ***anchors)
}
/*
* When instantiating and when dumping, we assume that bases appear in the
* frame->vecs list before vectors using them. A move may change this order.
* We therefore have to sort the list after the move.
*
* Since the list is already ordered, cleaning it up is just O(n).
*/
static void do_move_to_vec(struct inst *inst, struct inst *to, int i)
{
struct vec *to_vec = inst_get_vec(to);
struct vec *vec = inst->vec;
struct frame *frame = vec->frame;
struct vec *v, **anchor, **walk;
assert(!i);
vec->base = to_vec;
/*
* Mark the vector that's being rebased and all vectors that
* (recursively) depend on it.
*
* We're only interested in the range between the vector being moved
* and the new base. If the vector follows the base, the list is
* already in the correct order and nothing needs moving.
*/
for (v = vec; v && v != to_vec; v = v->next)
v->mark = v->base ? v->base->mark : 0;
if (!v)
return;
/*
* All the marked vectors appearing on the list before the new base
* are moved after the new base, preserving their order.
*/
anchor = &to_vec->next;
walk = &frame->vecs;
while (*walk != to_vec) {
v = *walk;
if (!v->mark)
walk = &v->next;
else {
*walk = v->next;
v->next = *anchor;
*anchor = v;
anchor = &v->next;
}
}
}
static struct inst_ops vec_ops = {
.draw = gui_draw_vec,
.hover = gui_hover_vec,
@ -620,6 +672,7 @@ static struct inst_ops vec_ops = {
.find_point = find_point_vec,
.anchors = vec_op_anchors,
.draw_move = draw_move_vec,
.do_move_to = do_move_to_vec,
};

3
obj.h
View File

@ -105,6 +105,9 @@ struct vec {
/* index into table of samples */
int n;
/* for re-ordering after a move */
int mark;
/* for the GUI */
GtkWidget *list_widget; /* NULL if items aren't shown */
};