package com.sun.electric.tool.generator.flag;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import com.sun.electric.database.hierarchy.Cell;
import com.sun.electric.database.hierarchy.Export;
import com.sun.electric.database.hierarchy.Library;
import com.sun.electric.database.hierarchy.View;
import com.sun.electric.database.hierarchy.Cell.CellGroup;
import com.sun.electric.database.network.NetworkTool;
import com.sun.electric.database.prototype.PortCharacteristic;
import com.sun.electric.tool.Job;
import com.sun.electric.tool.JobException;
public class FlagLibraryCheckerJob extends Job {
private static final long serialVersionUID = 0;
private void prln(String msg) {System.out.println(msg);}
private Set<CellGroup> getCellGroupsToCheck() {
Set<CellGroup> groupsToCheck = new HashSet<CellGroup>();
for (Iterator<Library> liIt=Library.getLibraries(); liIt.hasNext();) {
Library lib = liIt.next();
for (Iterator<Cell> cellIt=lib.getCells(); cellIt.hasNext();) {
Cell cell = cellIt.next();
if (cell.isSchematic()) {
FlagAnnotations ann = new FlagAnnotations(cell);
if (ann!=null && ann.isAtomic()) {
groupsToCheck.add(cell.getCellGroup());
}
}
}
}
return groupsToCheck;
}
private Cell findLayoutCell(CellGroup cg) {
Cell layCell = null;
for (Iterator<Cell> cIt=cg.getCells(); cIt.hasNext();) {
Cell c = cIt.next();
if (c.getView()==View.LAYOUT) {
if (layCell!=null) {
prln(" Cell group has more than one layout Cell");
break;
}
layCell = c;
}
}
return layCell;
}
private void checkCell(Cell c) {
Rectangle2D bnds = c.findEssentialBounds();
if (bnds==null) {
prln("Stage: "+c.getName()+" is missing essential bounds");
return;
}
for (Iterator it=c.getExports(); it.hasNext();) {
Export e = (Export) it.next();
// if (Utils.isPwrGnd(e)) {
// PortInst pi = e.getOriginalPort();
// if (!Utils.onBounds(pi, bnds, 0)) {
// prln("Cell: "+c.getName()+", Export: "+e.getName()+
// " Export not on Cell Bounding Box");
// prln(" Bounding box: "+bnds.toString());
// prln(" Port Center: "+pi.getCenter().toString());
// Utils.onBounds(pi, bnds, 0);
// }
// double w = LayoutLib.widestWireWidth(pi);
// if (w!=9) {
// prln("Cell: "+c.getName()+", power or ground Export: "+
// e.getName()+" has width: "+w);
// }
// } else {
PortCharacteristic pc = e.getCharacteristic();
if (pc!=PortCharacteristic.PWR && pc!=PortCharacteristic.GND &&
pc!=PortCharacteristic.IN && pc!=PortCharacteristic.OUT &&
pc!=PortCharacteristic.BIDIR) {
prln("Cell: "+c.getName()+" Export "+e+" has undesired characteristic: "+pc);
}
// }
}
}
private void checkCellGroup(CellGroup cg) {
prln(" Checking layout: "+cg.getName());
Cell layCell = findLayoutCell(cg);
if (layCell==null) {
prln(" Cell group has no layout Cell");
return;
}
checkCell(layCell);
}
private void checkCellGroups(Collection<CellGroup> cellGroups) {
for (CellGroup cg : cellGroups) {
checkCellGroup(cg);
}
}
@Override
public boolean doIt() throws JobException {
Set<CellGroup> cellsToCheck = getCellGroupsToCheck();
prln("FLAG Found "+cellsToCheck.size()+" atomic Cell groups");
checkCellGroups(cellsToCheck);
return true;
}
public FlagLibraryCheckerJob() {
super("FLAG library checker", NetworkTool.getNetworkTool(), Job.Type.CLIENT_EXAMINE, null, null, Job.Priority.USER);
startJob();
}
}