# interp.py - shell interpreter for pysh.
#
# Copyright 2007 Patrick Mezard
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

"""Implement the shell interpreter.

Most references are made to "The Open Group Base Specifications Issue 6".
<http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html>
"""
# TODO: document the fact input streams must implement fileno() so Popen will work correctly.
# it requires non-stdin stream to be implemented as files. Still to be tested...
# DOC: pathsep is used in PATH instead of ':'. Clearly, there are path syntax issues here.
# TODO: stop command execution upon error.
# TODO: sort out the filename/io_number mess. It should be possible to use filenames only.
# TODO: review subshell implementation
# TODO: test environment cloning for non-special builtins
# TODO: set -x should not rebuild commands from tokens, assignments/redirections are lost
# TODO: unit test for variable assignment
# TODO: test error management wrt error type/utility type
# TODO: test for binary output everywhere
# BUG: debug-parsing does not pass log file to PLY. Maybe a PLY upgrade is necessary.
import base64
import cPickle as pickle
import errno
import glob
import os
import re
import subprocess
import sys
import tempfile

try:
    s = set()
    del s
except NameError:
    from Set import Set as set

import builtin
from sherrors import *
import pyshlex
import pyshyacc

def mappend(func, *args, **kargs):
    """Like map but assume func returns a list. Returned lists are merged into
    a single one.
    """
    return reduce(lambda a,b: a+b, map(func, *args, **kargs), [])

class FileWrapper:
    """File object wrapper to ease debugging.
    
    Allow mode checking and implement file duplication through a simple 
    reference counting scheme. Not sure the latter is really useful since
    only real file descriptors can be used.
    """
    def __init__(self, mode, file, close=True):
        if mode not in ('r', 'w', 'a'):
            raise IOError('invalid mode: %s' % mode)
        self._mode = mode
        self._close = close
        if isinstance(file, FileWrapper):
            if file._refcount[0] <= 0:
                raise IOError(0, 'Error')
            self._refcount = file._refcount
            self._refcount[0] += 1
            self._file = file._file
        else:
            self._refcount = [1]
            self._file = file
        
    def dup(self):
        return FileWrapper(self._mode, self, self._close)
        
    def fileno(self):
        """fileno() should be only necessary for input streams."""
        return self._file.fileno()
        
    def read(self, size=-1):
        if self._mode!='r':
            raise IOError(0, 'Error')
        return self._file.read(size)
        
    def readlines(self, *args, **kwargs):
        return self._file.readlines(*args, **kwargs)
        
    def write(self, s):
        if self._mode not in ('w', 'a'):
            raise IOError(0, 'Error')
        return self._file.write(s)
        
    def flush(self):
        self._file.flush()
        
    def close(self):        
        if not self._refcount:
            return
        assert  self._refcount[0] > 0
        
        self._refcount[0] -= 1    
        if self._refcount[0] == 0:
            self._mode = 'c'
            if self._close:
                self._file.close()
        self._refcount = None
                
    def mode(self):
        return self._mode

    def __getattr__(self, name):
        if name == 'name':
            self.name = getattr(self._file, name)
            return self.name
        else:
            raise AttributeError(name)

    def __del__(self):
        self.close()
               
               
def win32_open_devnull(mode):
    return open('NUL', mode)
    
        
class Redirections:
    """Stores open files and their mapping to pseudo-sh file descriptor.
    """
    # BUG: redirections are not handled correctly: 1>&3 2>&3 3>&4 does 
    # not make 1 to redirect to 4
    def __init__(self, stdin=None, stdout=None, stderr=None):
        self._descriptors = {}
        if stdin is not None:
            self._add_descriptor(0, stdin)
        if stdout is not None:
            self._add_descriptor(1, stdout)
        if stderr is not None:
            self._add_descriptor(2, stderr)
            
    def add_here_document(self, interp, name, content, io_number=None):
        if io_number is None:
            io_number = 0
            
        if name==pyshlex.unquote_wordtree(name):
            content = interp.expand_here_document(('TOKEN', content))
    
        # Write document content in a temporary file
        tmp = tempfile.TemporaryFile()
        try:
            tmp.write(content)
            tmp.flush()
            tmp.seek(0)
            self._add_descriptor(io_number, FileWrapper('r', tmp))
        except:
            tmp.close()
            raise                
        
    def add(self, interp, op, filename, io_number=None):
        if op not in ('<', '>', '>|', '>>', '>&'):
            # TODO: add descriptor duplication and here_documents      
            raise RedirectionError('Unsupported redirection operator "%s"' % op)
            
        if io_number is not None:
            io_number = int(io_number)
            
        if (op == '>&' and filename.isdigit()) or filename=='-':
            # No expansion for file descriptors, quote them if you want a filename
            fullname = filename
        else:
            if filename.startswith('/'):
                # TODO: win32 kludge
                if filename=='/dev/null':
                    fullname = 'NUL'
                else:
                    # TODO: handle absolute pathnames, they are unlikely to exist on the
                    # current platform (win32 for instance).
                    raise NotImplementedError()
            else:
                fullname = interp.expand_redirection(('TOKEN', filename))
                if not fullname:
                    raise RedirectionError('%s: ambiguous redirect' % filename)
                # Build absolute path based on PWD
                fullname = os.path.join(interp.get_env()['PWD'], fullname)
            
        if op=='<':
            return self._add_input_redirection(interp, fullname, io_number)
        elif op in ('>', '>|'):
            clobber = ('>|'==op)
            return self._add_output_redirection(interp, fullname, io_number, clobber)
        elif op=='>>':
            return self._add_output_appending(interp, fullname, io_number)
        elif op=='>&':
            return self._dup_output_descriptor(fullname, io_number)
        
    def close(self):
        if self._descriptors is not None:
            for desc in self._descriptors.itervalues():
                desc.flush()
                desc.close()
            self._descriptors = None
            
    def stdin(self):
        return self._descriptors[0]
          
    def stdout(self):
        return self._descriptors[1] 
        
    def stderr(self):
        return self._descriptors[2] 
            
    def clone(self):
        clone = Redirections()
        for desc, fileobj in self._descriptors.iteritems():
            clone._descriptors[desc] = fileobj.dup()
        return clone
           
    def _add_output_redirection(self, interp, filename, io_number, clobber):    
        if io_number is None:
            # io_number default to standard output
            io_number = 1
        
        if not clobber and interp.get_env().has_opt('-C') and os.path.isfile(filename):
            # File already exist in no-clobber mode, bail out
            raise RedirectionError('File "%s" already exists' % filename)
            
        # Open and register
        self._add_file_descriptor(io_number, filename, 'w')
        
    def _add_output_appending(self, interp, filename, io_number):    
        if io_number is None:
            io_number = 1
        self._add_file_descriptor(io_number, filename, 'a')
            
    def _add_input_redirection(self, interp, filename, io_number):
        if io_number is None:
            io_number = 0
        self._add_file_descriptor(io_number, filename, 'r')
        
    def _add_file_descriptor(self, io_number, filename, mode):    
        try:            
            if filename.startswith('/'):
                if filename=='/dev/null':
                    f = win32_open_devnull(mode+'b')
                else:
                    # TODO: handle absolute pathnames, they are unlikely to exist on the
                    # current platform (win32 for instance).
                    raise NotImplementedError('cannot open absolute path %s' % repr(filename))
            else:
                f = file(filename, mode+'b')
        except IOError as e:
            raise RedirectionError(str(e))
            
        wrapper = None
        try:
            wrapper = FileWrapper(mode, f)
            f = None
            self._add_descriptor(io_number, wrapper)
        except:
            if f: f.close()
            if wrapper: wrapper.close()
            raise
            
    def _dup_output_descriptor(self, source_fd, dest_fd):
        if source_fd is None:
            source_fd = 1
        self._dup_file_descriptor(source_fd, dest_fd, 'w')
            
    def _dup_file_descriptor(self, source_fd, dest_fd, mode):
        source_fd = int(source_fd)
        if source_fd not in self._descriptors:
            raise RedirectionError('"%s" is not a valid file descriptor' % str(source_fd))
        source = self._descriptors[source_fd]
        
        if source.mode()!=mode:
            raise RedirectionError('Descriptor %s cannot be duplicated in mode "%s"' % (str(source), mode))
        
        if dest_fd=='-':
            # Close the source descriptor
            del self._descriptors[source_fd]
            source.close()
        else:
            dest_fd = int(dest_fd)
            if dest_fd not in self._descriptors:
                raise RedirectionError('Cannot replace file descriptor %s' % str(dest_fd))
                
            dest = self._descriptors[dest_fd]
            if dest.mode()!=mode:
                raise RedirectionError('Descriptor %s cannot be cannot be redirected in mode "%s"' % (str(dest), mode))
            
            self._descriptors[dest_fd] = source.dup()
            dest.close()        
            
    def _add_descriptor(self, io_number, file):
        io_number = int(io_number)
        
        if io_number in self._descriptors:
            # Close the current descriptor
            d = self._descriptors[io_number]
            del self._descriptors[io_number]
            d.close()
            
        self._descriptors[io_number] = file

    def __str__(self):
        names = [('%d=%r' % (k, getattr(v, 'name', None))) for k,v
                 in self._descriptors.iteritems()]
        names = ','.join(names)
        return 'Redirections(%s)' % names

    def __del__(self):
        self.close()
    
def cygwin_to_windows_path(path):
    """Turn /cygdrive/c/foo into c:/foo, or return path if it
    is not a cygwin path.
    """
    if not path.startswith('/cygdrive/'):
        return path
    path = path[len('/cygdrive/'):]
    path = path[:1] + ':' + path[1:]
    return path
    
def win32_to_unix_path(path):
    if path is not None:
        path = path.replace('\\', '/')
    return path    
    
_RE_SHEBANG = re.compile(r'^\#!\s?([^\s]+)(?:\s([^\s]+))?')
_SHEBANG_CMDS = {
    '/usr/bin/env': 'env',
    '/bin/sh': 'pysh',
    'python': 'python',
}
    
def resolve_shebang(path, ignoreshell=False):
    """Return a list of arguments as shebang interpreter call or an empty list
    if path does not refer to an executable script.
    See <http://www.opengroup.org/austin/docs/austin_51r2.txt>.
    
    ignoreshell - set to True to ignore sh shebangs. Return an empty list instead.
    """
    try:
        f = file(path)
        try:
            # At most 80 characters in the first line
            header = f.read(80).splitlines()[0]
        finally:
            f.close()
            
        m = _RE_SHEBANG.search(header)
        if not m:
            return []
        cmd, arg = m.group(1,2)
        if os.path.isfile(cmd):
            # Keep this one, the hg script for instance contains a weird windows
            # shebang referencing the current python install.
            cmdfile = os.path.basename(cmd).lower()
            if cmdfile == 'python.exe':
                cmd = 'python'
            pass
        elif cmd not in _SHEBANG_CMDS:
            raise CommandNotFound('Unknown interpreter "%s" referenced in '\
                'shebang' % header)
        cmd = _SHEBANG_CMDS.get(cmd)
        if cmd is None or (ignoreshell and cmd == 'pysh'):
            return []
        if arg is None:
            return [cmd, win32_to_unix_path(path)]
        return [cmd, arg, win32_to_unix_path(path)]
    except IOError as e:
        if  e.errno!=errno.ENOENT and \
            (e.errno!=errno.EPERM and not os.path.isdir(path)): # Opening a directory raises EPERM
            raise
        return []
        
def win32_find_in_path(name, path):
    if isinstance(path, str):
        path = path.split(os.pathsep)
        
    exts = os.environ.get('PATHEXT', '').lower().split(os.pathsep)
    for p in path:
        p_name = os.path.join(p, name)
        
        prefix = resolve_shebang(p_name)
        if prefix:
            return prefix
            
        for ext in exts:    
            p_name_ext = p_name + ext
            if os.path.exists(p_name_ext):
                return [win32_to_unix_path(p_name_ext)]
    return []

class Traps(dict):
    def __setitem__(self, key, value):
        if key not in ('EXIT',):
            raise NotImplementedError()
        super(Traps, self).__setitem__(key, value)

# IFS white spaces character class
_IFS_WHITESPACES = (' ', '\t', '\n')

class Environment:
    """Environment holds environment variables, export table, function 
    definitions and whatever is defined in 2.12 "Shell Execution Environment",
    redirection excepted.
    """
    def __init__(self, pwd):
        self._opt = set()       #Shell options
        
        self._functions = {}        
        self._env = {'?': '0', '#': '0'}
        self._exported = set([
            'HOME', 'IFS', 'PATH'
        ])
        
        # Set environment vars with side-effects
        self._ifs_ws = None     # Set of IFS whitespace characters
        self._ifs_re = None     # Regular expression used to split between words using IFS classes
        self['IFS'] = ''.join(_IFS_WHITESPACES) #Default environment values
        self['PWD'] = pwd
        self.traps = Traps()
        
    def clone(self, subshell=False):
        env = Environment(self['PWD'])
        env._opt = set(self._opt)
        for k,v in self.get_variables().iteritems():
            if k in self._exported:
                env.export(k,v)
            elif subshell:
                env[k] = v
                
        if subshell:
            env._functions = dict(self._functions)
            
        return env        
        
    def __getitem__(self, key):
        if key in ('@', '*', '-', '$'):
            raise NotImplementedError('%s is not implemented' % repr(key))
        return self._env[key]
        
    def get(self, key, defval=None):
        try:
            return self[key]
        except KeyError:
            return defval
        
    def __setitem__(self, key, value):
        if key=='IFS':
            # Update the whitespace/non-whitespace classes
            self._update_ifs(value)
        elif key=='PWD':
            pwd = os.path.abspath(value)
            if not os.path.isdir(pwd):
                raise VarAssignmentError('Invalid directory %s' % value)
            value = pwd
        elif key in ('?', '!'):
            value = str(int(value))
        self._env[key] = value
        
    def __delitem__(self, key):
        if key in ('IFS', 'PWD', '?'):
            raise VarAssignmentError('%s cannot be unset' % key)
        del self._env[key]

    def __contains__(self, item):
        return item in self._env
        
    def set_positional_args(self, args):
        """Set the content of 'args' as positional argument from 1 to len(args).
        Return previous argument as a list of strings.
        """
        # Save and remove previous arguments
        prevargs = []        
        for i in xrange(int(self._env['#'])):
            i = str(i+1)
            prevargs.append(self._env[i])
            del self._env[i]
        self._env['#'] = '0'
                
        #Set new ones
        for i,arg in enumerate(args):
            self._env[str(i+1)] = str(arg)
        self._env['#'] = str(len(args))
        
        return prevargs
        
    def get_positional_args(self):
        return [self._env[str(i+1)] for i in xrange(int(self._env['#']))]
        
    def get_variables(self):
        return dict(self._env)
        
    def export(self, key, value=None):
        if value is not None:
            self[key] = value
        self._exported.add(key)
        
    def get_exported(self):
        return [(k,self._env.get(k)) for k in self._exported]
            
    def split_fields(self, word):
        if not self._ifs_ws or not word:
            return [word]
        return re.split(self._ifs_re, word)
   
    def _update_ifs(self, value):
        """Update the split_fields related variables when IFS character set is
        changed.
        """
        # TODO: handle NULL IFS
        
        # Separate characters in whitespace and non-whitespace
        chars = set(value)
        ws = [c for c in chars if c in _IFS_WHITESPACES]
        nws = [c for c in chars if c not in _IFS_WHITESPACES]
        
        # Keep whitespaces in a string for left and right stripping
        self._ifs_ws = ''.join(ws)
        
        # Build a regexp to split fields
        trailing = '[' + ''.join([re.escape(c) for c in ws]) + ']'
        if nws:
            # First, the single non-whitespace occurence.
            nws = '[' + ''.join([re.escape(c) for c in nws]) + ']'
            nws = '(?:' + trailing + '*' + nws + trailing + '*' + '|' + trailing + '+)'
        else:
            # Then mix all parts with quantifiers
            nws = trailing + '+'
        self._ifs_re = re.compile(nws)
       
    def has_opt(self, opt, val=None):
        return (opt, val) in self._opt
        
    def set_opt(self, opt, val=None):
        self._opt.add((opt, val))
        
    def find_in_path(self, name, pwd=False):
        path = self._env.get('PATH', '').split(os.pathsep)
        if pwd:
            path[:0] = [self['PWD']]
        if os.name == 'nt':
            return win32_find_in_path(name, self._env.get('PATH', ''))
        else:
            raise NotImplementedError()
            
    def define_function(self, name, body):
        if not is_name(name):
            raise ShellSyntaxError('%s is not a valid function name' % repr(name))
        self._functions[name] = body
        
    def remove_function(self, name):
        del self._functions[name]
        
    def is_function(self, name):
        return name in self._functions
        
    def get_function(self, name):
        return self._functions.get(name)
        
       
name_charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
name_charset = dict(zip(name_charset,name_charset))
           
def match_name(s):
    """Return the length in characters of the longest prefix made of name
    allowed characters in s.
    """
    for i,c in enumerate(s):
        if c not in name_charset:
            return s[:i]
    return s
    
def is_name(s):
    return len([c for c in s if c not in name_charset])<=0
    
def is_special_param(c):
    return len(c)==1 and c in ('@','*','#','?','-','$','!','0')
    
def utility_not_implemented(name, *args, **kwargs):
    raise NotImplementedError('%s utility is not implemented' % name)
    

class Utility:
    """Define utilities properties:
    func -- utility callable. See builtin module for utility samples.
    is_special -- see XCU 2.8.
    """
    def __init__(self, func, is_special=0):
        self.func = func
        self.is_special = bool(is_special)


def encodeargs(args):
    def encodearg(s):
        lines = base64.encodestring(s)
        lines = [l.splitlines()[0] for l in lines]
        return ''.join(lines)

    s = pickle.dumps(args)
    return encodearg(s)

def decodeargs(s):
    s = base64.decodestring(s)
    return pickle.loads(s)
    

class GlobError(Exception):
    pass

class Options:
    def __init__(self):
        # True if Mercurial operates with binary streams
        self.hgbinary = True

class Interpreter:
    # Implementation is very basic: the execute() method just makes a DFS on the
    # AST and execute nodes one by one. Nodes are tuple (name,obj) where name
    # is a string identifier and obj the AST element returned by the parser.
    #
    # Handler are named after the node identifiers.
    # TODO: check node names and remove the switch in execute with some
    # dynamic getattr() call to find node handlers.
    """Shell interpreter.
    
    The following debugging flags can be passed:
    debug-parsing - enable PLY debugging.
    debug-tree - print the generated AST.
    debug-cmd - trace command execution before word expansion, plus exit status.
    debug-utility - trace utility execution.
    """
    
    # List supported commands.
    COMMANDS = {
        'cat':       Utility(builtin.utility_cat,),
        'cd':       Utility(builtin.utility_cd,),
        ':':        Utility(builtin.utility_colon,),
        'echo':     Utility(builtin.utility_echo),
        'env':      Utility(builtin.utility_env),
        'exit':     Utility(builtin.utility_exit),
        'export':   Utility(builtin.builtin_export,     is_special=1),
        'egrep':    Utility(builtin.utility_egrep),
        'fgrep':    Utility(builtin.utility_fgrep),
        'gunzip':   Utility(builtin.utility_gunzip),
        'kill':     Utility(builtin.utility_kill),
        'mkdir':    Utility(builtin.utility_mkdir),
        'netstat':  Utility(builtin.utility_netstat),
        'printf':   Utility(builtin.utility_printf),
        'pwd':      Utility(builtin.utility_pwd),
        'return':   Utility(builtin.builtin_return,     is_special=1),
        'sed':      Utility(builtin.utility_sed,),
        'set':      Utility(builtin.builtin_set,),
        'shift':    Utility(builtin.builtin_shift,),
        'sleep':    Utility(builtin.utility_sleep,),
        'sort':     Utility(builtin.utility_sort,),
        'trap':     Utility(builtin.builtin_trap,       is_special=1),
        'true':     Utility(builtin.utility_true),
        'unset':    Utility(builtin.builtin_unset,      is_special=1),
        'wait':     Utility(builtin.builtin_wait,       is_special=1),
    }
    
    def __init__(self, pwd, debugflags = [], env=None, redirs=None, stdin=None,
                 stdout=None, stderr=None, opts=Options()):
        self._env = env
        if self._env is None:
            self._env = Environment(pwd)
        self._children = {}
            
        self._redirs = redirs
        self._close_redirs = False
        
        if self._redirs is None:
            if stdin is None:
                stdin = sys.stdin
            if stdout is None:
                stdout = sys.stdout
            if stderr is None:
                stderr = sys.stderr
            stdin = FileWrapper('r', stdin, False)
            stdout = FileWrapper('w', stdout, False)
            stderr = FileWrapper('w', stderr, False)
            self._redirs = Redirections(stdin, stdout, stderr)
            self._close_redirs = True
            
        self._debugflags = list(debugflags)
        self._logfile = sys.stderr
        self._options = opts
        
    def close(self):
        """Must be called when the interpreter is no longer used."""
        script = self._env.traps.get('EXIT')
        if script:
            try:
                self.execute_script(script=script)
            except:
                pass

        if self._redirs is not None and self._close_redirs:
            self._redirs.close()
            self._redirs = None
            
    def log(self, s):
        self._logfile.write(s)
        self._logfile.flush()
            
    def __getitem__(self, key):
        return self._env[key]
        
    def __setitem__(self, key, value):
        self._env[key] = value

    def options(self):
        return self._options

    def redirect(self, redirs, ios):
        def add_redir(io):
            if isinstance(io, pyshyacc.IORedirect):
                redirs.add(self, io.op, io.filename, io.io_number)
            else:
                redirs.add_here_document(self, io.name, io.content, io.io_number)
                    
        map(add_redir, ios)
        return redirs
            
    def execute_script(self, script=None, ast=None, sourced=False,
                       scriptpath=None):
        """If script is not None, parse the input. Otherwise takes the supplied
        AST. Then execute the AST.
        Return the script exit status.
        """
        try:
            if scriptpath is not None:
                self._env['0'] = os.path.abspath(scriptpath)

            if script is not None:
                debug_parsing = ('debug-parsing' in self._debugflags)    
                cmds, script = pyshyacc.parse(script, True, debug_parsing)
                if 'debug-tree' in self._debugflags:
                    pyshyacc.print_commands(cmds, self._logfile)
                    self._logfile.flush()
            else:
                cmds, script = ast, ''                
                
            status = 0
            for cmd in cmds:
                try:
                    status = self.execute(cmd)
                except ExitSignal as e:
                    if sourced:
                        raise
                    status = int(e.args[0])
                    return status
                except ShellError:
                    self._env['?'] = 1
                    raise
                if 'debug-utility' in self._debugflags or 'debug-cmd' in self._debugflags:
                    self.log('returncode ' + str(status)+ '\n')
            return status
        except CommandNotFound as e:
            print >>self._redirs.stderr, str(e)
            self._redirs.stderr.flush()
            # Command not found by non-interactive shell
            # return 127
            raise
        except RedirectionError as e:
            # TODO: should be handled depending on the utility status
            print >>self._redirs.stderr, str(e)
            self._redirs.stderr.flush()
            # Command not found by non-interactive shell
            # return 127
            raise

    def dotcommand(self, env, args):
        if len(args) < 1:
            raise ShellError('. expects at least one argument')
        path = args[0]
        if '/' not in path:
            found = env.find_in_path(args[0], True)
            if found:
                path = found[0]
        script = file(path).read()
        return self.execute_script(script=script, sourced=True)

    def execute(self, token, redirs=None):
        """Execute and AST subtree with supplied redirections overriding default
        interpreter ones.
        Return the exit status.
        """
        if not token:
            return 0
            
        if redirs is None:
            redirs = self._redirs
            
        if isinstance(token, list):
            # Commands sequence
            res = 0
            for t in token:
                res = self.execute(t, redirs)
            return res

        type, value = token
        status = 0
        if type=='simple_command':
            redirs_copy = redirs.clone()
            try:
                # TODO: define and handle command return values
                # TODO: implement set -e
                status = self._execute_simple_command(value, redirs_copy)
            finally:
                redirs_copy.close()
        elif type=='pipeline':
            status = self._execute_pipeline(value, redirs)
        elif type=='and_or':
            status = self._execute_and_or(value, redirs)
        elif type=='for_clause':
            status = self._execute_for_clause(value, redirs)
        elif type=='while_clause':
            status = self._execute_while_clause(value, redirs)
        elif type=='function_definition':
            status = self._execute_function_definition(value, redirs)
        elif type=='brace_group':
            status = self._execute_brace_group(value, redirs)
        elif type=='if_clause':
            status = self._execute_if_clause(value, redirs)
        elif type=='subshell':
            status = self.subshell(ast=value.cmds, redirs=redirs)
        elif type=='async':
            status = self._asynclist(value)
        elif type=='redirect_list':
            redirs_copy = self.redirect(redirs.clone(), value.redirs)
            try:
                status = self.execute(value.cmd, redirs_copy)
            finally:
                redirs_copy.close()
        else:
            raise NotImplementedError('Unsupported token type ' + type)

        if status < 0:
            status = 255
        return status
            
    def _execute_if_clause(self, if_clause, redirs):
        cond_status = self.execute(if_clause.cond, redirs)
        if cond_status==0:
            return self.execute(if_clause.if_cmds, redirs)
        else:
            return self.execute(if_clause.else_cmds, redirs)
      
    def _execute_brace_group(self, group, redirs):
        status = 0
        for cmd in group.cmds:
            status = self.execute(cmd, redirs)
        return status
            
    def _execute_function_definition(self, fundef, redirs):
        self._env.define_function(fundef.name, fundef.body)
        return 0
            
    def _execute_while_clause(self, while_clause, redirs):
        status = 0
        while 1:
            cond_status = 0
            for cond in while_clause.condition:
                cond_status = self.execute(cond, redirs)
                
            if cond_status:
                break
                
            for cmd in while_clause.cmds:
                status = self.execute(cmd, redirs)
                
        return status
            
    def _execute_for_clause(self, for_clause, redirs):
        if not is_name(for_clause.name):
            raise ShellSyntaxError('%s is not a valid name' % repr(for_clause.name))
        items = mappend(self.expand_token, for_clause.items)
        
        status = 0    
        for item in items:
            self._env[for_clause.name] = item
            for cmd in for_clause.cmds:
                status = self.execute(cmd, redirs)
        return status
            
    def _execute_and_or(self, or_and, redirs):
        res = self.execute(or_and.left, redirs)        
        if (or_and.op=='&&' and res==0) or (or_and.op!='&&' and res!=0):
            res = self.execute(or_and.right, redirs)
        return res
            
    def _execute_pipeline(self, pipeline, redirs):            
        if len(pipeline.commands)==1:
            status = self.execute(pipeline.commands[0], redirs)
        else:
            # Execute all commands one after the other
            status = 0
            inpath, outpath = None, None
            try:
                # Commands inputs and outputs cannot really be plugged as done
                # by a real shell. Run commands sequentially and chain their
                # input/output throught temporary files.
                tmpfd, inpath = tempfile.mkstemp()
                os.close(tmpfd)
                tmpfd, outpath = tempfile.mkstemp()
                os.close(tmpfd)
                
                inpath = win32_to_unix_path(inpath)
                outpath = win32_to_unix_path(outpath)
                
                for i, cmd in enumerate(pipeline.commands):
                    call_redirs = redirs.clone()
                    try:
                        if i!=0:
                            call_redirs.add(self, '<', inpath)
                        if i!=len(pipeline.commands)-1:
                            call_redirs.add(self, '>', outpath)
                        
                        status = self.execute(cmd, call_redirs)
                        
                        # Chain inputs/outputs
                        inpath, outpath = outpath, inpath
                    finally:
                        call_redirs.close()            
            finally:
                if inpath: os.remove(inpath)
                if outpath: os.remove(outpath)
        
        if pipeline.reverse_status:
            status = int(not status)
        self._env['?'] = status
        return status
        
    def _execute_function(self, name, args, interp, env, stdin, stdout, stderr, *others):
        assert interp is self
        
        func = env.get_function(name)
        #Set positional parameters
        prevargs = None
        try:
            prevargs = env.set_positional_args(args)
            try:
                redirs = Redirections(stdin.dup(), stdout.dup(), stderr.dup())
                try:
                    status = self.execute(func, redirs)
                finally:
                    redirs.close()
            except ReturnSignal as e:
                status = int(e.args[0])
                env['?'] = status
            return status
        finally:
            #Reset positional parameters
            if prevargs is not None:
                env.set_positional_args(prevargs)
                
    def _execute_simple_command(self, token, redirs):
        """Can raise ReturnSignal when return builtin is called, ExitSignal when
        exit is called, and other shell exceptions upon builtin failures.
        """
        debug_command = 'debug-cmd' in self._debugflags
        if debug_command:
            self.log('word' + repr(token.words) + '\n')
            self.log('assigns' + repr(token.assigns) + '\n')
            self.log('redirs' + repr(token.redirs) + '\n')
        
        is_special = None
        env = self._env
        
        try:
            # Word expansion
            args = []
            for word in token.words:                
                args += self.expand_token(word)
                if is_special is None and args:
                    is_special = env.is_function(args[0]) or \
                        (args[0] in self.COMMANDS and self.COMMANDS[args[0]].is_special)
                        
            if debug_command:
                self.log('_execute_simple_command' + str(args) + '\n')
                
            if not args:
                # Redirections happen is a subshell
                redirs = redirs.clone()
            elif not is_special:
                env = self._env.clone()
            
            # Redirections
            self.redirect(redirs, token.redirs)
                
            # Variables assignments
            res = 0
            for type,(k,v) in token.assigns:
                status, expanded = self.expand_variable((k,v))
                if status is not None:
                    res = status
                if args:
                    env.export(k, expanded)
                else:
                    env[k] = expanded
                
            if args and args[0] in ('.', 'source'):
                res = self.dotcommand(env, args[1:])
            elif args:
                if args[0] in self.COMMANDS:
                    command = self.COMMANDS[args[0]]
                elif env.is_function(args[0]):
                    command = Utility(self._execute_function, is_special=True)
                else:
                    if not '/' in args[0].replace('\\', '/'):
                        cmd = env.find_in_path(args[0])
                        if not cmd:
                            # TODO: test error code on unknown command => 127
                            raise CommandNotFound('Unknown command: "%s"' % args[0])
                    else:
                        # Handle commands like '/cygdrive/c/foo.bat'
                        cmd = cygwin_to_windows_path(args[0])
                        if not os.path.exists(cmd):
                            raise CommandNotFound('%s: No such file or directory' % args[0])
                        shebang = resolve_shebang(cmd)
                        if shebang:
                            cmd = shebang
                        else:
                            cmd = [cmd]
                    args[0:1] = cmd
                    command = Utility(builtin.run_command)
                
                # Command execution
                if 'debug-cmd' in self._debugflags:
                    self.log('redirections ' + str(redirs) + '\n')
                    
                res = command.func(args[0], args[1:], self, env,
                                   redirs.stdin(), redirs.stdout(), 
                                   redirs.stderr(), self._debugflags)
            
            if self._env.has_opt('-x'):
                # Trace command execution in shell environment
                # BUG: would be hard to reproduce a real shell behaviour since
                # the AST is not annotated with source lines/tokens.
                self._redirs.stdout().write(' '.join(args))
                
        except ReturnSignal:
            raise
        except ShellError as e:
            if is_special or isinstance(e, (ExitSignal,
                                            ShellSyntaxError, ExpansionError)):
                raise e
            self._redirs.stderr().write(str(e)+'\n')
            return 1

        return res

    def expand_token(self, word):
        """Expand a word as specified in [2.6 Word Expansions]. Return the list
        of expanded words.
        """
        status, wtrees = self._expand_word(word)
        return map(pyshlex.wordtree_as_string, wtrees)
        
    def expand_variable(self, word):
        """Return a status code (or None if no command expansion occurred)
        and a single word.
        """
        status, wtrees = self._expand_word(word, pathname=False, split=False)
        words = map(pyshlex.wordtree_as_string, wtrees)
        assert len(words)==1
        return status, words[0]
        
    def expand_here_document(self, word):
        """Return the expanded document as a single word. The here document is 
        assumed to be unquoted.
        """
        status, wtrees = self._expand_word(word, pathname=False,
                                           split=False, here_document=True)
        words = map(pyshlex.wordtree_as_string, wtrees)
        assert len(words)==1
        return words[0]
        
    def expand_redirection(self, word):
        """Return a single word."""
        return self.expand_variable(word)[1]
        
    def get_env(self):
        return self._env
        
    def _expand_word(self, token, pathname=True, split=True, here_document=False):
        wtree = pyshlex.make_wordtree(token[1], here_document=here_document)
        
        # TODO: implement tilde expansion
        def expand(wtree):
            """Return a pseudo wordtree: the tree or its subelements can be empty
            lists when no value result from the expansion.
            """
            status = None
            for part in wtree:
                if not isinstance(part, list):
                    continue
                if part[0]in ("'", '\\'):
                    continue
                elif part[0] in ('`', '$('):
                    status, result = self._expand_command(part)
                    part[:] = result
                elif part[0] in ('$', '${'):
                    part[:] = self._expand_parameter(part, wtree[0]=='"', split)
                elif part[0] in ('', '"'):
                    status, result = expand(part)
                    part[:] = result
                else:
                    raise NotImplementedError('%s expansion is not implemented'
                                              % part[0])
            # [] is returned when an expansion result in no-field,
            # like an empty $@
            wtree = [p for p in wtree if p != []]
            if len(wtree) < 3:
                return status, []
            return status, wtree
        
        status, wtree = expand(wtree)
        if len(wtree) == 0:
            return status, wtree
        wtree = pyshlex.normalize_wordtree(wtree)
        
        if split:
            wtrees = self._split_fields(wtree)
        else:
            wtrees = [wtree]
        
        if pathname:
            wtrees = mappend(self._expand_pathname, wtrees)
        
        wtrees = map(self._remove_quotes, wtrees)
        return status, wtrees
        
    def _expand_command(self, wtree):
        # BUG: there is something to do with backslashes and quoted
        # characters here
        command = pyshlex.wordtree_as_string(wtree[1:-1])
        status, output = self.subshell_output(command)
        return status, ['', output, '']
        
    def _expand_parameter(self, wtree, quoted=False, split=False):
        """Return a valid wtree or an empty list when no parameter results."""
        # Get the parameter name
        # TODO: implement weird expansion rules with ':'
        name = pyshlex.wordtree_as_string(wtree[1:-1])
        if not is_name(name) and not is_special_param(name):
            raise ExpansionError('Bad substitution "%s"' % name)
        # TODO: implement special parameters
        if name in ('@', '*'):
            args = self._env.get_positional_args()
            if len(args) == 0:
                return []
            if len(args)<2:
                return ['', ''.join(args), '']
                
            sep = self._env.get('IFS', '')[:1]
            if split and quoted and name=='@':
                # Introduce a new token to tell the caller that these parameters
                # cause a split as specified in 2.5.2
                return ['@'] + args + ['']
            else:
                return ['', sep.join(args), '']                
        
        return ['', self._env.get(name, ''), '']
        
    def _split_fields(self, wtree):
        def is_empty(split):
            return split==['', '', '']
            
        def split_positional(quoted):
            # Return a list of wtree split according positional parameters rules.
            # All remaining '@' groups are removed.
            assert quoted[0]=='"'
            
            splits = [[]]
            for part in quoted:
                if not isinstance(part, list) or part[0]!='@':
                    splits[-1].append(part)
                else:
                    # Empty or single argument list were dealt with already
                    assert len(part)>3
                    # First argument must join with the beginning part of the original word
                    splits[-1].append(part[1])
                    # Create double-quotes expressions for every argument after the first
                    for arg in part[2:-1]:
                        splits[-1].append('"')
                        splits.append(['"', arg])
            return splits
        
        # At this point, all expansions but pathnames have occured. Only quoted
        # and positional sequences remain. Thus, all candidates for field splitting 
        # are in the tree root, or are positional splits ('@') and lie in root
        # children.
        if not wtree or wtree[0] not in ('', '"'):
            # The whole token is quoted or empty, nothing to split
            return [wtree]
            
        if wtree[0]=='"':
            wtree = ['', wtree, '']
        
        result = [['', '']]
        for part in wtree[1:-1]:
            if isinstance(part, list):
                if part[0]=='"':
                    splits = split_positional(part)
                    if len(splits)<=1:
                        result[-1] += [part, '']
                    else:
                        # Terminate the current split
                        result[-1] += [splits[0], '']
                        result += splits[1:-1]
                        # Create a new split
                        result += [['', splits[-1], '']]
                else:
                    result[-1] += [part, '']
            else:
                splits = self._env.split_fields(part)
                if len(splits)<=1:
                    # No split
                    result[-1][-1] += part
                else:
                    # Terminate the current resulting part and create a new one
                    result[-1][-1] += splits[0]
                    result[-1].append('')
                    result += [['', r, ''] for r in splits[1:-1]]
                    result += [['', splits[-1]]]
        result[-1].append('')
        
        # Leading and trailing empty groups come from leading/trailing blanks
        if result and is_empty(result[-1]):
            result[-1:] = []
        if result and is_empty(result[0]):
            result[:1] = []
        return result
        
    def _expand_pathname(self, wtree):
        """See [2.6.6 Pathname Expansion]."""
        if self._env.has_opt('-f'):
            return [wtree]
        
        # All expansions have been performed, only quoted sequences should remain
        # in the tree. Generate the pattern by folding the tree, escaping special
        # characters when appear quoted
        special_chars = '*?[]'
        
        def make_pattern(wtree):
            subpattern = []
            for part in wtree[1:-1]:
                if isinstance(part, list):
                    part = make_pattern(part)
                elif wtree[0]!='':
                    for c in part:
                        # Meta-characters cannot be quoted
                        if c in special_chars:
                            raise GlobError()
                subpattern.append(part)
            return ''.join(subpattern)
            
        def pwd_glob(pattern):
            cwd = os.getcwd()
            os.chdir(self._env['PWD'])
            try:
                return glob.glob(pattern) 
            finally:
                os.chdir(cwd)    
            
        #TODO: check working directory issues here wrt relative patterns
        try:
            pattern = make_pattern(wtree)
            paths = pwd_glob(pattern)
        except GlobError:
            # BUG: Meta-characters were found in quoted sequences. The should 
            # have been used literally but this is unsupported in current glob module.
            # Instead we consider the whole tree must be used literally and
            # therefore there is no point in globbing. This is wrong when meta
            # characters are mixed with quoted meta in the same pattern like:
            # < foo*"py*" >
            paths = []
            
        if not paths:
            return [wtree]
        return [['', path, ''] for path in paths]
        
    def _remove_quotes(self, wtree):
        """See [2.6.7 Quote Removal]."""
        
        def unquote(wtree):
            unquoted = []
            for part in wtree[1:-1]:
                if isinstance(part, list):
                    part = unquote(part)
                unquoted.append(part)
            return ''.join(unquoted)
            
        return ['', unquote(wtree), '']
        
    def subshell(self, script=None, ast=None, redirs=None):
        """Execute the script or AST in a subshell, with inherited redirections
        if redirs is not None.
        """
        if redirs:
            sub_redirs = redirs
        else:
            sub_redirs = redirs.clone()
        
        subshell = None    
        try:
            subshell = Interpreter(None, self._debugflags, self._env.clone(True),
                                   sub_redirs, opts=self._options)
            return subshell.execute_script(script, ast)
        finally:
            if not redirs: sub_redirs.close()
            if subshell: subshell.close()
        
    def subshell_output(self, script):
        """Execute the script in a subshell and return the captured output."""        
        # Create temporary file to capture subshell output
        tmpfd, tmppath = tempfile.mkstemp()
        try:
            tmpfile = os.fdopen(tmpfd, 'wb')
            stdout = FileWrapper('w', tmpfile)
            
            redirs = Redirections(self._redirs.stdin().dup(),
                                  stdout,
                                  self._redirs.stderr().dup())            
            try:
                status = self.subshell(script=script, redirs=redirs)
            finally:
                redirs.close()
                redirs = None
            
            # Extract subshell standard output
            tmpfile = open(tmppath, 'rb')
            try:
                output = tmpfile.read()
                return status, output.rstrip('\n')
            finally:
                tmpfile.close()
        finally:
            os.remove(tmppath)

    def _asynclist(self, cmd):
        args = (self._env.get_variables(), cmd)
        arg = encodeargs(args)
        assert len(args) < 30*1024
        cmd = ['pysh.bat', '--ast', '-c', arg]
        p = subprocess.Popen(cmd, cwd=self._env['PWD'])
        self._children[p.pid] = p
        self._env['!'] = p.pid
        return 0

    def wait(self, pids=None):
        if not pids:
            pids = self._children.keys()

        status = 127
        for pid in pids:
            if pid not in self._children:
                continue
            p = self._children.pop(pid)
            status = p.wait()

        return status

