#!/usr/bin/env python
"""Parser for parsing iocShell dbLoadRecords commands
These take these forms
1) dbLoadRecords("db/iocRelease.db"   ,"IOC=SIOC:$(AREA):$(IOC_SUFF)")
2) dbLoadRecords ("db/alhCONSTPVs.db")
3) dbLoadRecords "db/asynRecord.db"
4) dbLoadRecords "db/PCOCamera.db", "P=$(PREFIX),R=:$(ID):,TIMEOUT=1,PORT=$(CAM)$(ID),ADDR=0"
5) dbLoadRecords "db/dbSimple.db", "PREFIX=KHKIM"
6) dbLoadRecords("$(AREA_DETECTOR_SUPP)/db/profile.template","P=$(PREFIX):, ID=$(ID), XSIZE=$(XSIZE), X_OFF=$(X_OFF), YSIZE=$(YSIZE), Y_OFF=$(Y_OFF), RESOLUTION=$(RESOLUTION), PREC=1, EGU=$(EGU)")
"""
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
sprintfvariablename = Rep1(letter | digit)
openParan = Str("(")
closeParan = Str(")")
comment = Bol + Str("#") + Rep(AnyBut("\n")) + Str("\n")

fileLexicon = Lexicon([
    (comment,  'comment'),
    (space, IGNORE),
    (Str("dbLoadRecords"), Begin("dbLoadRecords")),
    State('dbLoadRecords', [
                    (openParan, IGNORE),
                    (hspace, IGNORE),
                    (quote, "beginQuote"),
                    (nameinquotes, 'recordsFileInQuotes'),
                    (sprintfvariablename, 'varName'),
                    (newline, Begin('')),
                    (closeParan, Begin(''))
                    ]),
    State('beginQuote', [
                         (quote, 'recordsFile'),
                         (newline, Begin('')),
                         (closeParan, Begin(''))
                         ]),
    (space, IGNORE)
])

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

if __name__ == "__main__":
    print('|' + parseDBLoadRecordsCommand('dbLoadRecords("db/iocRelease.db"   ,"IOC=SIOC:$(AREA):$(IOC_SUFF)")') + '|')
    print('|' + parseDBLoadRecordsCommand('dbLoadRecords ("db/alhCONSTPVs.db")') + '|')
    print('|' + parseDBLoadRecordsCommand('dbLoadRecords "db/asynRecord.db"') + '|')
    print('|' + parseDBLoadRecordsCommand(
        'dbLoadRecords "db/PCOCamera.db", "P=$(PREFIX),R=:$(ID):,TIMEOUT=1,PORT=$(CAM)$(ID),ADDR=0"') + '|')
    print('|' + parseDBLoadRecordsCommand('dbLoadRecords "db/dbSimple.db", "PREFIX=KHKIM"') + '|')
    print('|' + parseDBLoadRecordsCommand(
        'dbLoadRecords("$(AREA_DETECTOR_SUPP)/db/profile.template","P=$(PREFIX):, ID=$(ID), XSIZE=$(XSIZE), X_OFF=$(X_OFF), YSIZE=$(YSIZE), Y_OFF=$(Y_OFF), RESOLUTION=$(RESOLUTION), PREC=1, EGU=$(EGU)")') + '|')
    print('|' + parseDBLoadRecordsCommand('dbLoadRecords(str,0)') + '|')
    