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 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,))