📄 output.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Output.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.io.output;import com.sun.electric.database.IdMapper;import com.sun.electric.database.LibraryBackup;import com.sun.electric.database.Snapshot;import com.sun.electric.database.constraint.Constraints;import com.sun.electric.database.geometry.ERectangle;import com.sun.electric.database.geometry.PolyBase;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.hierarchy.EDatabase;import com.sun.electric.database.hierarchy.Library;import com.sun.electric.database.id.LibId;import com.sun.electric.database.text.TextUtils;import com.sun.electric.database.text.Version;import com.sun.electric.database.topology.PortInst;import com.sun.electric.database.variable.EditWindow_;import com.sun.electric.database.variable.ElectricObject;import com.sun.electric.database.variable.VarContext;import com.sun.electric.database.variable.Variable;import com.sun.electric.technology.Technology;import com.sun.electric.technology.technologies.Schematics;import com.sun.electric.tool.Job;import com.sun.electric.tool.JobException;import com.sun.electric.tool.Listener;import com.sun.electric.tool.Tool;import com.sun.electric.tool.cvspm.CVS;import com.sun.electric.tool.cvspm.CVSLibrary;import com.sun.electric.tool.io.FileType;import com.sun.electric.tool.io.IOTool;import com.sun.electric.tool.user.User;import java.awt.geom.Rectangle2D;import java.io.BufferedOutputStream;import java.io.BufferedWriter;import java.io.DataOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.io.StringWriter;import java.net.URL;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Comparator;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.TreeMap;/** * This class manages writing files in different formats. * The class is subclassed by the different file writers. */public class Output{ /** * Used in ECAD */ static class NetNames { String nodeName; String netName; String portName; } static class NetNamesSort implements Comparator<NetNames> { public int compare(NetNames nn1, NetNames nn2) { String name1 = nn1.netName; String name2 = nn2.netName; return name1.compareToIgnoreCase(name2); } } /** * This is the non-interactive version of exportCellCommand * @param cell the Cell to be written. * @param context the VarContext of the Cell (its position in the hierarchy above it). * @param filePath the path to the disk file to be written. * @param type the format of the output file. * @param override a list of Polys to draw instead of the cell contents. */ public static void exportCellCommand(Cell cell, VarContext context, String filePath, FileType type, List<PolyBase> override) { new OutputCellInfo(cell, context, filePath, type, override); } /** file path */ protected String filePath; /** for writing text files */ protected PrintWriter printWriter; /** for writing text arrays */ protected StringWriter stringWriter; /** for writing binary files */ protected DataOutputStream dataOutputStream; /** True to write with less information displayed */protected boolean quiet; public Output() { }// /**// * Method to write a Library.// * This method is never called.// * Instead, it is always overridden by the appropriate write subclass.// * @param lib the Library to be written.// * @return true on error.// */// protected boolean writeLib(Library lib) { return true; }// /** * Method to write a cell. * This method is never called. * Instead, it is always overridden by the appropriate write subclass. * @param cell the Cell to be written. * @param context the VarContext of the cell (for parameter evaluation) * @return true on error. */ protected boolean writeCell(Cell cell, VarContext context) { return true; } /** * Method to write all Libraries in Snapsht into a panic directory. * @param panicSnapshot Snapshot to save. * @param panicDir panic directory to save. * @return true on error. */ public static boolean writePanicSnapshot(Snapshot panicSnapshot, File panicDir, boolean oldRevision) { FileType type = FileType.JELIB; HashMap<LibId,URL> libFiles = new HashMap<LibId,URL>(); TreeMap<String,LibId> sortedLibs = new TreeMap<String,LibId>(TextUtils.STRING_NUMBER_ORDER); for (LibraryBackup libBackup: panicSnapshot.libBackups) { if (libBackup == null) continue; if ((libBackup.d.flags & Library.HIDDENLIBRARY) != 0) continue; LibId libId = libBackup.d.libId; String libName = libBackup.d.libId.libName; URL libURL = libBackup.d.libFile; File newLibFile = null; if (libURL == null || libURL.getPath() == null) { newLibFile = new File(panicDir.getAbsolutePath(), libName + "." + type.getExtensions()[0]); } else { File libFile = new File(libURL.getPath()); String fileName = libFile.getName(); if (fileName == null) fileName = libName + "." + type.getExtensions()[0]; newLibFile = new File(panicDir.getAbsolutePath(), fileName); } URL newLibURL = TextUtils.makeURLToFile(newLibFile.getAbsolutePath()); libFiles.put(libId, newLibURL); sortedLibs.put(libName, libId); } boolean error = false; if (oldRevision) { IdMapper idMapper = IdMapper.consolidateExportIds(panicSnapshot); panicSnapshot = panicSnapshot.withRenamedIds(idMapper, null, null); } for (LibId libId: sortedLibs.values()) { System.out.print("."); System.out.flush(); URL libURL = libFiles.get(libId); JELIB jelib = new JELIB(); String properOutputName = TextUtils.getFilePath(libURL) + TextUtils.getFileNameWithoutExtension(libURL) + ".jelib"; if (jelib.openTextOutputStream(properOutputName) || jelib.writeLib(panicSnapshot, libId, libFiles, oldRevision) || jelib.closeTextOutputStream()) { System.out.println("Error saving "+panicSnapshot.getLib(libId).d.libId.libName); error = true; } } System.out.println(" Libraries saved"); return error; } /** * Method to write an entire Library in JELIB format. * This method doesn't modifiy library, so it can be run out of Job. * @param newName name which is used to prepare file name of the library. * @param lib library to save */ public static boolean saveJelib(String newName, Library lib) { HashMap<LibId,URL> libFiles = new HashMap<LibId,URL>(); // rename the library if requested URL libURL = lib.getLibFile(); if (newName != null) { libURL = TextUtils.makeURLToFile(newName); libFiles.put(lib.getId(), libURL);// lib.setLibFile(libURL);// lib.setName(TextUtils.getFileNameWithoutExtension(libURL)); } boolean error = false; String properOutputName = TextUtils.getFilePath(libURL) + TextUtils.getFileNameWithoutExtension(libURL) + ".jelib"; JELIB jelib = new JELIB(); if (jelib.openTextOutputStream(properOutputName) || jelib.writeLib(lib.getDatabase().backupUnsafe(), lib.getId(), libFiles, false) || jelib.closeTextOutputStream()) { System.out.println("Error saving "+lib.getName()); error = true; } return error; } /** * Method to write an entire Library with a particular format. * This is used for output formats that capture the entire library * (only the ELIB and Readable Dump formats). * The alternative to writing the entire library is writing a single * cell and the hierarchy below it (use "writeCell"). * @param lib the Library to be written. * @param type the format of the output file. * @param compatibleWith6 true to write a library that is compatible with version 6 Electric. * @param quiet true to save with less information displayed. * @param delibHeaderOnly true to write only the header for a DELIB type library * @return true on error. */ public static boolean writeLibrary(Library lib, FileType type, boolean compatibleWith6, boolean quiet, boolean delibHeaderOnly) { // make sure that all "meaning" options are attached to the database// Pref.installMeaningVariables(); // make sure that this library save is announced for(Iterator<Listener> it = Tool.getListeners(); it.hasNext(); ) { Listener listener = it.next(); listener.writeLibrary(lib); } Snapshot snapshot = lib.getDatabase().backup(); LibId libId = lib.getId();// // make sure all technologies with irrelevant scale information have the same scale value// double largestScale = 0;// for(Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); )// {// Technology tech = it.next();// if (tech.isScaleRelevant()) continue;// if (tech == Generic.tech) continue;// if (tech.getScale() > largestScale) largestScale = tech.getScale();// }// Setting.SettingChangeBatch changeBatch = new Setting.SettingChangeBatch();// for(Iterator<Technology> it = Technology.getTechnologies(); it.hasNext(); )// {// Technology tech = it.next();// if (tech.isScaleRelevant()) continue;// if (tech == Generic.tech) continue;// changeBatch.add(tech.getScaleSetting(), Double.valueOf(largestScale));//// tech.setScale(largestScale);// }// Setting.implementSettingChanges(changeBatch); // handle different file types URL libFile = lib.getLibFile(); if (libFile == null) libFile = TextUtils.makeURLToFile(lib.getName()); // make the proper output file name String properOutputNameWithoutExtension = TextUtils.getFilePath(libFile) + TextUtils.getFileNameWithoutExtension(libFile); String properOutputName = properOutputNameWithoutExtension; if (type == FileType.ELIB) properOutputName += ".elib"; if (type == FileType.JELIB) properOutputName += ".jelib"; if (type == FileType.DELIB) properOutputName += ".delib"; if (type == FileType.READABLEDUMP) properOutputName += ".txt"; if (type == FileType.ELIB || type == FileType.JELIB || type == FileType.DELIB) { // backup previous files if requested int backupScheme = IOTool.getBackupRedundancy(); if (backupScheme == 1) { // one-level backup File newFile = new File(properOutputName); if (newFile.exists()) { String backupFileName = properOutputName + "~"; File oldFile = new File(backupFileName); boolean canRename = true; if (oldFile.exists()) { if (!oldFile.delete()) { System.out.println("Unable to delete former library file " + oldFile); canRename = false; } } if (canRename) { if (!newFile.renameTo(oldFile)) { System.out.println("Unable to rename " + newFile + " to " + oldFile); } } } } else if (backupScheme == 2) { // full-history backup File newFile = new File(properOutputName); if (newFile.exists()) { long modified = newFile.lastModified(); Date modifiedDate = new Date(modified); SimpleDateFormat sdf = new SimpleDateFormat("-yyyy-MM-dd"); for(int i=0; i<1000; i++) { String backupFileName = properOutputNameWithoutExtension + sdf.format(modifiedDate); if (i != 0) backupFileName += "--" + i; backupFileName += "." + type.getExtensions()[0]; File oldFile = new File(backupFileName); if (oldFile.exists()) continue; if (!newFile.renameTo(oldFile)) { System.out.println("Unable to rename " + newFile + " to " + oldFile); } break; } } } } if (type == FileType.ELIB || type == FileType.JELIB) { if (type == FileType.ELIB) { ELIB elib = new ELIB(); elib.quiet = quiet; if (compatibleWith6) elib.write6Compatible(); if (elib.openBinaryOutputStream(properOutputName)) return true; if (CVS.isEnabled()) { CVSLibrary.savingLibrary(lib); } if (elib.writeLib(snapshot, libId)) return true; if (elib.closeBinaryOutputStream()) return true; if (CVS.isEnabled()) { CVSLibrary.savedLibrary(lib); } } else { JELIB jelib = new JELIB(); jelib.quiet = quiet; if (jelib.openTextOutputStream(properOutputName)) return true; if (CVS.isEnabled()) { CVSLibrary.savingLibrary(lib); } if (jelib.writeLib(snapshot, libId, null, false)) return true; if (jelib.closeTextOutputStream()) return true; if (CVS.isEnabled()) { CVSLibrary.savedLibrary(lib); } } } else if (type == FileType.READABLEDUMP) { ReadableDump readableDump = new ReadableDump(); readableDump.quiet = quiet; if (readableDump.openTextOutputStream(properOutputName)) return true; if (readableDump.writeLib(snapshot, libId)) return true; if (readableDump.closeTextOutputStream()) return true; } else if (type == FileType.DELIB) { DELIB delib = new DELIB(delibHeaderOnly); delib.quiet = quiet; if (delib.openTextOutputStream(properOutputName)) return true; if (CVS.isEnabled() && !delibHeaderOnly) { CVSLibrary.savingLibrary(lib); } if (delib.writeLib(snapshot, libId, lib.getDelibCellFiles())) return true; if (delib.closeTextOutputStream()) return true; if (CVS.isEnabled() && !delibHeaderOnly) { CVSLibrary.savedLibrary(lib, delib.getDeletedCellFiles(), delib.getWrittenCellFiles()); } } else { System.out.println("Unknown export type: " + type); return true; } // clean up and return lib.setFromDisk(); if (!quiet) System.out.println(properOutputName + " written"); // Update the version in library read in memory lib.setVersion(Version.getVersion()); // if using CVS, update state/* if (CVS.isEnabled()) { CVSLibrary.updateState(lib); }*/ lib.clearChanged(); Constraints.getCurrent().writeLibrary(lib); return false; } /** * Method to write a Cell to a file with a particular format. * In addition to the specified Cell, these formats typically * also include the hierarchy below it. * The alternative is to write the entire library, regardless of * hierarchical structure (use "WriteLibrary"). * @param cell the Cell to be written. * @param context the VarContext of the Cell (its position in the hierarchy above it). * @param filePath the path to the disk file to be written. * @param type the format of the output file. * @param override a list of overriding polygons to write. * NOTE: Keep public for regressions */ public static void writeCell(Cell cell, VarContext context, String filePath, FileType type, List<PolyBase> override) { if (type == FileType.ARCHSIM) { ArchSim.writeArchSimFile(cell, filePath); } else if (type == FileType.CDL) { Spice.writeSpiceFile(cell, context, filePath, true); } else if (type == FileType.CIF) { CIF.writeCIFFile(cell, context, filePath); } else if (type == FileType.COSMOS) { Sim.writeSimFile(cell, context, filePath, type); } else if (type == FileType.DXF) { DXF.writeDXFFile(cell, filePath); } else if (type == FileType.EAGLE) { Eagle.writeEagleFile(cell, context, filePath);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -