181ad6265SDimitry Andricimport sys 2*5f757f3fSDimitry Andric 30b57cec5SDimitry Andricif sys.version_info[0] < 3: 40b57cec5SDimitry Andric import __builtin__ as builtins 50b57cec5SDimitry Andricelse: 60b57cec5SDimitry Andric import builtins 70b57cec5SDimitry Andricimport code 80b57cec5SDimitry Andricimport lldb 90b57cec5SDimitry Andricimport traceback 100b57cec5SDimitry Andric 110b57cec5SDimitry Andrictry: 120b57cec5SDimitry Andric import readline 130b57cec5SDimitry Andric import rlcompleter 140b57cec5SDimitry Andricexcept ImportError: 150b57cec5SDimitry Andric have_readline = False 160b57cec5SDimitry Andricexcept AttributeError: 170b57cec5SDimitry Andric # This exception gets hit by the rlcompleter when Linux is using 180b57cec5SDimitry Andric # the readline suppression import. 190b57cec5SDimitry Andric have_readline = False 200b57cec5SDimitry Andricelse: 210b57cec5SDimitry Andric have_readline = True 22*5f757f3fSDimitry Andric if "libedit" in readline.__doc__: 23*5f757f3fSDimitry Andric readline.parse_and_bind("bind ^I rl_complete") 240b57cec5SDimitry Andric else: 25*5f757f3fSDimitry Andric readline.parse_and_bind("tab: complete") 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric# When running one line, we might place the string to run in this string 280b57cec5SDimitry Andric# in case it would be hard to correctly escape a string's contents 290b57cec5SDimitry Andric 300b57cec5SDimitry Andricg_run_one_line_str = None 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric 330b57cec5SDimitry Andricdef get_terminal_size(fd): 340b57cec5SDimitry Andric try: 350b57cec5SDimitry Andric import fcntl 360b57cec5SDimitry Andric import termios 370b57cec5SDimitry Andric import struct 38*5f757f3fSDimitry Andric 39*5f757f3fSDimitry Andric hw = struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234")) 400b57cec5SDimitry Andric except: 410b57cec5SDimitry Andric hw = (0, 0) 420b57cec5SDimitry Andric return hw 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric 4581ad6265SDimitry Andricclass LLDBExit(SystemExit): 4681ad6265SDimitry Andric pass 4781ad6265SDimitry Andric 4881ad6265SDimitry Andric 4981ad6265SDimitry Andricdef strip_and_check_exit(line): 5081ad6265SDimitry Andric line = line.rstrip() 51*5f757f3fSDimitry Andric if line in ("exit", "quit"): 5281ad6265SDimitry Andric raise LLDBExit 5381ad6265SDimitry Andric return line 5481ad6265SDimitry Andric 5581ad6265SDimitry Andric 5681ad6265SDimitry Andricdef readfunc(prompt): 5781ad6265SDimitry Andric line = input(prompt) 5881ad6265SDimitry Andric return strip_and_check_exit(line) 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric 610b57cec5SDimitry Andricdef readfunc_stdio(prompt): 620b57cec5SDimitry Andric sys.stdout.write(prompt) 630b57cec5SDimitry Andric sys.stdout.flush() 645ffd83dbSDimitry Andric line = sys.stdin.readline() 655ffd83dbSDimitry Andric # Readline always includes a trailing newline character unless the file 665ffd83dbSDimitry Andric # ends with an incomplete line. An empty line indicates EOF. 675ffd83dbSDimitry Andric if not line: 685ffd83dbSDimitry Andric raise EOFError 6981ad6265SDimitry Andric return strip_and_check_exit(line) 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric 720b57cec5SDimitry Andricdef run_python_interpreter(local_dict): 730b57cec5SDimitry Andric # Pass in the dictionary, for continuity from one session to the next. 740b57cec5SDimitry Andric try: 750b57cec5SDimitry Andric fd = sys.stdin.fileno() 760b57cec5SDimitry Andric interacted = False 770b57cec5SDimitry Andric if get_terminal_size(fd)[1] == 0: 780b57cec5SDimitry Andric try: 790b57cec5SDimitry Andric import termios 80*5f757f3fSDimitry Andric 810b57cec5SDimitry Andric old = termios.tcgetattr(fd) 820b57cec5SDimitry Andric if old[3] & termios.ECHO: 830b57cec5SDimitry Andric # Need to turn off echoing and restore 840b57cec5SDimitry Andric new = termios.tcgetattr(fd) 850b57cec5SDimitry Andric new[3] = new[3] & ~termios.ECHO 860b57cec5SDimitry Andric try: 870b57cec5SDimitry Andric termios.tcsetattr(fd, termios.TCSADRAIN, new) 880b57cec5SDimitry Andric interacted = True 890b57cec5SDimitry Andric code.interact( 900b57cec5SDimitry Andric banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", 910b57cec5SDimitry Andric readfunc=readfunc_stdio, 92*5f757f3fSDimitry Andric local=local_dict, 93*5f757f3fSDimitry Andric ) 940b57cec5SDimitry Andric finally: 950b57cec5SDimitry Andric termios.tcsetattr(fd, termios.TCSADRAIN, old) 960b57cec5SDimitry Andric except: 970b57cec5SDimitry Andric pass 980b57cec5SDimitry Andric # Don't need to turn off echoing 990b57cec5SDimitry Andric if not interacted: 1000b57cec5SDimitry Andric code.interact( 1010b57cec5SDimitry Andric banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", 1020b57cec5SDimitry Andric readfunc=readfunc_stdio, 103*5f757f3fSDimitry Andric local=local_dict, 104*5f757f3fSDimitry Andric ) 1050b57cec5SDimitry Andric else: 1060b57cec5SDimitry Andric # We have a real interactive terminal 1070b57cec5SDimitry Andric code.interact( 1080b57cec5SDimitry Andric banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", 10981ad6265SDimitry Andric readfunc=readfunc, 110*5f757f3fSDimitry Andric local=local_dict, 111*5f757f3fSDimitry Andric ) 11281ad6265SDimitry Andric except LLDBExit: 11381ad6265SDimitry Andric pass 1140b57cec5SDimitry Andric except SystemExit as e: 11581ad6265SDimitry Andric if e.code: 116*5f757f3fSDimitry Andric print("Script exited with code %s" % e.code) 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andricdef run_one_line(local_dict, input_string): 1200b57cec5SDimitry Andric global g_run_one_line_str 1210b57cec5SDimitry Andric try: 12281ad6265SDimitry Andric input_string = strip_and_check_exit(input_string) 1230b57cec5SDimitry Andric repl = code.InteractiveConsole(local_dict) 1240b57cec5SDimitry Andric if input_string: 12581ad6265SDimitry Andric # A newline is appended to support one-line statements containing 12681ad6265SDimitry Andric # control flow. For example "if True: print(1)" silently does 12781ad6265SDimitry Andric # nothing, but works with a newline: "if True: print(1)\n". 12881ad6265SDimitry Andric input_string += "\n" 1290b57cec5SDimitry Andric repl.runsource(input_string) 1300b57cec5SDimitry Andric elif g_run_one_line_str: 1310b57cec5SDimitry Andric repl.runsource(g_run_one_line_str) 13281ad6265SDimitry Andric except LLDBExit: 13381ad6265SDimitry Andric pass 1340b57cec5SDimitry Andric except SystemExit as e: 13581ad6265SDimitry Andric if e.code: 136*5f757f3fSDimitry Andric print("Script exited with code %s" % e.code) 137