#!/usr/bin/env python3
#
# split_spice.py --
#
# Script that reads the SPICE output from the convert_spectre.py script,
# which typically has parsed through files containing inline subcircuits
# and recast them as normal SPICE .subckt ... .ends entries, and pulled
# any model blocks inside the inline subckt out.  This script removes
# each .subckt ... .ends block from every file and moves it to its own
# file named <subckt_name>.spice.
#
# The arguments are <path_to_input> and <path_to_output>.  If there is
# only one argument, or if <path_to_input> is equal to <path_to_output>,
# then the new .spice files are added to the directory and the model
# files are modified in place.  Otherwise, all modified files are placed
# in <path_to_output>.

import os
import sys
import re
import glob

def usage():
    print('split_spice.py <path_to_input> <path_to_output>')

def convert_file(in_file, out_path, out_file):

    # Regexp patterns
    paramrex = re.compile(r'\.param[ \t]+(.*)')
    subrex = re.compile(r'\.subckt[ \t]+([^ \t]+)[ \t]+([^ \t]*)')
    modelrex = re.compile(r'\.model[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+(.*)')
    endsubrex = re.compile(r'\.ends[ \t]+(.+)')
    increx = re.compile(r'\.include[ \t]+')

    with open(in_file, 'r') as ifile:
        inplines = ifile.read().splitlines()

    insubckt = False
    inparam = False
    inmodel = False
    inpinlist = False
    spicelines = []
    subcktlines = []
    savematch = None
    subname = ''
    modname = ''
    modtype = ''

    for line in inplines:

        # Item 1.  Handle comment lines
        if line.startswith('*'):
            if subcktlines != []:
                subcktlines.append(line.strip())
            else:
                spicelines.append(line.strip())
            continue

        # Item 2.  Flag continuation lines
        if line.startswith('+'):
            contline = True
        else:
            contline = False
            if inparam:
                inparam = False
            if inpinlist:
                inpinlist = False

        # Item 3.  Handle blank lines like comment lines
        if line.strip() == '':
            if subcktlines != []:
                subcktlines.append(line)
            else:
                spicelines.append(line)
            continue

        # Item 4.  Handle continuation lines
        if contline:
            if inparam:
                # Continue handling parameters
                if subcktlines != []:
                    subcktlines.append(line)
                else:
                    spicelines.append(line)
                continue

        # Item 5.  Regexp matching

        # If inside a subcircuit, remove "parameters".  If outside,
        # change it to ".param"
        pmatch = paramrex.match(line)
        if pmatch:
            inparam = True
            if insubckt:
                subcktlines.append(line)
            else:
                spicelines.append(line)
            continue

        # model
        mmatch = modelrex.match(line)
        if mmatch:
            modellines = []
            modname = mmatch.group(1)
            modtype = mmatch.group(2)

            spicelines.append(line)
            inmodel = 2
            continue

        if not insubckt:
            # Things to parse if not in a subcircuit

            imatch = subrex.match(line)
            if imatch:
                insubckt = True
                subname = imatch.group(1)
                devrex = re.compile(subname + r'[ \t]*([^ \t]+)[ \t]*([^ \t]+)[ \t]*(.*)', re.IGNORECASE)
                inpinlist = True
                subcktlines.append(line)
                continue

        else:
            # Things to parse when inside of a ".subckt" block

            if inpinlist:
                # Watch for pin list continuation line.
                subcktlines.append(line)
                continue
                
            else:
                ematch = endsubrex.match(line)
                if ematch:
                    if ematch.group(1) != subname:
                        print('Error:  "ends" name does not match "subckt" name!')
                        print('"ends" name = ' + ematch.group(1))
                        print('"subckt" name = ' + subname)

                    subcktlines.append(line)

                    # Dump the contents of subcktlines into a file
                    subckt_file = subname + '.spice'
                    with open(out_path + '/' + subckt_file, 'w') as ofile:
                        print('* Subcircuit definition of cell ' + subname, file=ofile)
                        for line in subcktlines:
                            print(line, file=ofile)
                        subcktlines = []

                    # Add an include statement to this file in the source
                    spicelines.append('.include ' + subckt_file)

                    insubckt = False
                    inmodel = False
                    subname = ''
                    continue

        # Copy line as-is
        if insubckt:
            subcktlines.append(line)
        else:
            spicelines.append(line)

    # Output the result to out_file.
    with open(out_path + '/' + out_file, 'w') as ofile:
        for line in spicelines:
            print(line, file=ofile)

if __name__ == '__main__':
    debug = False

    if len(sys.argv) == 1:
        print("No options given to split_spice.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 split_spice.py.")
        usage()
        sys.exit(0)

    if '-debug' in optionlist:
        debug = True

    inpath = arguments[0]
    outpath = arguments[1]
    do_one_file = False

    if not os.path.exists(inpath):
        print('No such source directory ' + inpath)
        sys.exit(1)

    if os.path.isfile(inpath):
        do_one_file = True

    if do_one_file:
        if os.path.exists(outpath):
            print('Error:  File ' + outpath + ' exists.')
            sys.exit(1)
        convert_file(inpath, outpath)

    else:
        if not os.path.exists(outpath):
            os.makedirs(outpath)

        infilelist = glob.glob(inpath + '/*')

        for filename in infilelist:
            fileext = os.path.splitext(filename)[1]

            # Ignore verilog or verilog-A files that might be in a model directory
            if fileext == '.v' or fileext == '.va':
                continue

            froot = os.path.split(filename)[1]
            convert_file(filename, outpath, froot)

    print('Done.')
    exit(0)
