diff options
Diffstat (limited to 'contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py')
-rw-r--r-- | contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py b/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py new file mode 100644 index 000000000000..a487592ef1ae --- /dev/null +++ b/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py @@ -0,0 +1,136 @@ +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) |