Index: third_party/pexpect/pexpect/utils.py |
diff --git a/third_party/pexpect/pexpect/utils.py b/third_party/pexpect/pexpect/utils.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..737f0eda05afb70140021999e48cc48e8a2d89f2 |
--- /dev/null |
+++ b/third_party/pexpect/pexpect/utils.py |
@@ -0,0 +1,112 @@ |
+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 |