pexpect.utils — Pexpect 4.1.0 documentation

# Source code for pexpect.utils

    import os
    import sys
    import stat

    def is_executable_file(path):
        """Checks that path is an executable regular file, or a symlink towards one.

        This is roughly ``os.path isfile(path) and os.access(path, os.X_OK)``.
        """
        # follow symlinks,
        fpath = os.path.realpath(path)

        if not os.path.isfile(fpath):
            # non-files (directories, fifo, etc.)
            return False

        mode = os.stat(fpath).st_mode

        if (sys.platform.startswith('sunos')
                and os.getuid() == 0):
            # When root on Solaris, os.X_OK is True for *all* files, irregardless
            # of their executability -- instead, any permission bit of any user,
            # group, or other is fine enough.
            #
            # (This may be true for other "Unix98" OS's such as HP-UX and AIX)
            return bool(mode & (stat.S_IXUSR |
                                stat.S_IXGRP |
                                stat.S_IXOTH))

        return os.access(fpath, os.X_OK)

    def which(filename):
        '''This takes a given filename; tries to find it in the environment path;
        then checks if it is executable. This returns the full path to the filename
        if found and executable. Otherwise this returns None.'''

        # Special case where filename contains an explicit path.
        if os.path.dirname(filename) != '' and is_executable_file(filename):
            return filename
        if 'PATH' not in os.environ or os.environ['PATH'] == '':
            p = os.defpath
        else:
            p = os.environ['PATH']
        pathlist = p.split(os.pathsep)
        for path in pathlist:
            ff = os.path.join(path, filename)
            if is_executable_file(ff):
                return ff
        return None

    def split_command_line(command_line):

        '''This splits a command line into a list of arguments. It splits arguments
        on spaces, but handles embedded quotes, doublequotes, and escaped
        characters. It's impossible to do this with a regular expression, so I
        wrote a little state machine to parse the command line. '''

        arg_list = []
        arg = ''

        # Constants to name the states we can be in.
        state_basic = 0
        state_esc = 1
        state_singlequote = 2
        state_doublequote = 3
        # The state when consuming whitespace between commands.
        state_whitespace = 4
        state = state_basic

        for c in command_line:
            if state == state_basic or state == state_whitespace:
                if c == '\\':
                    # Escape the next character
                    state = state_esc
                elif c == r"'":
                    # Handle single quote
                    state = state_singlequote
                elif c == r'"':
                    # Handle double quote
                    state = state_doublequote
                elif c.isspace():
                    # Add arg to arg_list if we aren't in the middle of whitespace.
                    if state == state_whitespace:
                        # Do nothing.
                        None
                    else:
                        arg_list.append(arg)
                        arg = ''
                        state = state_whitespace
                else:
                    arg = arg + c
                    state = state_basic
            elif state == state_esc:
                arg = arg + c
                state = state_basic
            elif state == state_singlequote:
                if c == r"'":
                    state = state_basic
                else:
                    arg = arg + c
            elif state == state_doublequote:
                if c == r'"':
                    state = state_basic
                else:
                    arg = arg + c

        if arg != '':
            arg_list.append(arg)
        return arg_list