1from __future__ import absolute_import
2
3# System modules
4import os
5import sys
6
7# LLDB Modules
8import lldb
9from .lldbtest import *
10from . import lldbutil
11from lldbsuite.test.decorators import *
12
13@skipIfRemote
14@skipIfWindows  # llvm.org/pr22274: need a pexpect replacement for windows
15class PExpectTest(TestBase):
16
17    NO_DEBUG_INFO_TESTCASE = True
18    PROMPT = "(lldb) "
19
20    def expect_prompt(self):
21        self.child.expect_exact(self.PROMPT)
22
23    def launch(self, executable=None, extra_args=None, timeout=60,
24               dimensions=None, run_under=None, post_spawn=None,
25               use_colors=False):
26        logfile = getattr(sys.stdout, 'buffer',
27                            sys.stdout) if self.TraceOn() else None
28
29        args = []
30        if run_under is not None:
31            args += run_under
32        args += [lldbtest_config.lldbExec, '--no-lldbinit']
33        if not use_colors:
34            args.append('--no-use-colors')
35        for cmd in self.setUpCommands():
36            if "use-color false" in cmd and use_colors:
37                continue
38            args += ['-O', cmd]
39        if executable is not None:
40            args += ['--file', executable]
41        if extra_args is not None:
42            args.extend(extra_args)
43
44        env = dict(os.environ)
45        env["TERM"] = "vt100"
46        env["HOME"] = self.getBuildDir()
47
48        import pexpect
49        self.child = pexpect.spawn(
50                args[0], args=args[1:], logfile=logfile,
51                timeout=timeout, dimensions=dimensions, env=env)
52        self.child.ptyproc.delayafterclose = timeout/10
53        self.child.ptyproc.delayafterterminate = timeout/10
54
55        if post_spawn is not None:
56            post_spawn()
57        self.expect_prompt()
58        for cmd in self.setUpCommands():
59            if "use-color false" in cmd and use_colors:
60                continue
61            self.child.expect_exact(cmd)
62            self.expect_prompt()
63        if executable is not None:
64            self.child.expect_exact("target create")
65            self.child.expect_exact("Current executable set to")
66            self.expect_prompt()
67
68    def expect(self, cmd, substrs=None):
69        self.assertNotIn('\n', cmd)
70        # If 'substrs' is a string then this code would just check that every
71        # character of the string is in the output.
72        assert not isinstance(substrs, str), \
73            "substrs must be a collection of strings"
74
75        self.child.sendline(cmd)
76        if substrs is not None:
77            for s in substrs:
78                self.child.expect_exact(s)
79        self.expect_prompt()
80
81    def quit(self, gracefully=True):
82        self.child.sendeof()
83        self.child.close(force=not gracefully)
84        self.child = None
85
86    def cursor_forward_escape_seq(self, chars_to_move):
87        """
88        Returns the escape sequence to move the cursor forward/right
89        by a certain amount of characters.
90        """
91        return b"\x1b\[" + str(chars_to_move).encode("utf-8") + b"C"
92