aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py')
-rw-r--r--contrib/llvm-project/lldb/source/Interpreter/embedded_interpreter.py136
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)