Exemple #1
0
    def default(self, cmd, line, i):
        """Check for IRAF task calls and use CL emulation mode if needed

        cmd = alpha-numeric string from beginning of line
        line = full line (including cmd, preceding blanks, etc.)
        i = index in line of first non-blank character following cmd
        """
        if self.debug > 1: self.write('default: %s - %s\n' % (cmd, line[i:]))
        if len(cmd) == 0:
            if line[i:i + 1] == '!':
                # '!' is shell escape
                # handle it here only if cl emulation is turned off
                if not self.clemulate:
                    iraf.clOscmd(line[i + 1:])
                    return ''
            elif line[i:i + 1] != '?':
                # leading '?' will be handled by CL code -- else this is Python
                return line
        elif self.clemulate == 0:
            # if CL emulation is turned off then just return
            return line
        elif keyword.iskeyword(cmd) or \
          (cmd in os.__builtins__ and cmd not in ['type', 'dir', 'help', 'set']):
            # don't mess with Python keywords or built-in functions
            # except allow 'type', 'dir, 'help' to be used in simple syntax
            return line
        elif line[i:i + 1] != "" and line[i] in '=,[':
            # don't even try if it doesn't look like a procedure call
            return line
        elif not hasattr(iraf, cmd):
            # not an IRAF command
            #XXX Eventually want to improve error message for
            #XXX case where user intended to use IRAF syntax but
            #XXX forgot to load package
            return line
        elif self.isLocal(cmd):
            # cmd is both a local variable and an IRAF task or procedure name
            # figure out whether IRAF or CL syntax is intended from syntax
            if line[i:i + 1] == "" or line[i] == "(":
                return line
            if line[i] not in string.digits and \
               line[i] not in string.ascii_letters and \
               line[i] not in "<>|":
                # this does not look like an IRAF command
                return line
            # check for some Python operator keywords
            mm = self.reword.match(line[i:])
            if mm.group() in ["is", "in", "and", "or", "not"]:
                return line
        elif line[i:i + 1] == '(':
            if cmd in ['type', 'dir', 'set']:
                # assume a standalone call of Python type, dir functions
                # rather than IRAF task
                #XXX Use IRAF help function in every case (may want to
                # change this eventually, when Python built-in help
                # gets a bit better.)
                return line
            else:
                # Not a local function, so user presumably intends to
                # call IRAF task.  Force Python mode but add the 'iraf.'
                # string to the task name for convenience.
                #XXX this find() may be improved with latest Python readline features
                j = line.find(cmd)
                return line[:j] + 'iraf.' + line[j:]
        elif not callable(getattr(iraf, cmd)):
            # variable from iraf module is not callable task (e.g.,
            # yes, no, INDEF, etc.) -- add 'iraf.' so it can be used
            # as a variable and execute as Python
            j = line.find(cmd)
            return line[:j] + 'iraf.' + line[j:]

        # if we get to here then it looks like CL code
        if self.debug > 1: self.write('CL: %s\n' % line)
        try:
            code = iraf.clExecute(line, locals=self.locals, mode='single')
            if self.logfile is not None:
                # log CL code as comment
                cllines = line.split('\n')
                for oneline in cllines:
                    self.logfile.write('# %s\n' % oneline)
                self.logfile.write(code)
                self.logfile.flush()
        except:
            self.showtraceback()
        return ''
Exemple #2
0
    def default(self, cmd, line, i):
        """Check for IRAF task calls and use CL emulation mode if needed

        cmd = alpha-numeric string from beginning of line
        line = full line (including cmd, preceding blanks, etc.)
        i = index in line of first non-blank character following cmd
        """
        if self.debug>1: self.write('default: %s - %s\n' % (cmd,line[i:]))
        if len(cmd)==0:
            if line[i:i+1] == '!':
                # '!' is shell escape
                # handle it here only if cl emulation is turned off
                if not self.clemulate:
                    iraf.clOscmd(line[i+1:])
                    return ''
            elif line[i:i+1] != '?':
                # leading '?' will be handled by CL code -- else this is Python
                return line
        elif self.clemulate == 0:
            # if CL emulation is turned off then just return
            return line
        elif keyword.iskeyword(cmd) or \
          (cmd in os.__builtins__ and cmd not in ['type', 'dir', 'help', 'set']):
            # don't mess with Python keywords or built-in functions
            # except allow 'type', 'dir, 'help' to be used in simple syntax
            return line
        elif line[i:i+1] != "" and line[i] in '=,[':
            # don't even try if it doesn't look like a procedure call
            return line
        elif not hasattr(iraf,cmd):
            # not an IRAF command
            #XXX Eventually want to improve error message for
            #XXX case where user intended to use IRAF syntax but
            #XXX forgot to load package
            return line
        elif self.isLocal(cmd):
            # cmd is both a local variable and an IRAF task or procedure name
            # figure out whether IRAF or CL syntax is intended from syntax
            if line[i:i+1] == "" or line[i] == "(":
                return line
            if line[i] not in string.digits and \
               line[i] not in string.ascii_letters and \
               line[i] not in "<>|":
                # this does not look like an IRAF command
                return line
            # check for some Python operator keywords
            mm = self.reword.match(line[i:])
            if mm.group() in ["is","in","and","or","not"]:
                return line
        elif line[i:i+1] == '(':
            if cmd in ['type', 'dir', 'set']:
                # assume a standalone call of Python type, dir functions
                # rather than IRAF task
                #XXX Use IRAF help function in every case (may want to
                # change this eventually, when Python built-in help
                # gets a bit better.)
                return line
            else:
                # Not a local function, so user presumably intends to
                # call IRAF task.  Force Python mode but add the 'iraf.'
                # string to the task name for convenience.
                #XXX this find() may be improved with latest Python readline features
                j = line.find(cmd)
                return line[:j] + 'iraf.' + line[j:]
        elif not callable(getattr(iraf,cmd)):
            # variable from iraf module is not callable task (e.g.,
            # yes, no, INDEF, etc.) -- add 'iraf.' so it can be used
            # as a variable and execute as Python
            j = line.find(cmd)
            return line[:j] + 'iraf.' + line[j:]

        # if we get to here then it looks like CL code
        if self.debug>1: self.write('CL: %s\n' % line)
        try:
            code = iraf.clExecute(line, locals=self.locals, mode='single')
            if self.logfile is not None:
                # log CL code as comment
                cllines = line.split('\n')
                for oneline in cllines:
                    self.logfile.write('# %s\n' % oneline)
                self.logfile.write(code)
                self.logfile.flush()
        except:
            self.showtraceback()
        return ''
    def executeClCommand(self):

        """Execute an arbitrary CL command"""

        # pattern match to handle special commands that write to task
        mcmd = _re_clcmd.match(self.msg)
        if mcmd is None:
            # general command
            i = string.find(self.msg,"\n")
            if i>=0:
                cmd = self.msg[:i+1]
                self.msg = self.msg[i+1:]
            else:
                cmd = self.msg
                self.msg = ""
            if not (string.find(cmd, IPCOUT) >= 0):
                # normal case -- execute the CL script code
                # redirect I/O (but don't use graphics status line)
                iraf.clExecute(cmd, Stdout=self.default_stdout,
                        Stdin=self.default_stdin, Stderr=self.default_stderr)
            else:
                #
                # Bizzaro protocol -- redirection to file with special
                # name given by IPCOUT causes output to be written back
                # to subprocess instead of to stdout.
                #
                # I think this only occurs one place in the entire system
                # (in clio/clepset.x) so I'm not trying to handle it robustly.
                # Just raise an exception if it does not fit my preconceptions.
                #
                ll = -(len(IPCOUT)+3)
                if cmd[ll:] != "> %s\n" % IPCOUT:
                    raise IrafProcessError(
                            "Error: cannot understand IPCOUT syntax in `%s'"
                            % (cmd,))
                sys.stdout.flush()
                # strip the redirection off and capture output of command
                buffer = cStringIO.StringIO()
                # redirect other I/O (but don't use graphics status line)
                iraf.clExecute(cmd[:ll]+"\n", Stdout=buffer,
                        Stdin=self.default_stdin, Stderr=self.default_stderr)
                # send it off to the task with special flag line at end
                buffer.write(IPCDONEMSG)
                self.writeString(buffer.getvalue())
                buffer.close()
        elif mcmd.group('stty'):
            # terminal window size
            if self.stdoutIsatty:
                nlines, ncols = wutil.getTermWindowSize()
            else:
                # a kluge -- if self.stdout is not a tty, assume it is a
                # file and give a large number for the number of lines
                nlines, ncols = 100000, 80
            self.writeString('set ttynlines=%d\nset ttyncols=%d\n' %
                    (nlines, ncols))
            self.msg = self.msg[mcmd.end():]
        elif mcmd.group('curpack'):
            # current package request
            self.writeString(iraf.curpack() + '\n')
            self.msg = self.msg[mcmd.end():]
        elif mcmd.group('sysescape'):
            # OS escape
            tmsg = mcmd.group('sys_cmd')
            # use my version of system command so redirection works
            sysstatus = iraf.clOscmd(tmsg, Stdin=self.stdin,
                    Stdout=self.stdout, Stderr=self.stderr)
            self.writeString(str(sysstatus)+"\n")
            self.msg = self.msg[mcmd.end():]
            # self.stdout.write(self.msg + "\n")
        else:
            # should never get here
            raise RuntimeError(
                            "Program bug: uninterpreted message `%s'"
                            % (self.msg,))