Corrected an error in change_gds_cell that fails to handle the
GDSism of a null byte after an odd-length string. Added another
helper script called find_gds_prefix.py which can find cells with
a prefix as added by magic's "gds write" command when dumping a
full GDS library into the output.
diff --git a/VERSION b/VERSION
index 0a3b55e..f6e5575 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.172
+1.0.173
diff --git a/common/change_gds_cell.py b/common/change_gds_cell.py
index 7e2c22a..ddb4e4d 100755
--- a/common/change_gds_cell.py
+++ b/common/change_gds_cell.py
@@ -106,6 +106,9 @@
sys.exit(1)
bstring = celldata[dataptr + 4: dataptr + reclen]
+ # Odd length strings end in null byte which needs to be removed
+ if bstring[-1] == 0:
+ bstring = bstring[:-1]
strname = bstring.decode('ascii')
if strname == cellname:
print('Cell ' + cellname + ' found at position ' + str(saveptr))
@@ -163,6 +166,9 @@
sys.exit(1)
bstring = gdsdata[dataptr + 4: dataptr + reclen]
+ # Odd length strings end in null byte which needs to be removed
+ if bstring[-1] == 0:
+ bstring = bstring[:-1]
strname = bstring.decode('ascii')
if strname == cellname:
print('Cell ' + cellname + ' found at position ' + str(saveptr))
diff --git a/common/find_gds_prefix.py b/common/find_gds_prefix.py
new file mode 100755
index 0000000..aeab8cc
--- /dev/null
+++ b/common/find_gds_prefix.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+#
+# Script to read a GDS file, and find the given cellname if it has the
+# standard random two-character prefix generated by magic when writing
+# out a vendor GDS, and report the prefix. No changes are made to any
+# file.
+
+import os
+import sys
+
+def usage():
+ print('find_gds_prefix.py <cell_name> <path_to_cell_gds>')
+
+if __name__ == '__main__':
+ debug = False
+
+ if len(sys.argv) == 1:
+ print("No options given to find_gds_prefix.py.")
+ usage()
+ sys.exit(0)
+
+ optionlist = []
+ arguments = []
+
+ for option in sys.argv[1:]:
+ if option.find('-', 0) == 0:
+ optionlist.append(option)
+ else:
+ arguments.append(option)
+
+ if len(arguments) != 2:
+ print("Wrong number of arguments given to find_gds_prefix.py.")
+ usage()
+ sys.exit(0)
+
+ for option in optionlist:
+ if option == '-debug':
+ debug = True
+
+ cellname = arguments[0]
+ cellsource = arguments[1]
+
+ cellsrcdir = os.path.split(cellsource)[0]
+ cellinfile = os.path.split(cellsource)[1]
+
+ print('Reading GDS file looking for prefixed cell ' + cellname)
+ with open(cellsource, 'rb') as ifile:
+ celldata = ifile.read()
+
+ #----------------------------------------------------------------------
+ # Assume that celldata contains the cell in question.
+ # Find the extend of the data from 'beginstr' to 'endstr'
+ #----------------------------------------------------------------------
+
+ datalen = len(celldata)
+ dataptr = 0
+ found = False
+ while dataptr < datalen:
+ # Read stream records up to 'beginstr'
+ bheader = celldata[dataptr:dataptr + 2]
+ reclen = int.from_bytes(bheader, 'big')
+ if reclen == 0:
+ print('Error: found zero-length record at position ' + str(dataptr))
+ break
+
+ rectype = celldata[dataptr + 2]
+ datatype = celldata[dataptr + 3]
+
+ brectype = rectype.to_bytes(1, byteorder='big')
+ bdatatype = datatype.to_bytes(1, byteorder='big')
+
+ if rectype == 5: # beginstr
+ saveptr = dataptr
+
+ elif rectype == 6: # strname
+ if datatype != 6:
+ print('Error: Structure name record is not a string!')
+ sys.exit(1)
+
+ bstring = celldata[dataptr + 4: dataptr + reclen]
+ # Odd length strings end in null byte which needs to be removed
+ if bstring[-1] == 0:
+ bstring = bstring[:-1]
+ strname = bstring.decode('ascii')
+ if strname[3:] == cellname:
+ print('Cell ' + strname + ' found at position ' + str(saveptr))
+ print('Prefix: ' + strname[0:2])
+ found = True
+ break
+ elif strname == cellname:
+ print('Unprefixed cell ' + strname + ' found at position ' + str(saveptr))
+ elif debug:
+ print('Cell ' + strname + ' position ' + str(dataptr) + ' (ignored)')
+
+ # Advance the pointer past the data
+ dataptr += reclen
+
+ if not found:
+ print('Failed to find a prefixed cell ' + cellname)
+ sys.exit(1)
+
+ exit(0)