#!/usr/bin/env python3
#
# fixspice ---
#
# This script fixes problems in SPICE models to make them ngspice-compatible.
# The methods searched and corrected in this file correspond to ngspice
# version 30.
#
# This script is a filter to be run by setting the name of this script as
# the value to "filter=" for the model install in the PDK Makefile in
# open_pdks.
#
# This script converted from the bash script by Risto Bell, with improvements.
#
# This script is minimally invasive to the original SPICE file, making changes
# while preserving comments and line continuations.  In order to properly parse
# the file, comments and line continuations are recorded and removed from the
# file contents, then inserted again before the modified file is written.

import re
import os
import sys
import textwrap

def filter(inname, outname, debug=False):
    notparsed = []

    # Read input.  Note that splitlines() performs the additional fix of
    # correcting carriage-return linefeed (CRLF) line endings.
    try:
        with open(inname, 'r') as inFile:
            spitext = inFile.read()
    except:
        print('fixspice.py: failed to open ' + inname + ' for reading.', file=sys.stderr)
        return 1
    else:
        if debug:
            print('Fixing ngspice incompatibilities in file ' + inname + '.')

    # Due to the complexity of comment lines embedded within continuation lines,
    # the result needs to be processed line by line.  Blank lines and comment
    # lines are removed from the text, replaced with tab characters, and collected
    # in a separate array.  Then the continuation lines are unfolded, and each
    # line processed.  Then it is all put back together at the end.

    # First replace all tabs with spaces so we can use tabs as markers.
    spitext = spitext.replace('\t', '    ')

    # Now do an initial line split
    spilines = spitext.splitlines()

    # Search lines for comments and blank lines and replace them with tabs
    # Replace continuation lines with tabs and preserve the position.
    spitext = ''
    for line in spilines:
        if len(line) == 0:
            notparsed.append('\n')
            spitext += '\t '
        elif line[0] == '*':
            notparsed.append('\n' + line)
            spitext += '\t '
        elif line[0] == '+':
            notparsed.append('\n+')
            spitext += '\t ' + line[1:]
        else:
            spitext += '\n' + line

    # Now split back into an array of lines
    spilines = spitext.splitlines()

    # Process input with regexp

    fixedlines = []
    modified = False

    # Regular expression to find 'agauss(a,b,c)' lines and record a, b, and c
    grex = re.compile(r'[^{]agauss\(([^,]*),([^,]*),([^)]*)\)', re.IGNORECASE)

    # Regular expression to determine if the line is a .PARAM card    
    paramrex = re.compile(r'^\.param', re.IGNORECASE)
    # Regular expression to determine if the line is a .MODEL card    
    modelrex = re.compile(r'^\.model', re.IGNORECASE)
    # Regular expression to detect a .SUBCKT card
    subcktrex = re.compile(r'^\.subckt', re.IGNORECASE)

    for line in spilines:
        devtype = line[0].upper() if len(line) > 0 else 0

        # NOTE:  All filter functions below take variable fixedline, alter it, then
        # set fixedline to the altered text for the next filter function.

        fixedline = line

        # Fix: Wrap "agauss(...)" in brackets and remove single quotes around expressions
        # Example:
        #    before: + SD_DN_CJ=agauss(7.900e-04,'1.580e-05*__LOT__',1)   dn_cj=SD_DN_CJ"
        #    after:  + SD_DN_CJ={agauss(7.900e-04,1.580e-05*__LOT__,1)}   dn_cj=SD_DN_CJ"

        # for gmatch in grex.finditer(fixedline):
        while True:
            gmatch = grex.search(fixedline)
            if gmatch:
                fixpart1 = gmatch.group(1).strip("'")
                fixpart2 = gmatch.group(2).strip("'")
                fixpart3 = gmatch.group(3).strip("'")
                fixedline = fixedline[0:gmatch.span(0)[0] + 1] + '{agauss(' + fixpart1 + ',' + fixpart2 + ',' + fixpart3 + ')}' + fixedline[gmatch.span(0)[1]:]
                if debug:
                    print('Fixed agauss() call.')
            else:
                break

        # Fix: Check for "dtemp=dtemp" and remove unless in a .param line
        pmatch = paramrex.search(fixedline)
        if not pmatch:
            altered = re.sub(' dtemp=dtemp', ' ', fixedline, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Removed dtemp=dtemp from instance call')

        # Fixes related to .MODEL cards:

        mmatch = modelrex.search(fixedline)
        if mmatch:

            modeltype = fixedline.split()[2].lower()

            if modeltype == 'nmos' or modeltype == 'pmos':

                # Fixes related specifically to MOS models:

                # Fix: Look for hspver=98.2 in FET model
                altered = re.sub(r' hspver[ ]*=[ ]*98\.2', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed hspver=98.2 from ' + modeltype + ' model')

                # Fix:  Change level 53 FETs to level 49
                altered = re.sub(r' (level[ ]*=[ ]*)53', ' \g<1>49', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Changed level 53 ' + modeltype + ' to level 49')

                # Fix: Look for version=4.3 or 4.5 FETs, change to 4.8.0 per recommendations
                altered = re.sub(r' (version[ ]*=[ ]*)4\.[35]', ' \g<1>4.8.0',
					fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Changed version 4.3/4.5 ' + modeltype + ' to version 4.8.0')
    
                # Fix: Look for mulu0= (NOTE:  Might be supported for bsim4?)
                altered = re.sub('mulu0[ ]*=[ ]*[0-9.e+-]*', '', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed mulu0= from ' + modeltype + ' model')

                # Fix: Look for apwarn=
                altered = re.sub(' apwarn[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed apwarn= from ' + modeltype + ' model')

                # Fix: Look for lmlt=
                altered = re.sub(' lmlt[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed lmlt= from ' + modeltype + ' model')

                # Fix: Look for nf=
                altered = re.sub(' nf[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed nf= from ' + modeltype + ' model')

                # Fix: Look for sa/b/c/d/=
                altered = re.sub(' s[abcd][ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed s[abcd]= from ' + modeltype + ' model')

                # Fix: Look for binflag= in MOS .MODEL
                altered = re.sub(' binflag[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed binflag= from ' + modeltype + ' model')

                # Fix: Look for wref, lref= in MOS .MODEL (note:  could be found in other models?)
                altered = re.sub(' [wl]ref[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
                if altered != fixedline:
                    fixedline = altered
                    if debug:
                        print('Removed lref= from MOS .MODEL')

            # TREF is a known issue for (apparently?) all device types
            # Fix: Look for tref= in .MODEL
            altered = re.sub(' tref[ ]*=[ ]*[0-9.e+-]*', ' ', fixedline, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Removed tref= from ' + modeltype + ' model')

            # Fix: Look for double-dot model binning and replace with single dot
            altered = re.sub(r'\.\.([0-9]+)', '.\g<1>', fixedline, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Collapsed double-dot model binning.')

        # Various deleted parameters above may appear in instances, so those must be
        # caught as well.  Need to catch expressions and variables in addition to the
        # usual numeric assignments.

        if devtype == 'M':
            altered = re.sub(r' nf=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
            altered = re.sub(r' nf=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Removed nf= from MOSFET device instance')

            altered = re.sub(r' mulu0=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
            altered = re.sub(r' mulu0=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Removed mulu0= from MOSFET device instance')

            altered = re.sub(r' s[abcd]=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
            altered = re.sub(r' s[abcd]=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Removed s[abcd]= from MOSFET device instance')

        # Remove tref= from all device type instances
        altered = re.sub(r' tref=[^ \'\t]+', ' ', fixedline, flags=re.IGNORECASE)
        altered = re.sub(r' tref=\'[^\'\t]+\'', ' ', altered, flags=re.IGNORECASE)
        if altered != fixedline:
            fixedline = altered
            if debug:
                print('Removed tref= from device instance')

        # Check for use of ".subckt ...  <name>=l" (or <name>=w) with no antecedent
        # for 'w' or 'l'.  It is the responsibility of the technology file for extraction
        # to produce the correct name to pass to the subcircuit for length or width.

        smatch = subcktrex.match(fixedline)
        if smatch:
            altered = fixedline
            if fixedline.lower().endswith('=l'):
                if ' l=' not in fixedline.lower():
                    altered=re.sub( '=l$', '=0', fixedline, flags=re.IGNORECASE)
            elif '=l ' in fixedline.lower():
                if ' l=' not in fixedline.lower():
                    altered=re.sub( '=l ', '=0 ', altered, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Replaced use of "l" with no definition in .subckt line')

            altered = fixedline
            if fixedline.lower().endswith('=w'):
                if ' w=' not in fixedline.lower():
                    altered=re.sub( '=w$', '=0', fixedline, flags=re.IGNORECASE)
            elif '=w ' in fixedline.lower():
                if ' w=' not in fixedline.lower():
                    altered=re.sub( '=w ', '=0 ', altered, flags=re.IGNORECASE)
            if altered != fixedline:
                fixedline = altered
                if debug:
                    print('Replaced use of "w" with no definition in .subckt line')

        fixedlines.append(fixedline)
        if fixedline != line:
            modified = True

    # Reinsert embedded comments and continuation lines
    if debug:
        print('Reconstructing output')
    olines = []
    for line in fixedlines:
        while '\t ' in line:
            line = line.replace('\t ', notparsed.pop(0), 1)
        olines.append(line)

    fixedlines = '\n'.join(olines).strip()
    olines = fixedlines.splitlines()

    # Write output
    if debug:
        print('Writing output')
    if outname == None:
        for line in olines:
            print(line)
    else:
        # If the output is a symbolic link but no modifications have been made,
        # then leave it alone.  If it was modified, then remove the symbolic
        # link before writing.
        if os.path.islink(outname):
            if not modified:
                return 0
            else:
                os.unlink(outname)
        try:
            with open(outname, 'w') as outFile:
                for line in olines:
                    print(line, file=outFile)
        except:
            print('fixspice.py: failed to open ' + outname + ' for writing.', file=sys.stderr)
            return 1


if __name__ == '__main__':

    # This script expects to get one or two arguments.  One argument is
    # mandatory and is the input file.  The other argument is optional and
    # is the output file.  The output file and input file may be the same
    # name, in which case the original input is overwritten.

    options = []
    arguments = []
    for item in sys.argv[1:]:
        if item.find('-', 0) == 0:
            options.append(item[1:])
        else:
            arguments.append(item)

    if len(arguments) > 0:
        infilename = arguments[0]

    if len(arguments) > 1:
        outfilename = arguments[1]
    else:
        outfilename = None

    debug = True if 'debug' in options else False

    result = filter(infilename, outfilename, debug)
    sys.exit(result)
