r5713 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Fri Nov 27 17:23:36 CET 2009


Author: werner
Date: 2009-11-27 17:23:35 +0100 (Fri, 27 Nov 2009)
New Revision: 5713

Modified:
   trunk/eda/fped/gui_tool.c
   trunk/eda/fped/inst.c
   trunk/eda/fped/obj.h
Log:
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.



Modified: trunk/eda/fped/gui_tool.c
===================================================================
--- trunk/eda/fped/gui_tool.c	2009-11-12 12:32:12 UTC (rev 5712)
+++ trunk/eda/fped/gui_tool.c	2009-11-27 16:23:35 UTC (rev 5713)
@@ -918,7 +918,6 @@
 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;
 	active_ops = NULL;

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2009-11-12 12:32:12 UTC (rev 5712)
+++ trunk/eda/fped/inst.c	2009-11-27 16:23:35 UTC (rev 5713)
@@ -612,6 +612,58 @@
 }
 
 
+/*
+ * 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 @@
 	.find_point	= find_point_vec,
 	.anchors	= vec_op_anchors,
 	.draw_move	= draw_move_vec,
+	.do_move_to	= do_move_to_vec,
 };
 
 

Modified: trunk/eda/fped/obj.h
===================================================================
--- trunk/eda/fped/obj.h	2009-11-12 12:32:12 UTC (rev 5712)
+++ trunk/eda/fped/obj.h	2009-11-27 16:23:35 UTC (rev 5713)
@@ -105,6 +105,9 @@
 	/* 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 */
 };




More information about the commitlog mailing list