Added the capability to handle compressed GDS files through the use
of systems calls to "gzip" and "gunzip". A compressed GDS file can be made simply by doing "gds write <name>.gds.gz", and can be read simply by doing "gds read <name>.gds.gz". Names of compressed files can be put in the GDS_FILE property of a cell.
This commit is contained in:
parent
468a8ae0be
commit
85d8ad6622
|
|
@ -943,12 +943,43 @@ calmaProcessDef(def, outf, do_library)
|
|||
size_t defsize, numbytes;
|
||||
off_t cellstart, cellend, structstart;
|
||||
dlong cval;
|
||||
int namelen;
|
||||
char *modName;
|
||||
FILE *fi;
|
||||
|
||||
/* Handle compressed files */
|
||||
|
||||
modName = filename;
|
||||
namelen = strlen(filename);
|
||||
if ((namelen > 4) && !strcmp(filename + namelen - 3, ".gz"))
|
||||
{
|
||||
char *sysCmd, sptr;
|
||||
|
||||
sptr = strrchr(filename, '/');
|
||||
if (sptr == NULL)
|
||||
sptr = filename;
|
||||
else
|
||||
sptr++;
|
||||
|
||||
modName = StrDup((char **)NULL, sptr);
|
||||
*(modName + strlen(modName) - 3) = '\0';
|
||||
|
||||
sysCmd = mallocMagic(18 + namelen + strlen(modName));
|
||||
sprinf(sysCmd, "gunzip -c -k %s > %s", filename, modName);
|
||||
if (system(sysCmd) != 0)
|
||||
{
|
||||
/* File didn't uncompress. Go back to original name,
|
||||
* although that will probably fail and raise an error.
|
||||
*/
|
||||
freeMagic(modName);
|
||||
modName = filename;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use PaOpen() so the paths searched are the same as were */
|
||||
/* searched to find the .mag file that indicated this GDS file. */
|
||||
|
||||
fi = PaOpen(filename, "r", "", Path, CellLibPath, &retfilename);
|
||||
fi = PaOpen(modName, "r", "", Path, CellLibPath, &retfilename);
|
||||
if (fi == NULL)
|
||||
{
|
||||
/* This is a rare error, but if the subcell is inside */
|
||||
|
|
@ -964,7 +995,9 @@ calmaProcessDef(def, outf, do_library)
|
|||
|
||||
TxError("Calma output error: Can't find GDS file \"%s\" "
|
||||
"for vendor cell \"%s\". It will not be output.\n",
|
||||
filename, def->cd_name);
|
||||
modName, def->cd_name);
|
||||
|
||||
if (modName != filename) freeMagic(modName);
|
||||
|
||||
if (CalmaAllowUndefined)
|
||||
return 0;
|
||||
|
|
@ -1112,6 +1145,17 @@ calmaProcessDef(def, outf, do_library)
|
|||
}
|
||||
fclose(fi);
|
||||
|
||||
if (modName != filename)
|
||||
{
|
||||
/* Remove the uncompressed file */
|
||||
if (unlink(modName) != 0)
|
||||
{
|
||||
TxError("Error attempting to delete uncompressed file \"%s\"\n",
|
||||
modName);
|
||||
}
|
||||
freeMagic(modName);
|
||||
}
|
||||
|
||||
/* Mark the definition as vendor GDS so that magic doesn't */
|
||||
/* try to generate subcell interaction or array interaction */
|
||||
/* paint for it. */
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ CmdCalma(w, cmd)
|
|||
char **msg, *namep, *dotptr;
|
||||
CellDef *rootDef;
|
||||
FILE *f;
|
||||
int namelen;
|
||||
bool gzipd;
|
||||
char *realName, *saveName, *modName;
|
||||
|
||||
extern int CalmaFlattenLimit;
|
||||
|
||||
|
|
@ -870,11 +873,54 @@ 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 -k %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(cmd->tx_argv[2], "r", gdsExts[ext], Path,
|
||||
if ((f = PaOpen(modName, "r", gdsExts[ext], Path,
|
||||
(char *) NULL, &namep)) != (FILE *)NULL)
|
||||
break;
|
||||
|
||||
|
|
@ -887,6 +933,18 @@ CmdCalma(w, cmd)
|
|||
}
|
||||
CalmaReadFile(f, namep);
|
||||
(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);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -898,8 +956,20 @@ CmdCalma(w, cmd)
|
|||
outputCalma:
|
||||
dotptr = strrchr(namep, '.');
|
||||
|
||||
/* Check for additional ".gz" extension */
|
||||
if (!strcmp(dotptr, ".gz"))
|
||||
{
|
||||
gzipd = TRUE;
|
||||
*dotptr = '\0';
|
||||
dotptr = strrchr(namep, '.');
|
||||
}
|
||||
else
|
||||
gzipd = FALSE;
|
||||
|
||||
f = PaOpen(namep, "w", (dotptr == NULL) ? ".gds" : "", ".",
|
||||
(char *) NULL, (char **) NULL);
|
||||
(char *) NULL, (char **)&realName);
|
||||
if (gzipd)
|
||||
saveName = StrDup((char **)NULL, realName);
|
||||
|
||||
if (f == (FILE *) NULL)
|
||||
{
|
||||
|
|
@ -914,6 +984,24 @@ outputCalma:
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -672,6 +672,8 @@ X_PRE_LIBS
|
|||
X_CFLAGS
|
||||
XMKMF
|
||||
PYTHON3
|
||||
GUNZIP
|
||||
GZIP
|
||||
CSH
|
||||
GCORE
|
||||
EGREP
|
||||
|
|
@ -5327,6 +5329,103 @@ if test "x${CSH}" = "xno"; then
|
|||
as_fn_error $? "cannot find /bin/csh---cannot compile!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
# Extract the first word of "gzip", so it can be a program name with args.
|
||||
set dummy gzip; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_GZIP+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $GZIP in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
test -z "$ac_cv_path_GZIP" && ac_cv_path_GZIP="no"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
GZIP=$ac_cv_path_GZIP
|
||||
if test -n "$GZIP"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $GZIP" >&5
|
||||
$as_echo "$GZIP" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x${GZIP}" = "xno"; then
|
||||
as_fn_error $? "cannot find gzip---will not be able to compress large files" "$LINENO" 5
|
||||
else
|
||||
$as_echo "#define HAVE_GZIP 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
# Extract the first word of "gunzip", so it can be a program name with args.
|
||||
set dummy gunzip; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_GUNZIP+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $GUNZIP in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_GUNZIP="$GUNZIP" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_GUNZIP="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
test -z "$ac_cv_path_GUNZIP" && ac_cv_path_GUNZIP="no"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
GUNZIP=$ac_cv_path_GUNZIP
|
||||
if test -n "$GUNZIP"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $GUNZIP" >&5
|
||||
$as_echo "$GUNZIP" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test "x${GUNZIP}" = "xno"; then
|
||||
as_fn_error $? "cannot find gunzip---will not be able to automatically uncompress files" "$LINENO" 5
|
||||
else
|
||||
$as_echo "#define HAVE_GUNZIP 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Extract the first word of "python3", so it can be a program name with args.
|
||||
set dummy python3; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
|
|
|
|||
|
|
@ -285,6 +285,23 @@ if test "x${CSH}" = "xno"; then
|
|||
AC_MSG_ERROR([cannot find /bin/csh---cannot compile!])
|
||||
fi
|
||||
|
||||
dnl gzip and gunzip are used for file compression and uncompression of
|
||||
dnl large files (e.g., GDS)
|
||||
AC_PATH_PROG([GZIP], [gzip], [no])
|
||||
if test "x${GZIP}" = "xno"; then
|
||||
AC_MSG_ERROR([cannot find gzip---will not be able to compress large files])
|
||||
else
|
||||
AC_DEFINE(HAVE_GZIP)
|
||||
fi
|
||||
|
||||
AC_PATH_PROG([GUNZIP], [gunzip], [no])
|
||||
if test "x${GUNZIP}" = "xno"; then
|
||||
AC_MSG_ERROR([cannot find gunzip---will not be able to automatically uncompress files])
|
||||
else
|
||||
AC_DEFINE(HAVE_GUNZIP)
|
||||
fi
|
||||
|
||||
|
||||
dnl Python3 is preferred for running the preprocessor script
|
||||
dnl but CPP can be used instead.
|
||||
AC_PATH_PROG([PYTHON3], [python3], [no])
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ extern int LookupStructFull();
|
|||
extern int PaExpand(char **, char **, int);
|
||||
extern char *nextName();
|
||||
extern FILE *PaOpen(char *, char *, char *, char *, char *, char **);
|
||||
extern FILE *PaZOpen(char *, char *, char *, char *, char *, char **, bool *);
|
||||
extern FILE *PaLockOpen(char *, char *, char *, char *, char *, char **, bool *);
|
||||
extern char *StrDup(char **, char *);
|
||||
extern int Match();
|
||||
|
|
|
|||
Loading…
Reference in New Issue