diff --git a/bplane/bpMain.c b/bplane/bpMain.c index f1c6c43c..93f94379 100644 --- a/bplane/bpMain.c +++ b/bplane/bpMain.c @@ -40,6 +40,7 @@ #include "utils/utils.h" #include "utils/malloc.h" #include "database/database.h" +#include "textio/textio.h" #include "utils/geometry.h" #include "bplane/bplaneInt.h" @@ -180,6 +181,11 @@ void BPDelete(BPlane *bp, void *element) Element *e = element; ASSERT(e,"BPDelete"); + if (bp->bp_count == 0) + { + TxError("Error: Attempt to delete instance from empty cell!\n"); + return; + } bp->bp_count--; /* if element was on edge of bbox, bbox may no longer diff --git a/database/DBcell.c b/database/DBcell.c index c0dbae2f..0bc26090 100644 --- a/database/DBcell.c +++ b/database/DBcell.c @@ -65,6 +65,7 @@ dbInstanceUnplace(CellUse *use) * or else we could leave the subcell tile plane in a weird * state. */ + BPDelete(use->cu_parent->cd_cellPlane, use); } diff --git a/database/DBcellsubr.c b/database/DBcellsubr.c index 16d70e0e..1ade3ea5 100644 --- a/database/DBcellsubr.c +++ b/database/DBcellsubr.c @@ -30,6 +30,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "tiles/tile.h" #include "database/database.h" #include "database/databaseInt.h" +#include "dbwind/dbwind.h" #include "utils/signals.h" /* Forward declarations */ @@ -214,6 +215,9 @@ DBCellClearDef(cellDef) /* Remove all defined properties */ DBPropClearAll(cellDef); + /* Remove any elements associated with the cell */ + DBWElementClearDef(cellDef); + SigEnableInterrupts(); } diff --git a/database/DBtiles.c b/database/DBtiles.c index 70e8d401..347ba461 100644 --- a/database/DBtiles.c +++ b/database/DBtiles.c @@ -811,7 +811,7 @@ DBClearCellPlane(def) /* Do not use BPDelete() inside a BPEnum loop. Use DBSrCellUses */ /* to get a linked list of cell instances, then remove each one. */ - DBSrCellUses(def, dbDeleteCellUse, (ClientData)NULL); + DBSrCellUses(def, dbDeleteCellUse, (ClientData)def); SigEnableInterrupts(); } @@ -829,9 +829,32 @@ DBClearCellPlane(def) int dbDeleteCellUse(CellUse *use, ClientData arg) { + CellDef *def = (CellDef *)arg; + CellUse *defuses, *lastuse; + dbInstanceUnplace(use); + if (UndoIsEnabled()) DBUndoCellUse(use, UNDO_CELL_DELETE); + + /* Remove use from cd_parents of the use's def */ + lastuse = (CellUse *)NULL; + for (defuses = use->cu_def->cd_parents; defuses ; defuses = defuses->cu_nextuse) + { + if (defuses == use) + { + if (lastuse) + lastuse->cu_nextuse = defuses->cu_nextuse; + else + use->cu_def->cd_parents = defuses->cu_nextuse; + defuses->cu_nextuse = (CellUse *)NULL; + break; + } + lastuse = defuses; + } + if (use->cu_id) freeMagic(use->cu_id); + freeMagic(use); + return 0; } diff --git a/dbwind/DBWelement.c b/dbwind/DBWelement.c index 9170233d..d112d66d 100644 --- a/dbwind/DBWelement.c +++ b/dbwind/DBWelement.c @@ -1239,3 +1239,46 @@ DBWElementPos(MagWindow *w, char *ename, Rect *crect) elem->rootDef->cd_flags |= CDMODIFIED; } } + +/* + * ---------------------------------------------------------------------------- + * + * DBWElementClearDef -- + * + * Removes all elements associated with the given CellDef. + * + * Results: + * None. + * + * Side effects: + * Elements are removed from the element hash. + * + * ---------------------------------------------------------------------------- + */ + +void +DBWElementClearDef(cellDef) + CellDef *cellDef; +{ + DBWElement *elem; + HashEntry *entry; + styleptr stylePtr; + HashSearch hs; + + HashStartSearch(&hs); + while ((entry = HashNext(&elementTable, &hs)) != NULL) + { + elem = (DBWElement *) HashGetValue(entry); + if (!elem) continue; + if (elem->rootDef != cellDef) continue; + + for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next) + freeMagic(stylePtr); + + if (elem->type == ELEMENT_TEXT) + freeMagic(elem->text); + + HashSetValue(entry, NULL); + freeMagic(elem); + } +} diff --git a/dbwind/dbwind.h b/dbwind/dbwind.h index 9a1486d6..d488cf16 100644 --- a/dbwind/dbwind.h +++ b/dbwind/dbwind.h @@ -217,6 +217,7 @@ extern void DBWElementAddText(); extern void DBWElementDelete(); extern void DBWElementNames(); extern void DBWElementInbox(); +extern void DBWElementClearDef(); extern void DBWElementParseFlags(); extern char *DBWPrintElements(); extern void DBWScaleElements();