Implemented native gzip compression/decompression using zlib routines.
Compression levels of the output can be controlled with the "gds compress [<value>]" command, where <value> 0 (default) is uncompressed output, 6 is "normal" gzip compression, and 9 is maximum compression.
This commit is contained in:
parent
6e0768ebd4
commit
371018ae4b
|
|
@ -91,19 +91,19 @@ typedef struct {
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
off_t
|
||||
OFFTYPE
|
||||
calmaSetPosition(sname)
|
||||
char *sname;
|
||||
{
|
||||
off_t originalPos = 0, currentPos = 0;
|
||||
OFFTYPE originalPos = 0, currentPos = 0;
|
||||
int nbytes, rtype;
|
||||
char *strname = NULL;
|
||||
int strRecSize = 0;
|
||||
bool found = FALSE;
|
||||
|
||||
originalPos = ftello(calmaInputFile);
|
||||
originalPos = FTELL(calmaInputFile);
|
||||
|
||||
while (feof(calmaInputFile) == 0)
|
||||
while (FEOF(calmaInputFile) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
|
@ -113,7 +113,7 @@ calmaSetPosition(sname)
|
|||
/* Skip no of bytes in record header until
|
||||
* we reach to next structure record.
|
||||
*/
|
||||
fseek(calmaInputFile, nbytes - CALMAHEADERLENGTH, SEEK_CUR);
|
||||
FSEEK(calmaInputFile, nbytes - CALMAHEADERLENGTH, SEEK_CUR);
|
||||
} while (rtype != CALMA_BGNSTR);
|
||||
if (nbytes <= 0) break;
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ calmaSetPosition(sname)
|
|||
*/
|
||||
strRecSize = strlen(strname);
|
||||
if (strRecSize & 01) strRecSize++;
|
||||
fseek(calmaInputFile, -(nbytes + strRecSize + CALMAHEADERLENGTH),
|
||||
FSEEK(calmaInputFile, -(nbytes + strRecSize + CALMAHEADERLENGTH),
|
||||
SEEK_CUR);
|
||||
freeMagic(strname);
|
||||
return originalPos;
|
||||
|
|
@ -188,7 +188,7 @@ calmaNextCell()
|
|||
{
|
||||
int nbytes, rtype;
|
||||
|
||||
if (feof(calmaInputFile) == 0)
|
||||
if (FEOF(calmaInputFile) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
|
@ -199,17 +199,17 @@ calmaNextCell()
|
|||
* try to set the file pointer somewhere sane, but
|
||||
* it will likely dump an error later on.
|
||||
*/
|
||||
fseek(calmaInputFile, -(CALMAHEADERLENGTH), SEEK_END);
|
||||
FSEEK(calmaInputFile, -(CALMAHEADERLENGTH), SEEK_END);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Skip no. of bytes in record header to reach the next
|
||||
* structure record.
|
||||
*/
|
||||
fseek(calmaInputFile, nbytes - CALMAHEADERLENGTH, SEEK_CUR);
|
||||
FSEEK(calmaInputFile, nbytes - CALMAHEADERLENGTH, SEEK_CUR);
|
||||
} while((rtype != CALMA_BGNSTR) && (rtype != CALMA_ENDLIB));
|
||||
|
||||
fseek(calmaInputFile, -nbytes, SEEK_CUR);
|
||||
FSEEK(calmaInputFile, -nbytes, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ calmaParseStructure(filename, origname)
|
|||
int timestampval = 0;
|
||||
int suffix;
|
||||
int mfactor;
|
||||
off_t filepos;
|
||||
OFFTYPE filepos;
|
||||
bool was_called;
|
||||
bool was_initialized;
|
||||
bool predefined;
|
||||
|
|
@ -327,7 +327,7 @@ calmaParseStructure(filename, origname)
|
|||
TxPrintf("Reading \"%s\".\n", strname);
|
||||
|
||||
/* Used for read-only and annotated LEF views */
|
||||
filepos = ftello(calmaInputFile);
|
||||
filepos = FTELL(calmaInputFile);
|
||||
|
||||
/* Set up the cell definition */
|
||||
he = HashFind(&calmaDefInitHash, strname);
|
||||
|
|
@ -455,7 +455,7 @@ calmaParseStructure(filename, origname)
|
|||
DBPropPut(cifReadCellDef, "GDS_START", (ClientData)fpcopy);
|
||||
|
||||
fpcopy = (char *)mallocMagic(20);
|
||||
filepos = ftello(calmaInputFile);
|
||||
filepos = FTELL(calmaInputFile);
|
||||
sprintf(fpcopy, "%"DLONG_PREFIX"d", (dlong) filepos);
|
||||
DBPropPut(cifReadCellDef, "GDS_END", (ClientData)fpcopy);
|
||||
|
||||
|
|
@ -743,8 +743,8 @@ calmaElementSref(filename)
|
|||
* Added by Nishit 8/16/2004
|
||||
*/
|
||||
|
||||
off_t originalFilePos = calmaSetPosition(sname);
|
||||
if (!feof(calmaInputFile))
|
||||
OFFTYPE originalFilePos = calmaSetPosition(sname);
|
||||
if (!FEOF(calmaInputFile))
|
||||
{
|
||||
HashTable OrigCalmaLayerHash;
|
||||
int crsMultiplier = cifCurReadStyle->crs_multiplier;
|
||||
|
|
@ -758,7 +758,7 @@ calmaElementSref(filename)
|
|||
calmaParseStructure(filename);
|
||||
|
||||
/* Put things back to the way they were. */
|
||||
fseek(calmaInputFile, originalFilePos, SEEK_SET);
|
||||
FSEEK(calmaInputFile, originalFilePos, SEEK_SET);
|
||||
cifReadCellDef = calmaLookCell(currentSname);
|
||||
def = calmaLookCell(sname);
|
||||
cifCurReadPlanes = savePlanes;
|
||||
|
|
@ -783,7 +783,7 @@ calmaElementSref(filename)
|
|||
{
|
||||
/* This is redundant messaging */
|
||||
// TxPrintf("Cell definition %s does not exist!\n", sname);
|
||||
fseek(calmaInputFile, originalFilePos, SEEK_SET);
|
||||
FSEEK(calmaInputFile, originalFilePos, SEEK_SET);
|
||||
def = calmaFindCell(sname, NULL, NULL);
|
||||
/* Cell flags set to "dereferenced" in case there is no */
|
||||
/* definition in the GDS file. If there is a definition */
|
||||
|
|
@ -821,7 +821,7 @@ calmaElementSref(filename)
|
|||
READI2(rows);
|
||||
xlo = 0; xhi = cols - 1;
|
||||
ylo = 0; yhi = rows - 1;
|
||||
if (feof(calmaInputFile)) return -1;
|
||||
if (FEOF(calmaInputFile)) return -1;
|
||||
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH - 4);
|
||||
}
|
||||
else
|
||||
|
|
@ -897,7 +897,7 @@ calmaElementSref(filename)
|
|||
refarray[n].p_x *= (savescale / cifCurReadStyle->crs_scaleFactor);
|
||||
}
|
||||
|
||||
if (feof(calmaInputFile))
|
||||
if (FEOF(calmaInputFile))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ calmaReadI2Record(type, pvalue)
|
|||
|
||||
/* Read the value */
|
||||
READI2(n);
|
||||
if (feof(calmaInputFile)) goto eof;
|
||||
if (FEOF(calmaInputFile)) goto eof;
|
||||
*pvalue = n;
|
||||
return (TRUE);
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ calmaReadI4Record(type, pvalue)
|
|||
|
||||
/* Read the value */
|
||||
READI4(n);
|
||||
if (feof(calmaInputFile)) goto eof;
|
||||
if (FEOF(calmaInputFile)) goto eof;
|
||||
*pvalue = n;
|
||||
return (TRUE);
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ calmaReadStringRecord(type, str)
|
|||
|
||||
nbytes -= CALMAHEADERLENGTH;
|
||||
*str = (char *) mallocMagic(nbytes + 1);
|
||||
if (fread(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
|
||||
if (FREAD(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
|
||||
goto eof;
|
||||
|
||||
*(*str + nbytes) = '\0';
|
||||
|
|
@ -425,7 +425,7 @@ calmaReadR8(pd)
|
|||
double mantissa, d;
|
||||
bool isneg;
|
||||
|
||||
if (fread((char *) dchars, sizeof (char), sizeof dchars,
|
||||
if (FREAD((char *) dchars, sizeof (char), sizeof dchars,
|
||||
calmaInputFile) != sizeof dchars)
|
||||
return (FALSE);
|
||||
|
||||
|
|
@ -616,7 +616,7 @@ calmaSkipBytes(nbytes)
|
|||
int nbytes; /* Skip this many bytes */
|
||||
{
|
||||
while (nbytes-- > 0)
|
||||
if (getc(calmaInputFile) < 0)
|
||||
if (FGETC(calmaInputFile) < 0)
|
||||
return (FALSE);
|
||||
|
||||
return (TRUE);
|
||||
|
|
|
|||
|
|
@ -1075,7 +1075,7 @@ calmaReadPath(pathheadpp, iscale)
|
|||
CalmaReadError("Warning: Very large point in path: (%d, %d)\n",
|
||||
path.cifp_x, path.cifp_y);
|
||||
}
|
||||
if (feof(calmaInputFile))
|
||||
if (FEOF(calmaInputFile))
|
||||
{
|
||||
CIFFreePath(*pathheadpp);
|
||||
return (FALSE);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/undo.h"
|
||||
|
||||
/* Globals for Calma reading */
|
||||
FILE *calmaInputFile = NULL; /* Read from this stream */
|
||||
FILETYPE calmaInputFile = NULL; /* Read from this stream */
|
||||
FILE *calmaErrorFile = NULL; /* Write error output here */
|
||||
bool CalmaSubcellPolygons = FALSE; /* Put non-Manhattan polygons
|
||||
* in their own subcells.
|
||||
|
|
@ -153,7 +153,7 @@ int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 };
|
|||
|
||||
void
|
||||
CalmaReadFile(file, filename, origname)
|
||||
FILE *file; /* File from which to read Calma */
|
||||
FILETYPE file; /* File from which to read Calma */
|
||||
char *filename; /* The real name of the file read */
|
||||
char *origname; /* Original name of file read (used for
|
||||
* compressed files)
|
||||
|
|
@ -269,7 +269,7 @@ done:
|
|||
HashKill(&calmaDefInitHash);
|
||||
UndoEnable();
|
||||
|
||||
if (calmaErrorFile != NULL) fclose(calmaErrorFile);
|
||||
if (calmaErrorFile != NULL) FCLOSE(calmaErrorFile);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -386,14 +386,14 @@ CalmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
|||
char *format;
|
||||
char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a10;
|
||||
{
|
||||
off_t filepos;
|
||||
OFFTYPE filepos;
|
||||
|
||||
calmaTotalErrors++;
|
||||
if (CIFWarningLevel == CIF_WARN_NONE) return;
|
||||
|
||||
if ((calmaTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT))
|
||||
{
|
||||
filepos = ftello(calmaInputFile);
|
||||
filepos = FTELL(calmaInputFile);
|
||||
|
||||
if (CIFWarningLevel == CIF_WARN_REDIRECT)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ bool CalmaAllowUndefined = FALSE; /* If TRUE, allow calls to undefined cells */
|
|||
bool CalmaContactArrays = FALSE; /* If TRUE, output contacts as subcell arrays */
|
||||
bool CalmaMergeTiles = FALSE; /* If TRUE, merge tiles into polygons in output. */
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
int CalmaCompression = 0; /* Output file compression level (0 = uncompressed) */
|
||||
#endif
|
||||
|
||||
/* Forward declarations */
|
||||
extern int calmaWriteInitFunc();
|
||||
extern int calmaWriteMarkFunc();
|
||||
|
|
@ -286,7 +290,7 @@ CalmaWrite(rootDef, f)
|
|||
CellDef *rootDef; /* Pointer to CellDef to be written */
|
||||
FILE *f; /* Open output file */
|
||||
{
|
||||
int oldCount = DBWFeedbackCount, problems;
|
||||
int oldCount = DBWFeedbackCount, problems, nerr;
|
||||
bool good;
|
||||
CellUse dummy;
|
||||
HashEntry *he;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
MODULE = calma
|
||||
MAGICDIR = ..
|
||||
SRCS = CalmaRead.c CalmaRdcl.c CalmaRdio.c CalmaRdpt.c CalmaWrite.c
|
||||
SRCS = CalmaRead.c CalmaRdcl.c CalmaRdio.c CalmaRdpt.c CalmaWrite.c CalmaWriteZ.c
|
||||
|
||||
include ${MAGICDIR}/defs.mak
|
||||
include ${MAGICDIR}/rules.mak
|
||||
|
|
|
|||
|
|
@ -42,6 +42,9 @@ extern bool CalmaFlattenUses;
|
|||
extern char **CalmaFlattenUsesByName;
|
||||
extern bool CalmaReadOnly;
|
||||
extern bool CalmaContactArrays;
|
||||
#ifdef HAVE_ZLIB
|
||||
extern bool CalmaCompression;
|
||||
#endif
|
||||
extern bool CalmaPostOrder;
|
||||
extern bool CalmaAllowUndefined;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@
|
|||
#include "utils/magic.h"
|
||||
#include "database/database.h"
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
/* Record data types */
|
||||
#define CALMA_NODATA 0 /* No data present */
|
||||
#define CALMA_BITARRAY 1 /* Bit array */
|
||||
|
|
@ -136,8 +140,30 @@ typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CEL
|
|||
|
||||
/* ------------------------- Input macros ----------------------------- */
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#define FOPEN gzopen
|
||||
#define FCLOSE gzclose
|
||||
#define FGETC gzgetc
|
||||
#define FREAD(a,b,c,d) gzread(d,a,b*c)
|
||||
#define FEOF gzeof
|
||||
#define FSEEK gzseek
|
||||
#define FTELL gztell
|
||||
#define FILETYPE gzFile
|
||||
#define OFFTYPE z_off_t
|
||||
#else
|
||||
#define FOPEN fopen
|
||||
#define FCLOSE fclose
|
||||
#define FGETC getc
|
||||
#define FREAD fread
|
||||
#define FEOF feof
|
||||
#define FSEEK fseek
|
||||
#define FTELL ftello
|
||||
#define FILETYPE FILE *
|
||||
#define OFFTYPE off_t
|
||||
#endif
|
||||
|
||||
/* Globals for Calma reading */
|
||||
extern FILE *calmaInputFile;
|
||||
extern FILETYPE calmaInputFile;
|
||||
extern char *calmaFilename;
|
||||
extern int calmaReadScale1;
|
||||
extern int calmaReadScale2;
|
||||
|
|
@ -168,8 +194,8 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
|
|||
#define READI2(z) \
|
||||
{ \
|
||||
TwoByteInt u; \
|
||||
u.uc[0] = getc(calmaInputFile); \
|
||||
u.uc[1] = getc(calmaInputFile); \
|
||||
u.uc[0] = FGETC(calmaInputFile); \
|
||||
u.uc[1] = FGETC(calmaInputFile); \
|
||||
(z) = (int) ntohs(u.us); \
|
||||
}
|
||||
|
||||
|
|
@ -177,10 +203,10 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
|
|||
#define READI4(z) \
|
||||
{ \
|
||||
FourByteInt u; \
|
||||
u.uc[0] = getc(calmaInputFile); \
|
||||
u.uc[1] = getc(calmaInputFile); \
|
||||
u.uc[2] = getc(calmaInputFile); \
|
||||
u.uc[3] = getc(calmaInputFile); \
|
||||
u.uc[0] = FGETC(calmaInputFile); \
|
||||
u.uc[1] = FGETC(calmaInputFile); \
|
||||
u.uc[2] = FGETC(calmaInputFile); \
|
||||
u.uc[3] = FGETC(calmaInputFile); \
|
||||
(z) = (int) ntohl(u.ul); \
|
||||
}
|
||||
|
||||
|
|
@ -193,10 +219,10 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
|
|||
calmaLApresent = FALSE; \
|
||||
} else { \
|
||||
READI2(nb); \
|
||||
if (feof(calmaInputFile)) nb = -1; \
|
||||
if (FEOF(calmaInputFile)) nb = -1; \
|
||||
else { \
|
||||
(rt) = getc(calmaInputFile); \
|
||||
(void) getc(calmaInputFile); \
|
||||
(rt) = FGETC(calmaInputFile); \
|
||||
(void) FGETC(calmaInputFile); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
|
|
|||
236
commands/CmdCD.c
236
commands/CmdCD.c
|
|
@ -49,6 +49,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/malloc.h"
|
||||
#include "cif/CIFint.h"
|
||||
#include "cif/CIFread.h"
|
||||
#include "calma/calmaInt.h"
|
||||
|
||||
/* The following structure is used by CmdCorner to keep track of
|
||||
* areas to be filled.
|
||||
|
|
@ -91,28 +92,29 @@ bool cmdDumpParseArgs();
|
|||
#define CALMA_HELP 0
|
||||
#define CALMA_ADDENDUM 1
|
||||
#define CALMA_ARRAYS 2
|
||||
#define CALMA_CONTACTS 3
|
||||
#define CALMA_DATESTAMP 4
|
||||
#define CALMA_DRCCHECK 5
|
||||
#define CALMA_FLATTEN 6
|
||||
#define CALMA_FLATGLOB 7
|
||||
#define CALMA_ORDERING 8
|
||||
#define CALMA_LABELS 9
|
||||
#define CALMA_LIBRARY 10
|
||||
#define CALMA_LOWER 11
|
||||
#define CALMA_MASKHINTS 12
|
||||
#define CALMA_MERGE 13
|
||||
#define CALMA_NO_STAMP 14
|
||||
#define CALMA_NO_DUP 15
|
||||
#define CALMA_READ 16
|
||||
#define CALMA_READONLY 17
|
||||
#define CALMA_RESCALE 18
|
||||
#define CALMA_WARNING 19
|
||||
#define CALMA_WRITE 20
|
||||
#define CALMA_POLYS 21
|
||||
#define CALMA_PATHS 22
|
||||
#define CALMA_UNDEFINED 23
|
||||
#define CALMA_UNIQUE 24
|
||||
#define CALMA_COMPRESS 3
|
||||
#define CALMA_CONTACTS 4
|
||||
#define CALMA_DATESTAMP 5
|
||||
#define CALMA_DRCCHECK 6
|
||||
#define CALMA_FLATTEN 7
|
||||
#define CALMA_FLATGLOB 8
|
||||
#define CALMA_ORDERING 9
|
||||
#define CALMA_LABELS 10
|
||||
#define CALMA_LIBRARY 11
|
||||
#define CALMA_LOWER 12
|
||||
#define CALMA_MASKHINTS 13
|
||||
#define CALMA_MERGE 14
|
||||
#define CALMA_NO_STAMP 15
|
||||
#define CALMA_NO_DUP 16
|
||||
#define CALMA_READ 17
|
||||
#define CALMA_READONLY 18
|
||||
#define CALMA_RESCALE 19
|
||||
#define CALMA_WARNING 20
|
||||
#define CALMA_WRITE 21
|
||||
#define CALMA_POLYS 22
|
||||
#define CALMA_PATHS 23
|
||||
#define CALMA_UNDEFINED 24
|
||||
#define CALMA_UNIQUE 25
|
||||
|
||||
#define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */
|
||||
|
||||
|
|
@ -121,17 +123,18 @@ CmdCalma(w, cmd)
|
|||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
{
|
||||
int option, ext;
|
||||
int option, ext, value;
|
||||
char **msg, *namep, *dotptr;
|
||||
char writeMode[3];
|
||||
CellDef *rootDef;
|
||||
FILE *f;
|
||||
int namelen;
|
||||
bool gzipd;
|
||||
char *realName, *saveName, *modName;
|
||||
#ifdef HAVE_ZLIB
|
||||
gzFile fz;
|
||||
#endif
|
||||
|
||||
extern int CalmaFlattenLimit;
|
||||
|
||||
static char *gdsExts[] = {".gds", ".gds2", ".strm", "", NULL};
|
||||
static char *gdsExts[] = {".gds", ".gds.gz", ".gds2", ".strm", "", NULL};
|
||||
static char *cmdCalmaYesNo[] = {
|
||||
"no", "false", "off", "0", "yes", "true", "on", "1", 0 };
|
||||
static char *cmdCalmaAllowDisallow[] = {"disallow", "0", "allow", "1", 0};
|
||||
|
|
@ -142,6 +145,7 @@ CmdCalma(w, cmd)
|
|||
"help print this help information",
|
||||
"addendum [yes|no] output only cells that are not type \"readonly\"",
|
||||
"arrays [yes|no] output arrays as individual subuses (like in CIF)",
|
||||
"compress [value] compress output with zlib compression 0 to 6",
|
||||
"contacts [yes|no] optimize output by arraying contacts as subcells",
|
||||
"datestamp [yes|value] use current time or value as the creation date stamp",
|
||||
"drccheck [yes|no] mark all cells as needing DRC checking",
|
||||
|
|
@ -312,6 +316,41 @@ CmdCalma(w, cmd)
|
|||
CalmaAllowUndefined = (option < 2) ? FALSE : TRUE;
|
||||
return;
|
||||
|
||||
case CALMA_COMPRESS:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
#ifdef HAVE_ZLIB
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(CalmaCompression));
|
||||
#else
|
||||
if (CalmaCompression == 0)
|
||||
TxPrintf("Calma files are not compressed.\n");
|
||||
else
|
||||
TxPrintf("Calma files are compressed with zlib compression level %d.\n", CalmaCompression);
|
||||
#endif
|
||||
#else /* !HAVE_ZLIB */
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(0));
|
||||
#else
|
||||
TxPrintf("No file compression has been enabled.\n");
|
||||
#endif
|
||||
#endif /* !HAVE_ZLIB */
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_ZLIB
|
||||
else if (cmd->tx_argc != 3)
|
||||
goto wrongNumArgs;
|
||||
|
||||
value = atoi(cmd->tx_argv[2]);
|
||||
if ((value < 0) || (value > 9))
|
||||
TxError("Bad compression value %d. Value must be in the range 0 to 9.\n", value);
|
||||
else
|
||||
CalmaCompression = value;
|
||||
#else
|
||||
goto wrongNumArgs;
|
||||
#endif
|
||||
return;
|
||||
|
||||
case CALMA_CONTACTS:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
|
|
@ -873,58 +912,15 @@ CmdCalma(w, cmd)
|
|||
case CALMA_READ:
|
||||
if (cmd->tx_argc != 3) goto wrongNumArgs;
|
||||
|
||||
/* Check for compressed files, and uncompress them. */
|
||||
/* Always uncompress into the current working directory */
|
||||
/* because the original compressed file might be in an */
|
||||
/* unwriteable directory. */
|
||||
|
||||
modName = cmd->tx_argv[2];
|
||||
namelen = strlen(modName);
|
||||
if ((namelen > 4) && !strcmp(modName + namelen - 3, ".gz"))
|
||||
{
|
||||
char *sysCmd, *sptr;
|
||||
|
||||
/* First try to open the uncompressed file name. If */
|
||||
/* the file exists, then don't try to uncompress on top */
|
||||
/* of it, but just fail. */
|
||||
|
||||
sptr = strrchr(modName, '/');
|
||||
if (sptr == NULL)
|
||||
sptr = modName;
|
||||
else
|
||||
sptr++;
|
||||
modName = StrDup((char **)NULL, sptr);
|
||||
*(modName + strlen(modName) - 3) = '\0';
|
||||
if ((f = PaOpen(modName, "r", NULL, Path,
|
||||
(char *)NULL, NULL)) != (FILE *)NULL)
|
||||
{
|
||||
fclose(f);
|
||||
TxError("Uncompressed file \"%s\" already exists!\n", modName);
|
||||
freeMagic(modName);
|
||||
return;
|
||||
}
|
||||
|
||||
sysCmd = mallocMagic(18 + namelen + strlen(modName));
|
||||
/* Note: "-k" keeps the original compressed file */
|
||||
TxPrintf("Uncompressing file \"%s\".\n", cmd->tx_argv[2]);
|
||||
sprintf(sysCmd, "gunzip -c %s > %s", cmd->tx_argv[2], modName);
|
||||
if (system(sysCmd) != 0)
|
||||
{
|
||||
freeMagic(modName);
|
||||
modName = NULL;
|
||||
}
|
||||
freeMagic(sysCmd);
|
||||
}
|
||||
|
||||
/* Check for various common file extensions, including */
|
||||
/* no extension (as-is), ".gds", ".gds2", and ".strm". */
|
||||
|
||||
for (ext = 0; gdsExts[ext] != NULL; ext++)
|
||||
if ((f = PaOpen(modName, "r", gdsExts[ext], Path,
|
||||
(char *) NULL, &namep)) != (FILE *)NULL)
|
||||
if ((f = PaZOpen(cmd->tx_argv[2], "r", gdsExts[ext], Path,
|
||||
(char *) NULL, &namep)) != (FILETYPE)NULL)
|
||||
break;
|
||||
|
||||
if (f == (FILE *) NULL)
|
||||
if (f == (FILETYPE) NULL)
|
||||
{
|
||||
TxError("Cannot open %s.gds, %s.strm or %s to read "
|
||||
"GDS-II stream input.\n",
|
||||
|
|
@ -932,19 +928,7 @@ CmdCalma(w, cmd)
|
|||
return;
|
||||
}
|
||||
CalmaReadFile(f, namep, cmd->tx_argv[2]);
|
||||
(void) fclose(f);
|
||||
if (modName != cmd->tx_argv[2])
|
||||
{
|
||||
/* A gzipped file was read and now the uncompressed */
|
||||
/* file that was generated should be removed. */
|
||||
|
||||
if (unlink(namep) != 0)
|
||||
{
|
||||
TxError("Error attempting to delete uncompressed file \"%s\"\n",
|
||||
namep);
|
||||
}
|
||||
freeMagic(modName);
|
||||
}
|
||||
(void) FCLOSE(f);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -956,54 +940,49 @@ CmdCalma(w, cmd)
|
|||
outputCalma:
|
||||
dotptr = strrchr(namep, '.');
|
||||
|
||||
/* Check for additional ".gz" extension */
|
||||
if (dotptr && !strcmp(dotptr, ".gz"))
|
||||
#ifdef HAVE_ZLIB
|
||||
/* Handle compression based on value of CalmaCompression */
|
||||
if (CalmaCompression > 0)
|
||||
{
|
||||
gzipd = TRUE;
|
||||
*dotptr = '\0';
|
||||
dotptr = strrchr(namep, '.');
|
||||
sprintf(writeMode, "w%d", CalmaCompression);
|
||||
fz = PaZOpen(namep, writeMode, (dotptr == NULL) ? ".gds.gz" : "", ".", (char *) NULL, (char **)NULL);
|
||||
if (fz == (gzFile)NULL)
|
||||
{
|
||||
TxError("Cannot open %s%s to write compressed GDS-II stream output\n", namep,
|
||||
(dotptr == NULL) ? ".gds.gz" : "");
|
||||
return;
|
||||
}
|
||||
if (!CalmaWriteZ(rootDef, fz))
|
||||
{
|
||||
TxError("I/O error in writing compressed file %s.\n", namep);
|
||||
TxError("File may be incompletely written.\n");
|
||||
}
|
||||
(void) gzclose(fz);
|
||||
}
|
||||
else
|
||||
gzipd = FALSE;
|
||||
|
||||
f = PaOpen(namep, "w", (dotptr == NULL) ? ".gds" : "", ".",
|
||||
(char *) NULL, (char **)&realName);
|
||||
if (gzipd)
|
||||
saveName = StrDup((char **)NULL, realName);
|
||||
|
||||
if (f == (FILE *) NULL)
|
||||
{
|
||||
TxError("Cannot open %s%s to write GDS-II stream output\n", namep,
|
||||
(dotptr == NULL) ? ".gds" : "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CalmaWrite(rootDef, f))
|
||||
{
|
||||
TxError("I/O error in writing file %s.\n", namep);
|
||||
TxError("File may be incompletely written.\n");
|
||||
}
|
||||
(void) fclose(f);
|
||||
|
||||
if (gzipd)
|
||||
{
|
||||
char *sysCmd;
|
||||
sysCmd = mallocMagic(16 + strlen(saveName));
|
||||
TxPrintf("Compressing file \"%s\"\n", saveName);
|
||||
sprintf(sysCmd, "gzip -n --best %s", saveName);
|
||||
|
||||
/* Note that without additional arguments, "gzip" will wholly */
|
||||
/* replace the uncompressed file with the compressed one. */
|
||||
|
||||
if (system(sysCmd) != 0)
|
||||
{
|
||||
TxError("Failed to compress file \"%s\"\n", saveName);
|
||||
}
|
||||
freeMagic(sysCmd);
|
||||
freeMagic(saveName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
f = PaOpen(namep, "w", (dotptr == NULL) ? ".gds" : "", ".", (char *) NULL, (char **)NULL);
|
||||
if (f == (FILE *)NULL)
|
||||
{
|
||||
TxError("Cannot open %s%s to write GDS-II stream output\n", namep,
|
||||
(dotptr == NULL) ? ".gds" : "");
|
||||
return;
|
||||
}
|
||||
if (!CalmaWrite(rootDef, f))
|
||||
{
|
||||
TxError("I/O error in writing file %s.\n", namep);
|
||||
TxError("File may be incompletely written.\n");
|
||||
}
|
||||
(void) fclose(f);
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* CALMA_MODULE */
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -5095,3 +5074,4 @@ cmdDumpFunc(rect, name, label, point)
|
|||
*point = rect->r_ll;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,16 @@ Read GDSII input or generate GDSII output.
|
|||
<DT> <B>arrays</B> [<B>yes</B>|<B>no</B>]
|
||||
<DD> Output arrays as individual subuses (like in CIF). Default
|
||||
is "no". Normally there is no reason to do this.
|
||||
<DT> <B>compress</B> [<I>value</I>]
|
||||
<DD> For non-zero <I>value</I>, apply gzip-style compression to the
|
||||
output stream. Per the gzip compression algorithm, <I>value</I>
|
||||
represents a level of compression effort, and ranges from 1 to
|
||||
9. When <I>value</I> is zero, no compression is applied and the
|
||||
output is standard GDS format, and the output file extension is
|
||||
".gds". When <I>value</I> is non-zero, compression is applied,
|
||||
and the output file extension is ".gds.gz". With no argument,
|
||||
return the current compression setting. The default compression
|
||||
setting is zero (no compression applied; output is plain GDS).
|
||||
<DT> <B>contacts</B> [<B>yes</B>|<B>no</B>]
|
||||
<DD> Causes contacts to be written to the GDS file as subcell
|
||||
arrays (experimental, introduced in version 7.3.55). This
|
||||
|
|
@ -270,6 +280,10 @@ Read GDSII input or generate GDSII output.
|
|||
If no option is given, a CALMA GDS-II stream file is produced for the
|
||||
root cell, with the default name of the root cell definition and the
|
||||
filename extension ".gds". <P>
|
||||
|
||||
<B>gds read</B> will read both (gzip-)compressed and uncompressed GDS
|
||||
files. <B>gds write</B> will only write compressed files as indicated
|
||||
by the <B>gds compress</B> setting. <P>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>Implementation Notes:</H3>
|
||||
|
|
@ -307,6 +321,6 @@ Read GDSII input or generate GDSII output.
|
|||
<TD> <A HREF=commands.html>Return to command index</A>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P><I>Last updated:</I> April 27, 2021 at 1:06pm <P>
|
||||
<P><I>Last updated:</I> May 10, 2022 at 9:14am <P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
|
|||
|
|
@ -5035,6 +5035,49 @@ $as_echo "#define HAVE___VA_COPY 1" >>confdefs.h
|
|||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzopen in -lz" >&5
|
||||
$as_echo_n "checking for gzopen in -lz... " >&6; }
|
||||
if ${ac_cv_lib_z_gzopen+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lz $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char gzopen ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return gzopen ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_z_gzopen=yes
|
||||
else
|
||||
ac_cv_lib_z_gzopen=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzopen" >&5
|
||||
$as_echo "$ac_cv_lib_z_gzopen" >&6; }
|
||||
if test "x$ac_cv_lib_z_gzopen" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ then
|
|||
AC_DEFINE(HAVE___VA_COPY, 1, [Define if we have __va_copy])
|
||||
fi
|
||||
|
||||
dnl Check for zlib
|
||||
AC_CHECK_LIB([z],[gzopen],[AC_DEFINE([HAVE_ZLIB],[1],["zlib compression"])])
|
||||
|
||||
dnl Check for some C99 functions
|
||||
|
||||
dnl Built-in round/roundf require CFLAGS -std=c99, but this also
|
||||
|
|
|
|||
135
utils/path.c
135
utils/path.c
|
|
@ -28,6 +28,10 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/magic.h"
|
||||
#include "utils/hash.h"
|
||||
|
|
@ -531,6 +535,137 @@ PaLockOpen(file, mode, ext, path, library, pRealName, is_locked)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* PaZOpen --
|
||||
* This routine does a file lookup using the current path and
|
||||
* supplying a default extension. The return type is a Zlib-
|
||||
* type compressed stream.
|
||||
*
|
||||
* Results:
|
||||
* A gzFile type, or NULL if the file couldn't be found.
|
||||
*
|
||||
* Side Effects:
|
||||
* See notes for PaLockOpen() for handling of extensions.
|
||||
*
|
||||
* Path Format:
|
||||
* A path is a string containing directory names separated by
|
||||
* colons or white space. Tilde notation may be used within paths.
|
||||
*-------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
gzFile
|
||||
PaZOpen(file, mode, ext, path, library, pRealName)
|
||||
char *file; /* Name of the file to be opened. */
|
||||
char *mode; /* The file mode, as given to gzopen. */
|
||||
char *ext; /* The extension to be added to the file name,
|
||||
* or NULL. Note: this string must include
|
||||
* the dot (or whatever separator you use).
|
||||
*/
|
||||
char *path; /* A search path: a list of directory names
|
||||
* separated by colons or blanks. To use
|
||||
* only the working directory, use "." for
|
||||
* the path.
|
||||
*/
|
||||
char *library; /* A 2nd path containing library names. Can be
|
||||
* NULL to indicate no library.
|
||||
*/
|
||||
char **pRealName; /* Pointer to a location that will be filled
|
||||
* in with the address of the real name of
|
||||
* the file that was successfully opened.
|
||||
* If NULL, then nothing is stored.
|
||||
*/
|
||||
{
|
||||
char extendedName[MAXSIZE], *p1, *p2;
|
||||
static char realName[MAXSIZE];
|
||||
int length, extLength, i;
|
||||
gzFile f;
|
||||
|
||||
if (file == NULL) return (gzFile) NULL;
|
||||
if (file[0] == '\0') return (gzFile) NULL;
|
||||
if (pRealName != NULL) (*pRealName) = realName;
|
||||
|
||||
/* See if we must supply an extension. */
|
||||
|
||||
length = strlen(file);
|
||||
if (length >= MAXSIZE) length = MAXSIZE - 1;
|
||||
if (ext != NULL)
|
||||
{
|
||||
(void) strncpy(extendedName, file, length + 1);
|
||||
i = MAXSIZE - 1 - length;
|
||||
extLength = strlen(ext);
|
||||
if (extLength > i) extLength = i;
|
||||
|
||||
(void) strncpy(&(extendedName[length]), ext, extLength + 1);
|
||||
|
||||
extendedName[MAXSIZE-1] = '\0';
|
||||
file = extendedName;
|
||||
}
|
||||
|
||||
/* If the first character of the file name is a tilde or dollar sign,
|
||||
* do tilde or environment variable expansion but don't touch a search
|
||||
* path.
|
||||
*/
|
||||
|
||||
if (file[0] == '~' || file[0] == '$')
|
||||
{
|
||||
p1 = realName;
|
||||
p2 = file;
|
||||
if (PaExpand(&p2, &p1, MAXSIZE) < 0) return NULL;
|
||||
return gzopen(realName, mode);
|
||||
}
|
||||
|
||||
/* If we were already given a full rooted file name,
|
||||
* or a relative pathname, just use it.
|
||||
*/
|
||||
|
||||
if (file[0] == '/'
|
||||
|| (file[0] == '.' && (strcmp(file, ".") == 0
|
||||
|| strncmp(file, "./", 2) == 0
|
||||
|| strcmp(file, "..") == 0
|
||||
|| strncmp(file, "../", 3) == 0)))
|
||||
{
|
||||
(void) strncpy(realName, file, MAXSIZE-1);
|
||||
realName[MAXSIZE-1] = '\0';
|
||||
return gzopen(realName, mode);
|
||||
}
|
||||
|
||||
/* Now try going through the path, one entry at a time. */
|
||||
|
||||
while (nextName(&path, file, realName, MAXSIZE) != NULL)
|
||||
{
|
||||
if (*realName == 0) continue;
|
||||
f = gzopen(realName, mode);
|
||||
|
||||
if (f != NULL) return f;
|
||||
|
||||
// If any error other than "file not found" occurred,
|
||||
// then halt immediately.
|
||||
if (errno != ENOENT) return NULL;
|
||||
}
|
||||
|
||||
/* We've tried the path and that didn't work. Now go through
|
||||
* the library area, one entry at a time.
|
||||
*/
|
||||
|
||||
if (library == NULL) return NULL;
|
||||
while (nextName(&library, file, realName, MAXSIZE) != NULL)
|
||||
{
|
||||
f = gzopen(realName, mode);
|
||||
|
||||
if (f != NULL) return f;
|
||||
|
||||
// If any error other than "file not found" occurred,
|
||||
// then halt immediately.
|
||||
if (errno != ENOENT) return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ZLIB */
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------
|
||||
* PaOpen --
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@
|
|||
#ifndef _UTILS_H
|
||||
#define _UTILS_H 1
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "utils/magic.h"
|
||||
|
||||
/*
|
||||
|
|
@ -52,6 +56,10 @@ extern bool StrIsWhite(char *, bool);
|
|||
extern bool StrIsInt(char *);
|
||||
extern bool StrIsNumeric(char *);
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
extern gzFile PaZOpen(char *, char *, char *, char *, char *, char **);
|
||||
#endif
|
||||
|
||||
extern int SetNoisyBool(bool *, char *, FILE *);
|
||||
|
||||
#ifdef FILE_LOCKS
|
||||
|
|
|
|||
Loading…
Reference in New Issue