From ac535d6e03c221d389a798af55f096f92c9bf3ff Mon Sep 17 00:00:00 2001 From: werner Date: Tue, 27 Apr 2010 22:36:46 +0000 Subject: [PATCH] Deleting things often left measurements behind. Fixed these bugs, enhanced %del to also delete frames and items in other frames than the current one, and added the corresponding regression tests. - fpd.y, README: %del can now also delete frames - test/del_frame: regression test for frame deletion - fpd.y: moved all debug items into debug_item, so that they can be invoked after defining measurements - README: clarified that object labels aren't entirely hidden in the GUI - delete.c (delete_references): also delete measurements referencing the frame (test/del_frame) - fpd.y (dbg_link_frame): described why we need base_frame in addition to base_vec - fpd.y, README: %del can now also reach into frames other than the current one - delete.c (do_delete_vec): also delete references in the root frame, i.e., measurements (tests/del_vec) git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5947 99fdad57-331a-0410-800a-d7fa5415bdb3 --- README | 17 +++++++------ delete.c | 13 +++++++++- fpd.y | 62 +++++++++++++++++++++++++++++++++++++--------- test/del_frame | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/del_vec | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 204 insertions(+), 19 deletions(-) create mode 100755 test/del_frame create mode 100755 test/del_vec diff --git a/README b/README index df0437b..3a39d15 100644 --- a/README +++ b/README @@ -588,7 +588,7 @@ Experimental: debugging directives For debugging and regression tests, fped supports the following commands, most of which mimick the effect of GUI operations: -%del +%del %move [] %frame %print @@ -596,14 +596,17 @@ most of which mimick the effect of GUI operations: %exit %tsort { - | + | [] ... } -%del and %move take as their first argument the name of the vector or -object to manipulate. For this purpose, also objects can be labeled. +%del removes the specified item. This can be a vector, an object, or +a frame. If the vector or object is in a different frame than the +current, its name is qualified with the frame name, e.g., "foo.obj". -Object labels behave like vector labels and share the same name space. -They are not shown anywhere in the GUI. +For this purpose, also objects can be labeled. Object labels behave like +vector labels and share the same name space. They are not normally +accessible in the GUI. (You can see them in the code view.) -%move sets an anchor point to the vector named as its last argument. -The anchor point is identified by index as follows: +%move take as its first argument the name of the vector or object to +manipulate. %move sets an anchor point to the vector named as its last +argument. The anchor point is identified by index as follows: anchor index vec/frame line/rect/pad arc measurement -------------- --------- ------------- ------------ ----------- diff --git a/delete.c b/delete.c index 93ac9ce..e53c983 100644 --- a/delete.c +++ b/delete.c @@ -177,6 +177,7 @@ static void do_delete_vec(struct vec *vec) delete_vecs_by_ref(vec->frame->vecs, vec); delete_objs_by_ref(&vec->frame->objs, vec); + delete_objs_by_ref(&root_frame->objs, vec); /* catch measurements */ } @@ -522,9 +523,19 @@ static void delete_references(const struct frame *ref) for (frame = frames; frame; frame = frame->next) for (obj = frame->objs; obj; obj = obj->next) - if (obj->type == ot_frame) + switch (obj->type) { + case ot_frame: if (obj->u.frame.ref == ref) do_delete_obj(obj); + break; + case ot_meas: + if (obj->base->frame == ref || + obj->u.meas.high->frame == ref) + do_delete_obj(obj); + break; + default: + break; + } for (obj = ref->objs; obj; obj = obj->next) if (obj->type == ot_frame) if (obj->u.frame.ref->active_ref == obj) diff --git a/fpd.y b/fpd.y index 43446ee..4f5fb5c 100644 --- a/fpd.y +++ b/fpd.y @@ -178,22 +178,48 @@ static struct obj *new_obj(enum obj_type type) } -static int dbg_delete(const char *name) +static int dbg_delete(const char *frame_name, const char *name) { struct vec *vec; struct obj *obj; + struct frame *frame; - vec = find_vec(curr_frame, name); + if (!frame_name) + frame = curr_frame; + else { + frame = find_frame(frame_name); + if (!frame) { + yyerrorf("unknown frame \"%s\"", frame_name); + return 0; + } + } + vec = find_vec(frame, name); if (vec) { delete_vec(vec); return 1; } - obj = find_obj(curr_frame, name); + obj = find_obj(frame, name); if (obj) { delete_obj(obj); return 1; } - yyerrorf("unknown item \"%s\"", name); + if (!frame_name) { + frame = find_frame(name); + if (frame) { + if (curr_frame == frame) { + yyerrorf("a frame can't delete itself"); + return 0; + } + if (last_frame == frame) + last_frame = frame->prev; + delete_frame(frame); + return 1; + } + } + if (frame_name) + yyerrorf("unknown item \"%s.%s\"", frame_name, name); + else + yyerrorf("unknown item \"%s\"", name); return 0; } @@ -238,12 +264,19 @@ static int dbg_move(const char *name, int anchor, const char *dest) * @@@ This is very similar to what we do in rule "obj". Consider merging. */ +/* + * We need to pass base_frame and base_vec, not just the vector (with the + * frame implied) since we can also reference the frame's origin, whose + * "vector" is NULL. + */ + static int dbg_link_frame(const char *frame_name, struct frame *base_frame, struct vec *base_vec) { struct frame *frame; struct obj *obj; + assert(!base_vec || base_vec->frame == base_frame); frame = find_frame(frame_name); if (!frame) { yyerrorf("unknown frame \"%s\"", frame_name); @@ -496,9 +529,20 @@ frame_item: } $2->name = $1; } - | TOK_DBG_DEL ID + | debug_item + ; + +debug_item: + TOK_DBG_DEL ID { - if (!dbg_delete($2)) + append_root_frame(); + if (!dbg_delete(NULL, $2)) + YYABORT; + } + | TOK_DBG_DEL ID '.' ID + { + append_root_frame(); + if (!dbg_delete($2, $4)) YYABORT; } | TOK_DBG_MOVE ID opt_num ID @@ -516,11 +560,7 @@ frame_item: if (!dbg_print($2)) YYABORT; } - | debug_item - ; - -debug_item: - TOK_DBG_DUMP + | TOK_DBG_DUMP { /* * It's okay to do append the root frame multiple diff --git a/test/del_frame b/test/del_frame new file mode 100755 index 0000000..f07ecfd --- /dev/null +++ b/test/del_frame @@ -0,0 +1,67 @@ +#!/bin/sh +. ./Common + +############################################################################### + +fped_fail "delete frame: can't self-destruct" < f.v + +%del f +EOF +expect < v +%del v +EOF +expect < f.v +%del f.v +EOF +expect <