forked from OSchip/llvm-project
134 lines
4.1 KiB
Python
134 lines
4.1 KiB
Python
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')
|
|
|
|
g_builtin_override_called = False
|
|
|
|
|
|
class LLDBQuitter(object):
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __repr__(self):
|
|
self()
|
|
|
|
def __call__(self, code=None):
|
|
global g_builtin_override_called
|
|
g_builtin_override_called = True
|
|
raise SystemExit(-1)
|
|
|
|
|
|
def setquit():
|
|
'''Redefine builtin functions 'quit()' and 'exit()' to print a message and raise an EOFError exception.'''
|
|
# This function will be called prior to each interactive
|
|
# interpreter loop or each single line, so we set the global
|
|
# g_builtin_override_called to False so we know if a SystemExit
|
|
# is thrown, we can catch it and tell the difference between
|
|
# a call to "quit()" or "exit()" and something like
|
|
# "sys.exit(123)"
|
|
global g_builtin_override_called
|
|
g_builtin_override_called = False
|
|
builtins.quit = LLDBQuitter('quit')
|
|
builtins.exit = LLDBQuitter('exit')
|
|
|
|
# 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
|
|
|
|
|
|
def readfunc_stdio(prompt):
|
|
sys.stdout.write(prompt)
|
|
return sys.stdin.readline().rstrip()
|
|
|
|
|
|
def run_python_interpreter(local_dict):
|
|
# Pass in the dictionary, for continuity from one session to the next.
|
|
setquit()
|
|
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.",
|
|
local=local_dict)
|
|
except SystemExit as e:
|
|
global g_builtin_override_called
|
|
if not g_builtin_override_called:
|
|
print('Script exited with %s' % (e))
|
|
|
|
|
|
def run_one_line(local_dict, input_string):
|
|
global g_run_one_line_str
|
|
setquit()
|
|
try:
|
|
repl = code.InteractiveConsole(local_dict)
|
|
if input_string:
|
|
repl.runsource(input_string)
|
|
elif g_run_one_line_str:
|
|
repl.runsource(g_run_one_line_str)
|
|
|
|
except SystemExit as e:
|
|
global g_builtin_override_called
|
|
if not g_builtin_override_called:
|
|
print('Script exited with %s' % (e))
|