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