Adding getting library+library version+cell from pathname.
diff --git a/scripts/python-skywater-pdk/skywater_pdk/base.py b/scripts/python-skywater-pdk/skywater_pdk/base.py
index 84ce182..08096a6 100644
--- a/scripts/python-skywater-pdk/skywater_pdk/base.py
+++ b/scripts/python-skywater-pdk/skywater_pdk/base.py
@@ -14,11 +14,140 @@
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from enum import Enum
-from typing import Optional
+from typing import Optional, Union, Tuple
-def parse_filename(pathname):
- """Extract library and module name from pathname.
+LibraryOrCell = Union['Library', 'Cell']
+
+
+def parse_pathname(pathname):
+ """Extract library and module name for pathname.
+
+ Returns
+ -------
+ obj : Library or Cell
+ Library or Cell information parsed from filename
+ filename : str, optional
+ String containing any filename extracted.
+ String containing the file extension
+
+ >>> parse_pathname('skywater-pdk/libraries/sky130_fd_sc_hd/v0.0.1/cells/a2111o')
+ (Cell(name='a2111o', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash=''))), None)
+
+ >>> parse_pathname('skywater-pdk/libraries/sky130_fd_sc_hd/v0.0.1/cells/a2111o/README.rst')
+ (Cell(name='a2111o', library=Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash=''))), 'README.rst')
+
+ >>> parse_pathname('skywater-pdk/libraries/sky130_fd_sc_hd/v0.0.1')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), None)
+
+ >>> parse_pathname('skywater-pdk/libraries/sky130_fd_sc_hd/v0.0.1/README.rst')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), 'README.rst')
+
+ >>> parse_pathname('libraries/sky130_fd_sc_hd/v0.0.1')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), None)
+
+ >>> parse_pathname('libraries/sky130_fd_sc_hd/v0.0.1/README.rst')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), 'README.rst')
+
+ >>> parse_pathname('sky130_fd_sc_hd/v0.0.1')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), None)
+
+ >>> parse_pathname('sky130_fd_sc_hd/v0.0.1/README.rst')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), 'README.rst')
+
+ >>> parse_pathname('sky130_fd_sc_hd/v0.0.1/RANDOM')
+ (Library(node=LibraryNode.SKY130, source=LibrarySource('fd'), type=LibraryType.sc, name='hd', version=LibraryVersion(milestone=0, major=0, minor=1, commits=0, hash='')), 'RANDOM')
+
+ >>> parse_pathname('RANDOM') #doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ ValueError: ...
+
+ >>> parse_pathname('libraries/RANDOM/v0.0.1') #doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ ValueError: ...
+
+ >>> parse_pathname('libraries/skywater_fd_sc_hd/vA.B.C') #doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ ValueError: ...
+ """
+ if os.path.exists(pathname):
+ pathname = os.path.abspath(pathname)
+
+ pathbits = pathname.split(os.path.sep)
+ # Remove any files at the end of the path
+ filename = None
+ if '.' in pathbits[-1]:
+ if not pathbits[-1].startswith('v'):
+ filename = pathbits.pop(-1)
+
+ obj_type = None
+ obj_name = None
+
+ lib_name = None
+ lib_version = None
+
+ while len(pathbits) > 1:
+ n1 = pathbits[-1]
+ n2 = pathbits[-2]
+ if len(pathbits) > 2:
+ n3 = pathbits[-3]
+ else:
+ n3 = ''
+
+ # [..., 'cells', <cellname>]
+ # [..., 'models', <modname>]
+ if n2 in ('cells', 'models'):
+ obj_name = pathbits.pop(-1)
+ obj_type = pathbits.pop(-1)
+ continue
+ # [..., 'skywater-pdk', 'libraries', <library name>, <library version>]
+ elif n3 == "libraries":
+ lib_version = pathbits.pop(-1)
+ lib_name = pathbits.pop(-1)
+ assert pathbits.pop(-1) == 'libraries'
+ # [..., 'skywater-pdk', 'libraries', <library name>]
+ elif n2 == "libraries":
+ lib_name = pathbits.pop(-1)
+ assert pathbits.pop(-1) == 'libraries'
+ # [<library name>, <library version>]
+ elif n1.startswith('v'):
+ lib_version = pathbits.pop(-1)
+ lib_name = pathbits.pop(-1)
+ elif filename is None:
+ filename = pathbits.pop(-1)
+ continue
+ else:
+ raise ValueError('Unable to parse: {}'.format(pathname))
+ break
+
+ if not lib_name:
+ raise ValueError('Unable to parse: {}'.format(pathname))
+ lib = Library.parse(lib_name)
+ if lib_version:
+ lib.version = LibraryVersion.parse(lib_version)
+ if obj_name:
+ obj = Cell.parse(obj_name)
+ obj.library = lib
+ return obj, filename
+ else:
+ return lib, filename
+
+
+
+def parse_filename(pathname) -> Tuple[LibraryOrCell, Optional[str], Optional[str]]:
+ """Extract library and module name from filename.
+
+ Returns
+ -------
+ obj : Library or Cell
+ Library or Cell information parsed from filename
+ extra : str, optional
+ String containing any extra unparsed data (like corner information)
+ ext : str, optional
+ String containing the file extension
>>> t = list(parse_filename('sky130_fd_io__top_ground_padonlyv2__tt_1p80V_3p30V_3p30V_25C.wrap.lib'))
>>> t.pop(0)
@@ -52,7 +181,7 @@
# Extract a version if it exists.
dirbase, dirversion = os.path.split(dirname)
- if dirbase.endswith('/cells'):
+ if dirbase.endswith('cells'):
dirbase, dirversion = os.path.split(dirbase)
assert dirversion == 'cells', (dirbase, dirversion)
dirbase, dirversion = os.path.split(dirbase)