Logo Search packages:      
Sourcecode: kayali version File versions  Download package

engine.py

#***************************************************************************
# *   Copyright (C) 2003 by A Lynch                                  *
# *   aalynch@users.sourceforge.net                                        *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU General Public License version 2 as published by  *
# *   the Free Software Foundation;                                         *
# *                                                                         *
# *   This program is distributed in the hope that it will be useful,       *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU General Public License for more details.                          *
# *                                                                         *
# *   You should have received a copy of the GNU General Public License     *
# *   along with this program; if not, write to the                         *
# *   Free Software Foundation, Inc.,                                       *
# *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
# ***************************************************************************/

import pexpect

from PyQt4 import QtGui, QtCore

import logging, os
from configuration import config

l = logging.getLogger(__name__)

waitTime = 15.0

# NOTE maxima sends out various combinations of \r \r\n and \r\r etc. This makes pattern matching a bit tricky and hard to debug
# - use debugging statements in pexpect marked AL


class TIMEOUTERROR(Exception):
    pass
class SYNTAXERROR(Exception):
    pass
class NUMARGSERROR(Exception):
    pass

class Engine:

    def __init__(self, control):
        
        global PROMPT_INPUT, PROMPT_OUTPUT

        self.control = control
        
        self.maxima = pexpect.spawn('maxima')
        self.maxima.setecho(False)
        fout = file(os.path.join(config["tempdir"],'mylog.txt'),'w')
        self.maxima.setlog (fout)
        self.sendInput('display2d:false')

        self.sendInput('inchar:%I')
        self.sendInput('outchar:%O')
        PROMPT_INPUT = r"\(%I([0-9]+)\)"
        PROMPT_OUTPUT = r"\(%O[0-9]+\)"
        
        self.getOutput()

        self.out = ""

    def getPromptLetters(self):
        return ("%I","%O")
        
    def sendInput(self,inputstring):
        l.debug( "send input " + repr(inputstring))
        self.maxima.sendline(inputstring + ";")

    def getOutput(self):
        sExpect = [ PROMPT_OUTPUT + "+" + "(.*)" + PROMPT_INPUT, \
                   pexpect.TIMEOUT,\
                    "Incorrect syntax" + ".*" + PROMPT_INPUT,\
                    "Wrong number of arguments",\
                     "Maxima encountered.*"+PROMPT_INPUT, \
                    "Bad Range.*"+PROMPT_INPUT,\
                    "Is(.*)zero or nonzero.*\r\n\r\n\r",\
                    PROMPT_INPUT + "(.*)To debug.*" + PROMPT_INPUT, \
                    PROMPT_INPUT + " \r\r\nIs(.*)positive, negative, or z" ]
        ret = self.maxima.expect(sExpect,timeout=waitTime)
        self.out = ""
        self.index = 0
        if ret == 0:
            self.index = str(int(self.maxima.match.group(2)) - 1)
            self.out = self.maxima.match.group(1)
        elif ret == 2:
            # see if there's any more to come
            self.eatOutput()
        elif ret == 6:
            unknownValue = self.maxima.match.group(1)
            self.eatOutput()
            ans = QtGui.QMessageBox.question(None,"Kayali","Is " + unknownValue + " zero?",\
            QtGui.QMessageBox.Yes,QtGui.QMessageBox.No,QtGui.QMessageBox.NoButton)
            if ans == QtGui.QMessageBox.Yes:
                response = "zero"
            else:
                response = "nonzero"
            self.sendInput(response)
            return self.getOutput()
        elif ret == 8:
            unknownValue = self.maxima.match.group(1)
            self.eatOutput()
            ans = QtGui.QMessageBox.question(None,"Kayali","Is " + unknownValue + "positive, negative or zero?",\
            QtGui.QMessageBox.Yes,QtGui.QMessageBox.No,QtGui.QMessageBox.NoButton)
            if ans == QtGui.QMessageBox.Yes:
                response = "zero"
            else:
                response = "negative"
            self.sendInput(response)
            return self.getOutput()
        
        l.debug( "return out " + str(ret))
        return (ret, self.index)

    def eatOutput(self):
        # eat what is left in maxima output
        while (True):
            try:
                inp = self.maxima.read_nonblocking(1,1)
                if len(inp) > 1:
                    l.debug( "inp is " + repr(inp))
                    self.eatOutput()
                    continue
            except:
                return
                

    def evaluateInput(self,input):
        output = ""
        # strip input of \r and \n
        input = input.replace('\r',' ')
        input = input.replace('\n',' ')
        
        l.debug( "input is " + repr(input))
        self.sendInput(input)

        ret,index = self.getOutput()
        self.out = self.out.replace('\r',' ')
        self.out = self.out.replace('\n',' ')
            
        if ret == 1:
            QtGui.QMessageBox.information(None,"Kayali","Timeout")
            l.debug( "Timeout")
            return None,ret,index
        if ret == 2:
            QtGui.QMessageBox.information(None,"Kayali","Syntax Error")
            l.debug( "Syntax Error")
            return None,ret,index
        if ret == 3:
            QtGui.QMessageBox.information(None,"Kayali","Number of Arguments Error")
            l.debug( "Num Args Error")
            return None,ret,index
        if ret == 4:
            QtGui.QMessageBox.information(None,"Kayali","Maxima Internal Lisp Error")
            l.debug( "Internal Lisp Error")
            return None,ret,index
        if ret == 5:
            QtGui.QMessageBox.information(None,"Kayali","Bad Range")
            l.debug( "Bad Range Error")
            return None,ret,index
        if ret == 7:
            error = self.maxima.match.group(2)
            QtGui.QMessageBox.information(None,"Kayali",error)
            l.debug( "Maxima Error")
            return None,ret,index

        return (self.out, ret, index)

Generated by  Doxygen 1.6.0   Back to index