#!/usr/bin/env python
"""Parser for parsing iocShell include commands
These take these forms
1) < envPaths
2) < iocBoot/${IOC}/areaDetector.cfg
3) < config/epicsEnvSetDev
4) < /boot/u/ad/mboyes/work/work-EPM/iocBoot/ioctest/pre_st.cmd
5) < "../st.padgeneric.cmd"
6) < /reg/d/iocCommon/All/pre_linux.cmd
7) . "../st.fnetgeneric.lcls.cmd"
8) . "iocBoot/start_restore.cmd"
"""
from __future__ import print_function

import os
import sys
from plex import *
import random
from io import StringIO

# Here's where we define the lexicon for the parser. 
letter = Range("AZaz")
digit = Range("09")
hspace = Any(" \t")
space = Any(" \t\n")
newline = Str("\n")
spchars = Any(".-_:{}()+/*$")
comma = Str(",")
quote = Str('"')
name = Rep1(letter | digit | spchars)
nameinquotes = quote + name + quote
openParan = Str("(")
closeParan = Str(")")
includeChar = Str("<", ".")
comment = Bol + Str("#") + Rep(AnyBut("\n")) + Str("\n")

fileLexicon = Lexicon([
    (comment,  'comment'),
    (space, IGNORE),
    (includeChar, Begin("Include")),
    State('Include', [
                    (openParan, IGNORE),
                    (includeChar, IGNORE),
                    (hspace, IGNORE),
                    (nameinquotes, 'includeFileNameInQuotes'),
                    (name, 'includeFileName'),
                    (newline, Begin(''))
                    ]),
    (space, IGNORE)
])

def parseIncludeCommand(line):
    '''Parses a epics include command and returns the file name we are including'''
    scanner = Scanner(fileLexicon, StringIO(line))
    while 1:
        token = scanner.read()
        if token[0] is None:
            break
        elif token[0] == 'includeFileName':
            return token[1]
        elif token[0] == 'includeFileNameInQuotes':
            return token[1].strip('"')
        else:
            sys.stderr.write("Unknown token" + token)
    return line

"""Parser for parsing iocShell include commands
These take these forms
1) 
2) 
3) 
4) 
5) 
"""


if __name__ == "__main__":
    print('|' + parseIncludeCommand('< envPaths') + '|')
    print('|' + parseIncludeCommand('< iocBoot/${IOC}/areaDetector.cfg') + '|')
    print('|' + parseIncludeCommand('< config/epicsEnvSetDev') + '|')
    print('|' + parseIncludeCommand('< /boot/u/ad/mboyes/work/work-EPM/iocBoot/ioctest/pre_st.cmd') + '|')
    print('|' + parseIncludeCommand('< "../st.padgeneric.cmd"') + '|')
    print('|' + parseIncludeCommand('< /reg/d/iocCommon/All/pre_linux.cmd') + '|')
    print('|' + parseIncludeCommand('</usr/local/lcls/epics/iocCommon/All/Prod/soft_pre_st.cmd') + '|')
    print('|' + parseIncludeCommand('< iocBoot/ioc-und1-uc24/st-unique.cmd') + '|')
    print('|' + parseIncludeCommand('< ../../common/init_st.soft.cmd') + '|')
    print('|' + parseIncludeCommand('< ${TOP}/iocBoot/st.softgeneric.cmd') + '|')
    print('|' + parseIncludeCommand('< ${AREA_DETECTOR}/iocBoot/commonPlugins.cmd') + '|')
    print('|' + parseIncludeCommand('<<<<<< st.cmd') + '|')
    print('|' + parseIncludeCommand('. "../st.fnetgeneric.lcls.cmd"') + '|')
    print('|' + parseIncludeCommand('. "iocBoot/start_restore.cmd"') + '|')
    print('|' + parseIncludeCommand('. iocBoot/start_restore.cmd') + '|')
    
