blob: a5334d78cef7aa3558915c802b618c156e361076 [file] [log] [blame]
#!/usr/bin/env python3
#
#-------------------------------------------------------------------
# makestub.py
#
# Read a CDL or SPICE netlist and remove all contents from subcircuits,
# leaving only the .SUBCKT ... .ENDS wrapper. Used as a filter, so it
# replaces the original file with the modified one. If the original
# file is a symbolic link, then it is first unlinked and replaced with
# the new contents.
#
# Use:
#
# makestub.py <path_to_netlist_file>
#
#-------------------------------------------------------------------
import os
import re
import sys
import stat
import textwrap
def makeuserwritable(filepath):
if os.path.exists(filepath):
st = os.stat(filepath)
os.chmod(filepath, st.st_mode | stat.S_IWUSR)
def generate_stubs(netlist_path, output_path):
netlist_dir = os.path.split(netlist_path)[0]
netlist_filename = os.path.split(netlist_path)[1]
netlist_root = os.path.splitext(netlist_filename)[0]
netlist_ext = os.path.splitext(netlist_filename)[1]
if not os.path.exists(netlist_path):
print('Error: Specified file "' + netlist_path + '" does not exist!')
return
if output_path == None:
output_path = netlist_path
with open(netlist_path, 'r') as ifile:
spicetext = ifile.read().splitlines()
# Remove blank lines and comment lines
spicelines = []
for line in spicetext:
if len(line) > 0:
if line[0] != '*':
spicelines.append(line)
# Remove line extensions
spicetext = '\n'.join(spicelines)
spicelines = spicetext.replace('\n+', ' ').splitlines()
# SPICE subcircuit definition:
subcrex = re.compile(r'[ \t]*\.subckt[ \t]+([^ \t]+)[ \t]+(.*)$', re.IGNORECASE)
endsrex = re.compile(r'[ \t]*\.ends[ \t]*', re.IGNORECASE)
spiceoutlines = []
insub = False
for line in spicelines:
if insub:
ematch = endsrex.match(line)
if ematch:
insub = False
spiceoutlines.append(line)
else:
smatch = subcrex.match(line)
if smatch:
insub = True
spiceoutlines.append('')
spiceoutlines.append('*----------------------------------------------')
spiceoutlines.append('* SPICE stub entry for ' + smatch.group(1) + '.')
spiceoutlines.append('*----------------------------------------------')
spiceoutlines.append('')
spiceoutlines.append(line)
if output_path == netlist_path:
if os.path.islink(netlist_path):
os.unlink(netlist_path)
# Re-wrap continuation lines at 100 characters
wrappedlines = []
for line in spiceoutlines:
wrappedlines.append('\n+ '.join(textwrap.wrap(line, 100)))
# Just in case the file in the source repo is not user-writable
if os.path.exists(output_path):
makeuserwritable(output_path)
with open(output_path, 'w') as ofile:
for line in wrappedlines:
print(line, file=ofile)
# If called as main, run generate_stubs
if __name__ == '__main__':
# Divide up command line into options and arguments
options = []
arguments = []
for item in sys.argv[1:]:
if item.find('-', 0) == 0:
options.append(item)
else:
arguments.append(item)
# Need one argument: path to CDL or SPICE netlist
# If two arguments, then 2nd argument is the output file.
if len(arguments) == 2:
netlist_path = arguments[0]
output_path = arguments[1]
generate_stubs(netlist_path, output_path)
elif len(arguments) != 1:
print("Usage: makestub.py <file_path> [<output_path>]")
elif len(arguments) == 1:
netlist_path = arguments[0]
generate_stubs(netlist_path, None)