Send commitlog mailing list submissions to
        commitlog@lists.openmoko.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.openmoko.org/mailman/listinfo/commitlog
or, via email, send a message with subject or body 'help' to
        commitlog-requ...@lists.openmoko.org

You can reach the person managing the list at
        commitlog-ow...@lists.openmoko.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of commitlog digest..."
Today's Topics:

   1. r5713 - trunk/eda/fped (wer...@docs.openmoko.org)
   2. r5714 - trunk/eda/fped (wer...@docs.openmoko.org)
   3. r5715 - trunk/eda/fped (wer...@docs.openmoko.org)
   4. r5716 - trunk/eda/fped (wer...@docs.openmoko.org)
--- Begin Message ---
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 */
 };




--- End Message ---
--- Begin Message ---
Author: werner
Date: 2009-11-27 20:18:44 +0100 (Fri, 27 Nov 2009)
New Revision: 5714

Modified:
   trunk/eda/fped/inst.c
Log:
Fixed some bugs in the vector list re-ordering function. This should work now,
but there's another problem in the dumping code that still spoils the fun.

- inst.c (do_move_to_vec): marking algorithm propagated an uninitialized value
- inst.c (do_move_to_vec): we have to clear the marks of vectors that are 
  before the vector being moved, because they will still be visited and 
  propagated



Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c       2009-11-27 16:23:35 UTC (rev 5713)
+++ trunk/eda/fped/inst.c       2009-11-27 19:18:44 UTC (rev 5714)
@@ -635,11 +635,14 @@
         * 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
+        * We're mainly 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)
+       for (v = frame->vecs; v != vec; v = v->next)
+               v->mark = 0;
+       vec->mark = 1;
+       for (v = vec->next; v && v != to_vec; v = v->next)
                v->mark = v->base ? v->base->mark : 0;
        if (!v)
                return;
@@ -647,6 +650,9 @@
        /*
         * All the marked vectors appearing on the list before the new base
         * are moved after the new base, preserving their order.
+        *
+        * Start at frame->vecs, not "vec", so that we move the the vector
+        * being rebased as well.
         */
        anchor = &to_vec->next;
        walk = &frame->vecs;




--- End Message ---
--- Begin Message ---
Author: werner
Date: 2009-11-27 20:55:25 +0100 (Fri, 27 Nov 2009)
New Revision: 5715

Modified:
   trunk/eda/fped/dump.c
   trunk/eda/fped/dump.h
   trunk/eda/fped/gui_frame.c
Log:
Vector name generation could produce duplicates if vectors were moved or 
deleted. The new algorithm checks for collisions and also reduces the number
of allocations.

- dump.c (generate_name): store the name in the vector being named
- dump.c (generate_name): compare the new name against all names in use
- dump.c (base_name, obj_base_name, print_label): don't allocate the name
- dump.c: changed all users of the above functions accordingly



Modified: trunk/eda/fped/dump.c
===================================================================
--- trunk/eda/fped/dump.c       2009-11-27 19:18:44 UTC (rev 5714)
+++ trunk/eda/fped/dump.c       2009-11-27 19:55:25 UTC (rev 5715)
@@ -260,41 +260,51 @@
 /* ----- vectors and objects ----------------------------------------------- */
 
 
-static char *generate_name(const struct vec *base)
+static void generate_name(struct vec *base)
 {
-       const struct vec *walk;
-       int n;
+       char tmp[10]; /* plenty */
+       const char *s;
+       struct vec *walk;
+       int n = 0;
 
-       n = 0;
-       for (walk = base->frame->vecs; walk != base; walk = walk->next)
+       while (1) {
+               sprintf(tmp, "__%d", n);
+               s = unique(tmp);
+               for (walk = base->frame->vecs; walk; walk = walk->next)
+                       if (walk->name == s)
+                               break;
+               if (!walk)
+                       break;
                n++;
-       return stralloc_printf("__%d", n);
+       }
+       base->name = s;
 }
 
 
-static char *base_name(const struct vec *base, const struct vec *next)
+static const char *base_name(struct vec *base, const struct vec *next)
 {
        if (!base)
-               return stralloc("@");
+               return "@";
        if (next && base->next == next)
-               return stralloc(".");
-       if (base->name)
-               return stralloc(base->name);
-       return generate_name(base);
+               return ".";
+       if (!base->name)
+               generate_name(base);
+       return base->name;
 }
 
 
-static char *obj_base_name(const struct vec *base, const struct vec *prev)
+static const char *obj_base_name(struct vec *base, const struct vec *prev)
 {
        if (base && base == prev)
-               return stralloc(".");
+               return ".";
        return base_name(base, NULL);
 }
 
 
 char *print_obj(const struct obj *obj, const struct vec *prev)
 {
-       char *base, *s, *s1, *s2, *s3;
+       const char *base, *s1, *s3;
+       char *s, *s2;
 
        base = obj_base_name(obj->base, prev);
        switch (obj->type) {
@@ -306,14 +316,12 @@
                s1 = obj_base_name(obj->u.line.other, prev);
                s2 = unparse(obj->u.line.width);
                s = stralloc_printf("line %s %s %s", base, s1, s2);
-               free(s1);
                free(s2);
                break;
        case ot_rect:
                s1 = obj_base_name(obj->u.rect.other, prev);
                s2 = unparse(obj->u.rect.width);
                s = stralloc_printf("rect %s %s %s", base, s1, s2);
-               free(s1);
                free(s2);
                break;
        case ot_pad:
@@ -337,26 +345,23 @@
                s = stralloc_printf("%spad \"%s\" %s %s%s",
                    obj->u.pad.rounded ? "r" : "",
                    obj->u.pad.name, base, s1, s2);
-               free(s1);
                break;
        case ot_arc:
                s1 = obj_base_name(obj->u.arc.start, prev);
-               s3 = unparse(obj->u.arc.width);
+               s2 = unparse(obj->u.arc.width);
                if (obj->u.arc.start == obj->u.arc.end) {
-                       s = stralloc_printf("circ %s %s %s", base, s1, s3);
+                       s = stralloc_printf("circ %s %s %s", base, s1, s2);
                } else {
-                       s2 = obj_base_name(obj->u.arc.end, prev);
+                       s3 = obj_base_name(obj->u.arc.end, prev);
                        s = stralloc_printf("arc %s %s %s %s",
-                           base, s1, s2, s3);
+                           base, s1, s3, s2);
                        free(s2);
                }
-               free(s1);
-               free(s3);
+               free(s2);
                break;
        default:
                abort();
        }
-       free(base);
        return s;
 }
 
@@ -373,14 +378,12 @@
 
 static char *print_meas_base(struct vec *base)
 {
-       char *name, *res;
+       const char *name;
 
        name = base_name(base, NULL);
        if (base->frame == root_frame)
-               return name;
-       res = stralloc_printf("%s.%s", base->frame->name, name);
-       free(name);
-       return res;
+               return stralloc(name);
+       return stralloc_printf("%s.%s", base->frame->name, name);
 }
 
 
@@ -423,18 +426,18 @@
 /* ----- print vector ------------------------------------------------------ */
 
 
-char *print_label(const struct vec *vec)
+const char *print_label(struct vec *vec)
 {
-       if (vec->name)
-               return stralloc(vec->name);
-       else
-               return generate_name(vec);
+       if (!vec->name)
+               generate_name(vec);
+       return vec->name;
 }
 
 
 char *print_vec(const struct vec *vec)
 {
-       char *base, *x, *y, *s;
+       const char *base;
+       char *x, *y, *s;
 
        base = base_name(vec->base, vec);
        x = unparse(vec->x);
@@ -444,7 +447,6 @@
        else {
                s = stralloc_printf("vec %s(%s, %s)", base, x, y);
        }
-       free(base);
        free(x);
        free(y);
        return s;
@@ -461,7 +463,8 @@
        struct obj *obj;
        struct order *order;
        const struct order *item;
-       char *s, *s1;
+       char *s;
+       const char *s1;
 
        if (frame->dumped)
                return;

Modified: trunk/eda/fped/dump.h
===================================================================
--- trunk/eda/fped/dump.h       2009-11-27 19:18:44 UTC (rev 5714)
+++ trunk/eda/fped/dump.h       2009-11-27 19:55:25 UTC (rev 5715)
@@ -34,7 +34,7 @@
 };
 
 
-char *print_label(const struct vec *vec);
+const char *print_label(struct vec *vec);
 char *print_vec(const struct vec *vec);
 char *print_obj(const struct obj *obj, const struct vec *prev);
 char *print_meas(const struct obj *obj);

Modified: trunk/eda/fped/gui_frame.c
===================================================================
--- trunk/eda/fped/gui_frame.c  2009-11-27 19:18:44 UTC (rev 5714)
+++ trunk/eda/fped/gui_frame.c  2009-11-27 19:55:25 UTC (rev 5715)
@@ -1167,9 +1167,7 @@
                                label_in_box_fg(item->obj->list_widget,
                                    COLOR_ITEM_ERROR);
                } else {
-                       s = print_label(item->vec);
-                       t = stralloc_printf("%s: ", s);
-                       free(s);
+                       t = stralloc_printf("%s: ", print_label(item->vec));
                        item_label(tab, t, 0, n, NULL, NULL);
 
                        s = print_vec(item->vec);




--- End Message ---
--- Begin Message ---
Author: werner
Date: 2009-11-28 00:31:03 +0100 (Sat, 28 Nov 2009)
New Revision: 5716

Modified:
   trunk/eda/fped/inst.c
Log:
- inst.c (inst_select): cycle through instances globally, not only within the
  same priority



Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c       2009-11-27 19:55:25 UTC (rev 5715)
+++ trunk/eda/fped/inst.c       2009-11-27 23:31:03 UTC (rev 5716)
@@ -226,13 +226,13 @@
                                }
                        }
                }
-               if (select_next) {
-                       selected_inst = next ? next : first;
-                       goto selected;
-               }
-               if (selected_inst)
-                       goto selected;
        }
+       if (select_next) {
+               selected_inst = next ? next : first;
+               goto selected;
+       }
+       if (selected_inst)
+               goto selected;
 
        /* give vectors a second chance */
 




--- End Message ---
_______________________________________________
commitlog mailing list
commitlog@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/commitlog

Reply via email to