| import sys |
| if sys.version_info[0] < 3: |
| import __builtin__ as builtins |
| else: |
| import builtins |
| import code |
| import lldb |
| import traceback |
| |
| try: |
| import readline |
| import rlcompleter |
| except ImportError: |
| have_readline = False |
| except AttributeError: |
| # This exception gets hit by the rlcompleter when Linux is using |
| # the readline suppression import. |
| have_readline = False |
| else: |
| have_readline = True |
| if 'libedit' in readline.__doc__: |
| readline.parse_and_bind('bind ^I rl_complete') |
| else: |
| readline.parse_and_bind('tab: complete') |
| |
| # When running one line, we might place the string to run in this string |
| # in case it would be hard to correctly escape a string's contents |
| |
| g_run_one_line_str = None |
| |
| |
| def get_terminal_size(fd): |
| try: |
| import fcntl |
| import termios |
| import struct |
| hw = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) |
| except: |
| hw = (0, 0) |
| return hw |
| |
| |
| class LLDBExit(SystemExit): |
| pass |
| |
| |
| def strip_and_check_exit(line): |
| line = line.rstrip() |
| if line in ('exit', 'quit'): |
| raise LLDBExit |
| return line |
| |
| |
| def readfunc(prompt): |
| line = input(prompt) |
| return strip_and_check_exit(line) |
| |
| |
| def readfunc_stdio(prompt): |
| sys.stdout.write(prompt) |
| sys.stdout.flush() |
| line = sys.stdin.readline() |
| # Readline always includes a trailing newline character unless the file |
| # ends with an incomplete line. An empty line indicates EOF. |
| if not line: |
| raise EOFError |
| return strip_and_check_exit(line) |
| |
| |
| def run_python_interpreter(local_dict): |
| # Pass in the dictionary, for continuity from one session to the next. |
| try: |
| fd = sys.stdin.fileno() |
| interacted = False |
| if get_terminal_size(fd)[1] == 0: |
| try: |
| import termios |
| old = termios.tcgetattr(fd) |
| if old[3] & termios.ECHO: |
| # Need to turn off echoing and restore |
| new = termios.tcgetattr(fd) |
| new[3] = new[3] & ~termios.ECHO |
| try: |
| termios.tcsetattr(fd, termios.TCSADRAIN, new) |
| interacted = True |
| code.interact( |
| banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", |
| readfunc=readfunc_stdio, |
| local=local_dict) |
| finally: |
| termios.tcsetattr(fd, termios.TCSADRAIN, old) |
| except: |
| pass |
| # Don't need to turn off echoing |
| if not interacted: |
| code.interact( |
| banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", |
| readfunc=readfunc_stdio, |
| local=local_dict) |
| else: |
| # We have a real interactive terminal |
| code.interact( |
| banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", |
| readfunc=readfunc, |
| local=local_dict) |
| except LLDBExit: |
| pass |
| except SystemExit as e: |
| if e.code: |
| print('Script exited with code %s' % e.code) |
| |
| |
| def run_one_line(local_dict, input_string): |
| global g_run_one_line_str |
| try: |
| input_string = strip_and_check_exit(input_string) |
| repl = code.InteractiveConsole(local_dict) |
| if input_string: |
| # A newline is appended to support one-line statements containing |
| # control flow. For example "if True: print(1)" silently does |
| # nothing, but works with a newline: "if True: print(1)\n". |
| input_string += "\n" |
| repl.runsource(input_string) |
| elif g_run_one_line_str: |
| repl.runsource(g_run_one_line_str) |
| except LLDBExit: |
| pass |
| except SystemExit as e: |
| if e.code: |
| print('Script exited with code %s' % e.code) |