xref: /llvm-project/lldb/source/Interpreter/embedded_interpreter.py (revision 9bb71b73d92331d1fb3d7561a44443252be813a7)
1import __builtin__
2import code
3import lldb
4import sys
5import traceback
6
7try:
8    import readline
9    import rlcompleter
10except ImportError:
11    have_readline = False
12except AttributeError:
13    # This exception gets hit by the rlcompleter when Linux is using
14    # the readline suppression import.
15    have_readline = False
16else:
17    have_readline = True
18    if 'libedit' in readline.__doc__:
19        readline.parse_and_bind('bind ^I rl_complete')
20    else:
21        readline.parse_and_bind('tab: complete')
22
23g_builtin_override_called = False
24
25class LLDBQuitter(object):
26    def __init__(self, name):
27        self.name = name
28    def __repr__(self):
29        self()
30    def __call__(self, code=None):
31        global g_builtin_override_called
32        g_builtin_override_called = True
33        raise SystemExit(-1)
34
35def setquit():
36    '''Redefine builtin functions 'quit()' and 'exit()' to print a message and raise an EOFError exception.'''
37    # This function will be called prior to each interactive
38    # interpreter loop or each single line, so we set the global
39    # g_builtin_override_called to False so we know if a SystemExit
40    # is thrown, we can catch it and tell the difference between
41    # a call to "quit()" or "exit()" and something like
42    # "sys.exit(123)"
43    global g_builtin_override_called
44    g_builtin_override_called = False
45    __builtin__.quit = LLDBQuitter('quit')
46    __builtin__.exit = LLDBQuitter('exit')
47
48# When running one line, we might place the string to run in this string
49# in case it would be hard to correctly escape a string's contents
50
51g_run_one_line_str = None
52
53
54def get_terminal_size(fd):
55    try:
56        import fcntl, termios, struct
57        hw = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
58    except:
59        hw = (0,0)
60    return hw
61
62def readfunc_stdio(prompt):
63    sys.stdout.write(prompt)
64    return sys.stdin.readline()
65
66def run_python_interpreter (local_dict):
67    # Pass in the dictionary, for continuity from one session to the next.
68    setquit()
69    try:
70        fd = sys.stdin.fileno();
71        interacted = False
72        if get_terminal_size(fd)[1] == 0:
73            try:
74                import termios
75                old = termios.tcgetattr(fd)
76                if old[3] & termios.ECHO:
77                    # Need to turn off echoing and restore
78                    new = termios.tcgetattr(fd)
79                    new[3] = new[3] & ~termios.ECHO
80                    try:
81                        termios.tcsetattr(fd, termios.TCSADRAIN, new)
82                        interacted = True
83                        code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.", readfunc=readfunc_stdio, local=local_dict)
84                    finally:
85                        termios.tcsetattr(fd, termios.TCSADRAIN, old)
86            except:
87                pass
88            # Don't need to turn off echoing
89            if not interacted:
90                code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", readfunc=readfunc_stdio, local=local_dict)
91        else:
92            # We have a real interactive terminal
93            code.interact(banner="Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.", local=local_dict)
94    except SystemExit as e:
95        global g_builtin_override_called
96        if not g_builtin_override_called:
97            print 'Script exited with %s' %(e)
98
99def run_one_line (local_dict, input_string):
100    global g_run_one_line_str
101    setquit()
102    try:
103        repl = code.InteractiveConsole(local_dict);
104        if input_string:
105            repl.runsource (input_string)
106        elif g_run_one_line_str:
107            repl.runsource (g_run_one_line_str)
108
109    except SystemExit as e:
110        global g_builtin_override_called
111        if not g_builtin_override_called:
112            print 'Script exited with %s' %(e)
113