1*f6aab3d8Srobertimport sys 2061da546Spatrickif sys.version_info[0] < 3: 3061da546Spatrick import __builtin__ as builtins 4061da546Spatrickelse: 5061da546Spatrick import builtins 6061da546Spatrickimport code 7061da546Spatrickimport lldb 8061da546Spatrickimport traceback 9061da546Spatrick 10061da546Spatricktry: 11061da546Spatrick import readline 12061da546Spatrick import rlcompleter 13061da546Spatrickexcept ImportError: 14061da546Spatrick have_readline = False 15061da546Spatrickexcept AttributeError: 16061da546Spatrick # This exception gets hit by the rlcompleter when Linux is using 17061da546Spatrick # the readline suppression import. 18061da546Spatrick have_readline = False 19061da546Spatrickelse: 20061da546Spatrick have_readline = True 21061da546Spatrick if 'libedit' in readline.__doc__: 22061da546Spatrick readline.parse_and_bind('bind ^I rl_complete') 23061da546Spatrick else: 24061da546Spatrick readline.parse_and_bind('tab: complete') 25061da546Spatrick 26061da546Spatrick# When running one line, we might place the string to run in this string 27061da546Spatrick# in case it would be hard to correctly escape a string's contents 28061da546Spatrick 29061da546Spatrickg_run_one_line_str = None 30061da546Spatrick 31061da546Spatrick 32061da546Spatrickdef get_terminal_size(fd): 33061da546Spatrick try: 34061da546Spatrick import fcntl 35061da546Spatrick import termios 36061da546Spatrick import struct 37061da546Spatrick hw = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) 38061da546Spatrick except: 39061da546Spatrick hw = (0, 0) 40061da546Spatrick return hw 41061da546Spatrick 42061da546Spatrick 43*f6aab3d8Srobertclass LLDBExit(SystemExit): 44*f6aab3d8Srobert pass 45*f6aab3d8Srobert 46*f6aab3d8Srobert 47*f6aab3d8Srobertdef strip_and_check_exit(line): 48*f6aab3d8Srobert line = line.rstrip() 49*f6aab3d8Srobert if line in ('exit', 'quit'): 50*f6aab3d8Srobert raise LLDBExit 51*f6aab3d8Srobert return line 52*f6aab3d8Srobert 53*f6aab3d8Srobert 54*f6aab3d8Srobertdef readfunc(prompt): 55*f6aab3d8Srobert line = input(prompt) 56*f6aab3d8Srobert return strip_and_check_exit(line) 57*f6aab3d8Srobert 58*f6aab3d8Srobert 59061da546Spatrickdef readfunc_stdio(prompt): 60061da546Spatrick sys.stdout.write(prompt) 61061da546Spatrick sys.stdout.flush() 62dda28197Spatrick line = sys.stdin.readline() 63dda28197Spatrick # Readline always includes a trailing newline character unless the file 64dda28197Spatrick # ends with an incomplete line. An empty line indicates EOF. 65dda28197Spatrick if not line: 66dda28197Spatrick raise EOFError 67*f6aab3d8Srobert return strip_and_check_exit(line) 68061da546Spatrick 69061da546Spatrick 70061da546Spatrickdef run_python_interpreter(local_dict): 71061da546Spatrick # Pass in the dictionary, for continuity from one session to the next. 72061da546Spatrick try: 73061da546Spatrick fd = sys.stdin.fileno() 74061da546Spatrick interacted = False 75061da546Spatrick if get_terminal_size(fd)[1] == 0: 76061da546Spatrick try: 77061da546Spatrick import termios 78061da546Spatrick old = termios.tcgetattr(fd) 79061da546Spatrick if old[3] & termios.ECHO: 80061da546Spatrick # Need to turn off echoing and restore 81061da546Spatrick new = termios.tcgetattr(fd) 82061da546Spatrick new[3] = new[3] & ~termios.ECHO 83061da546Spatrick try: 84061da546Spatrick termios.tcsetattr(fd, termios.TCSADRAIN, new) 85061da546Spatrick interacted = True 86061da546Spatrick code.interact( 87061da546Spatrick banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", 88061da546Spatrick readfunc=readfunc_stdio, 89061da546Spatrick local=local_dict) 90061da546Spatrick finally: 91061da546Spatrick termios.tcsetattr(fd, termios.TCSADRAIN, old) 92061da546Spatrick except: 93061da546Spatrick pass 94061da546Spatrick # Don't need to turn off echoing 95061da546Spatrick if not interacted: 96061da546Spatrick code.interact( 97061da546Spatrick banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", 98061da546Spatrick readfunc=readfunc_stdio, 99061da546Spatrick local=local_dict) 100061da546Spatrick else: 101061da546Spatrick # We have a real interactive terminal 102061da546Spatrick code.interact( 103061da546Spatrick banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", 104*f6aab3d8Srobert readfunc=readfunc, 105061da546Spatrick local=local_dict) 106*f6aab3d8Srobert except LLDBExit: 107*f6aab3d8Srobert pass 108061da546Spatrick except SystemExit as e: 109*f6aab3d8Srobert if e.code: 110*f6aab3d8Srobert print('Script exited with code %s' % e.code) 111061da546Spatrick 112061da546Spatrick 113061da546Spatrickdef run_one_line(local_dict, input_string): 114061da546Spatrick global g_run_one_line_str 115061da546Spatrick try: 116*f6aab3d8Srobert input_string = strip_and_check_exit(input_string) 117061da546Spatrick repl = code.InteractiveConsole(local_dict) 118061da546Spatrick if input_string: 119*f6aab3d8Srobert # A newline is appended to support one-line statements containing 120*f6aab3d8Srobert # control flow. For example "if True: print(1)" silently does 121*f6aab3d8Srobert # nothing, but works with a newline: "if True: print(1)\n". 122*f6aab3d8Srobert input_string += "\n" 123061da546Spatrick repl.runsource(input_string) 124061da546Spatrick elif g_run_one_line_str: 125061da546Spatrick repl.runsource(g_run_one_line_str) 126*f6aab3d8Srobert except LLDBExit: 127*f6aab3d8Srobert pass 128061da546Spatrick except SystemExit as e: 129*f6aab3d8Srobert if e.code: 130*f6aab3d8Srobert print('Script exited with code %s' % e.code) 131