133 lines · python
1import sys2import builtins3import code4import lldb5import traceback6 7try:8 import readline9 import rlcompleter10except ImportError:11 have_readline = False12except AttributeError:13 # This exception gets hit by the rlcompleter when Linux is using14 # the readline suppression import.15 have_readline = False16else:17 have_readline = True18 if "libedit" in readline.__doc__:19 readline.parse_and_bind("bind ^I rl_complete")20 else:21 readline.parse_and_bind("tab: complete")22 23# When running one line, we might place the string to run in this string24# in case it would be hard to correctly escape a string's contents25 26g_run_one_line_str = None27 28 29def get_terminal_size(fd):30 try:31 import fcntl32 import termios33 import struct34 35 hw = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))36 except:37 hw = (0, 0)38 return hw39 40 41class LLDBExit(SystemExit):42 pass43 44 45def strip_and_check_exit(line):46 line = line.rstrip()47 if line in ("exit", "quit"):48 raise LLDBExit49 return line50 51 52def readfunc(prompt):53 line = input(prompt)54 return strip_and_check_exit(line)55 56 57def readfunc_stdio(prompt):58 sys.stdout.write(prompt)59 sys.stdout.flush()60 line = sys.stdin.readline()61 # Readline always includes a trailing newline character unless the file62 # ends with an incomplete line. An empty line indicates EOF.63 if not line:64 raise EOFError65 return strip_and_check_exit(line)66 67 68def run_python_interpreter(local_dict):69 # Pass in the dictionary, for continuity from one session to the next.70 try:71 fd = sys.stdin.fileno()72 interacted = False73 if get_terminal_size(fd)[1] == 0:74 try:75 import termios76 77 old = termios.tcgetattr(fd)78 if old[3] & termios.ECHO:79 # Need to turn off echoing and restore80 new = termios.tcgetattr(fd)81 new[3] = new[3] & ~termios.ECHO82 try:83 termios.tcsetattr(fd, termios.TCSADRAIN, new)84 interacted = True85 code.interact(86 banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.",87 readfunc=readfunc_stdio,88 local=local_dict,89 )90 finally:91 termios.tcsetattr(fd, termios.TCSADRAIN, old)92 except:93 pass94 # Don't need to turn off echoing95 if not interacted:96 code.interact(97 banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.",98 readfunc=readfunc_stdio,99 local=local_dict,100 )101 else:102 # We have a real interactive terminal103 code.interact(104 banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.",105 readfunc=readfunc,106 local=local_dict,107 )108 except LLDBExit:109 pass110 except SystemExit as e:111 if e.code:112 print("Script exited with code %s" % e.code)113 114 115def run_one_line(local_dict, input_string):116 global g_run_one_line_str117 try:118 input_string = strip_and_check_exit(input_string)119 repl = code.InteractiveConsole(local_dict)120 if input_string:121 # A newline is appended to support one-line statements containing122 # control flow. For example "if True: print(1)" silently does123 # nothing, but works with a newline: "if True: print(1)\n".124 input_string += "\n"125 repl.runsource(input_string)126 elif g_run_one_line_str:127 repl.runsource(g_run_one_line_str)128 except LLDBExit:129 pass130 except SystemExit as e:131 if e.code:132 print("Script exited with code %s" % e.code)133