mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-08-29 09:30:46 +02:00
time ago by cleaning up excess usage of "equiv" lines in the .ext file output. The hierarchical extraction code did not distinguish between node names which were output and those that were not, requiring a setting "extract do aliases" to force all node aliases to be output with "equiv" statements. So hierarchical names might be any alias, whether output or not, and "merge" and "cap" lines might contain references to nodes that were not output, causing them to be disconnected nodes. This fix handles the "extract no aliases" (default) case by flagging node names that are redundant and not output, and not creating hierarchical names with them.
246 lines
7.1 KiB
C
246 lines
7.1 KiB
C
/*
|
|
* ExtYank.c --
|
|
*
|
|
* Circuit extraction.
|
|
* Hierarchical yanking of paint and labels.
|
|
*
|
|
* *********************************************************************
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
* * software and its documentation for any purpose and without *
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
* * notice appear in all copies. The University of California *
|
|
* * makes no representations about the suitability of this *
|
|
* * software for any purpose. It is provided "as is" without *
|
|
* * express or implied warranty. Export of this software outside *
|
|
* * of the United States of America may require an export license. *
|
|
* *********************************************************************
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/extract/ExtYank.c,v 1.2 2008/06/01 18:37:42 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "utils/geofast.h"
|
|
#include "tiles/tile.h"
|
|
#include "utils/hash.h"
|
|
#include "database/database.h"
|
|
#include "utils/malloc.h"
|
|
#include "textio/textio.h"
|
|
#include "debug/debug.h"
|
|
#include "utils/styles.h"
|
|
#include "extract/extract.h"
|
|
#include "extract/extractInt.h"
|
|
|
|
Rect extSubcellArea; /* Area of currently processed subcell, clipped
|
|
* to area of interaction, in parent coords.
|
|
*/
|
|
|
|
/* Forward declarations of filter functions */
|
|
int extHierYankFunc();
|
|
int extHierLabelFunc();
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* extHierCopyLabels --
|
|
*
|
|
* Copy the label list from sourceDef to targetDef, prepending
|
|
* it to any labels already in targetDef. Does not change
|
|
* sourceDef's label list.
|
|
*
|
|
* Labels are copied in order, so the first label on sourceDef's
|
|
* list becomes the first label on targetDef's list. THIS IS
|
|
* CRITICAL TO INSURE THAT HIERARCHICAL ADJUSTMENTS CAN BE MADE
|
|
* PROPERLY; SEE extSubtreeAdjustInit() FOR AN EXPLANATION.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
extHierCopyLabels(sourceDef, targetDef)
|
|
CellDef *sourceDef, *targetDef;
|
|
{
|
|
Label *lab, *newlab, *firstLab, *lastLab;
|
|
unsigned n;
|
|
|
|
firstLab = lastLab = (Label *) NULL;
|
|
for (lab = sourceDef->cd_labels; lab; lab = lab->lab_next)
|
|
{
|
|
n = sizeof (Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1;
|
|
newlab = (Label *) mallocMagic((unsigned) n);
|
|
bcopy((char *) lab, (char *) newlab, (int) n);
|
|
|
|
if (lastLab == NULL) lastLab = firstLab = newlab;
|
|
else lastLab->lab_next = newlab, lastLab = newlab;
|
|
}
|
|
|
|
if (lastLab)
|
|
{
|
|
lastLab->lab_next = targetDef->cd_labels;
|
|
targetDef->cd_labels = firstLab;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* extHierFreeLabels --
|
|
*
|
|
* Free all the labels from 'def'.
|
|
* Leaves the label lis of 'def' pointing to NULL.
|
|
*
|
|
* This procedure exists mainly so we can trace the freeing
|
|
* of labels for debugging.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
extHierFreeLabels(def)
|
|
CellDef *def;
|
|
{
|
|
Label *lab;
|
|
|
|
for (lab = def->cd_labels; lab; lab = lab->lab_next)
|
|
freeMagic((char *) lab);
|
|
def->cd_labels = (Label *) NULL;
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* extHierYankFunc --
|
|
*
|
|
* Filter function normally called by DBArraySr to yank hierarchically the
|
|
* paint and labels from 'use'. Called for each array element. Also called
|
|
* during array extraction.
|
|
*
|
|
* Expects hy->hy_area to be the area, in use->cu_parent coordinates,
|
|
* to be yanked. What we yank will be transformed to parent coordinates
|
|
* and placed in the cell hy->hy_target. If hy->hy_prefix is TRUE, we
|
|
* will prepend all the labels we yank with the use id of this array
|
|
* element; otherwise, the labels have no prefix.
|
|
*
|
|
* WARNING:
|
|
* Only node-name labels are yanked; attributes are not.
|
|
* The hierarchical extraction code depends on this fact.
|
|
*
|
|
* Results:
|
|
* Returns 0 to cause DBArraySr to keep going.
|
|
*
|
|
* Side effects:
|
|
* Adds paint and new labels to 'hy->hy_target'.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
extHierYankFunc(use, trans, x, y, hy)
|
|
CellUse *use; /* Use that is the root of the subtree being yanked */
|
|
Transform *trans; /* Transform from coordinates of use->cu_def to those
|
|
* in use->cu_parent, for the array element (x, y).
|
|
*/
|
|
int x, y; /* Indices of this array element */
|
|
HierYank *hy; /* See comments in procedure header */
|
|
{
|
|
char labelBuf[4096];
|
|
TerminalPath tpath;
|
|
SearchContext scx;
|
|
Transform tinv;
|
|
|
|
/*
|
|
* Want scx.scx_area to be the area in coordinates of use->cu_def
|
|
* but hy->hy_area is in coordinates of use->cu_parent.
|
|
*/
|
|
GEOINVERTTRANS(trans, &tinv);
|
|
GEOTRANSRECT(&tinv, hy->hy_area, &scx.scx_area);
|
|
GEOCLIP(&scx.scx_area, &use->cu_def->cd_bbox);
|
|
|
|
scx.scx_use = use;
|
|
scx.scx_trans = *trans;
|
|
scx.scx_x = x;
|
|
scx.scx_y = y;
|
|
|
|
/* Yank the paint */
|
|
DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, hy->hy_target);
|
|
|
|
/* Yank the labels */
|
|
tpath.tp_next = tpath.tp_first = labelBuf;
|
|
tpath.tp_last = &labelBuf[sizeof labelBuf - 2];
|
|
if (hy->hy_prefix)
|
|
{
|
|
tpath.tp_next = DBPrintUseId(&scx, labelBuf, sizeof labelBuf - 3, FALSE);
|
|
*tpath.tp_next++ = '/';
|
|
}
|
|
*tpath.tp_next = '\0';
|
|
(void) DBTreeSrLabels(&scx, &DBAllButSpaceBits, 0, &tpath, TF_LABEL_ATTACH,
|
|
extHierLabelFunc, (ClientData) hy->hy_target->cu_def);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
extHierLabelFunc(scx, label, tpath, targetDef)
|
|
SearchContext *scx;
|
|
Label *label;
|
|
TerminalPath *tpath;
|
|
CellDef *targetDef;
|
|
{
|
|
char *srcp, *dstp;
|
|
Label *newlab;
|
|
int len;
|
|
|
|
/* Reject if the label falls over space */
|
|
if (label->lab_type == TT_SPACE)
|
|
return (0);
|
|
|
|
/* Reject if not a node label */
|
|
if (!extLabType(label->lab_text, LABTYPE_NAME))
|
|
return (0);
|
|
|
|
/* Determine size of new label with hierarchical name */
|
|
for (srcp = label->lab_text; *srcp++; )
|
|
/* Nothing */;
|
|
len = srcp - label->lab_text;
|
|
for (srcp = tpath->tp_first; *srcp++; )
|
|
/* Nothing */;
|
|
len += srcp - tpath->tp_first + 1;
|
|
|
|
/* Allocate new label at correct location */
|
|
newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 4));
|
|
GeoTransRect(&scx->scx_trans, &label->lab_rect, &newlab->lab_rect);
|
|
newlab->lab_just = GeoTransPos(&scx->scx_trans, label->lab_just);
|
|
newlab->lab_type = label->lab_type;
|
|
newlab->lab_flags = label->lab_flags;
|
|
newlab->lab_port = label->lab_port;
|
|
dstp = newlab->lab_text;
|
|
for (srcp = tpath->tp_first; *dstp++ = *srcp++; )
|
|
/* Nothing */;
|
|
for (--dstp, srcp = label->lab_text; *dstp++ = *srcp++; )
|
|
/* Nothing */;
|
|
|
|
newlab->lab_next = targetDef->cd_labels;
|
|
targetDef->cd_labels = newlab;
|
|
|
|
return (0);
|
|
}
|