From 97441bc07aa13e13d38ef405bc6c0e4b261973a0 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 21 Jan 2022 13:05:24 -0500 Subject: [PATCH] Extended the GDS timestamp handling to GDS input. Unlike former behavior, in which all cells read from GDS are given a zero timestamp, and the timestamp is set when the file is written to disk, the default behavior now is to set the layout cell's timestamp from the timestamp provided in the GDS (the creation date timestamp, specifically). The same command "gds datestamp" implemented in the previous commit for GDS writes now also applies to GDS reads: If set to "no", then the timestamp value from the GDS file is transferred to the layout view (default behavior); if set to "yes", then the timestamp is set to zero (legacy behavior). If set to a value, then the value is used as the timestamp. --- calma/CalmaRdcl.c | 12 +++++++- calma/CalmaRdio.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++ doc/html/gds.html | 9 ++++++ 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index cf81d1b1..4281f331 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -301,6 +301,7 @@ calmaParseStructure(filename) int nbytes, rtype, nsrefs, osrefs, npaths; char *strname = NULL; HashEntry *he; + int timestampval = 0; int suffix; int mfactor; off_t filepos; @@ -318,7 +319,7 @@ calmaParseStructure(filename) /* Read the structure name */ was_initialized = FALSE; predefined = FALSE; - if (!calmaSkipExact(CALMA_BGNSTR)) goto syntaxerror; + if (!calmaReadStampRecord(CALMA_BGNSTR, ×tampval)) goto syntaxerror; if (!calmaReadStringRecord(CALMA_STRNAME, &strname)) goto syntaxerror; TxPrintf("Reading \"%s\".\n", strname); @@ -392,6 +393,15 @@ calmaParseStructure(filename) cifCurReadPlanes = cifSubcellPlanes; cifReadCellDef->cd_flags &= ~CDDEREFERENCE; + /* Set timestamp from the GDS cell's creation time */ + /* timestamp, unless "calma datestamp" was specified */ + /* with a value, in which case use that value. */ + + if (CalmaDateStamp == NULL) + cifReadCellDef->cd_timestamp = timestampval; + else + cifReadCellDef->cd_timestamp = *CalmaDateStamp; + /* For read-only cells, set flag in def */ if (CalmaReadOnly) cifReadCellDef->cd_flags |= CDVENDORGDS; diff --git a/calma/CalmaRdio.c b/calma/CalmaRdio.c index e9d6e679..4a0e7add 100644 --- a/calma/CalmaRdio.c +++ b/calma/CalmaRdio.c @@ -23,6 +23,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include #include +#include #include @@ -272,6 +273,81 @@ eof: return (FALSE); } +/* + * ---------------------------------------------------------------------------- + * + * calmaReadStampRecord -- + * + * Read a record that contains a pair of timestamps for creation and + * modification dates. + * + * Results: + * TRUE on success, FALSE if the record type we read is not + * what we're expecting. + * + * Side effects: + * Consumes input. + * Translates the creation timestamp from GDS format to a standard + * UNIX (time.h) timestamp (seconds since the epoch). + * Stores the result in the integer pointed to by 'stampptr'. + * + * ---------------------------------------------------------------------------- + */ + +bool +calmaReadStampRecord(type, stampptr) + int type; + int *stampptr; +{ + int nbytes, rtype; + struct tm gds_timestamp; + + READRH(nbytes, rtype); + if (nbytes < 0) + goto eof; + + if (type != rtype) + { + calmaUnexpected(type, rtype); + return (FALSE); + } + + nbytes -= CALMAHEADERLENGTH; + if (nbytes != 24) + { + /* Not dealing with any timestamp that is not in I2 format */ + calmaSkipBytes(nbytes); + if (stampptr) *stampptr = 0; + CalmaReadError("Unknown timestamp format; setting timestamp to zero.\n"); + return TRUE; + } + + gds_timestamp.tm_wday = 0; /* Not used by mktime() */ + gds_timestamp.tm_yday = 0; /* Not used by mktime() */ + gds_timestamp.tm_isdst = -1; + + READI2(gds_timestamp.tm_year); + READI2(gds_timestamp.tm_mon); + READI2(gds_timestamp.tm_mday); + READI2(gds_timestamp.tm_hour); + READI2(gds_timestamp.tm_min); + READI2(gds_timestamp.tm_sec); + + /* GDS timestamps differ from UNIX time structure only by a */ + /* difference of 1 in the month count. */ + gds_timestamp.tm_mon--; + + /* Skip the modification date timestamp */ + (void) calmaSkipBytes(nbytes - 12); + + if (stampptr) *stampptr = (int)mktime(&gds_timestamp); + return (TRUE); + +eof: + CalmaReadError("Unexpected EOF.\n"); + return (FALSE); +} + /* * ---------------------------------------------------------------------------- * diff --git a/doc/html/gds.html b/doc/html/gds.html index a8723633..a0412946 100644 --- a/doc/html/gds.html +++ b/doc/html/gds.html @@ -68,6 +68,15 @@ Read GDSII input or generate GDSII output. Options for gds read:
+
datestamp [yes|no|value] +
When reading a GDS file, the resulting layout views in magic + will be timestamped according to the declared datestamp + action. If yes (the default), then the creation date + timestamp from the GDS file is transferred to the layout cell. + If no, then the datestamp is set to zero and will be + created when the cell is saved to disk. If value, + then the specified value (in UNIX format of seconds since the + epoch) will be used for the layout timestamp.
drccheck [yes|no]
If set to no, then do not mark cells read from GDS as requiring DRC checks (default yes).