1"""
2Test lldb data formatter subsystem.
3"""
4
5import os, time
6import unittest2
7import lldb
8from lldbtest import *
9import lldbutil
10
11class LibcxxListDataFormatterTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "list")
14
15    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16    @dsym_test
17    def test_with_dsym_and_run_command(self):
18        """Test data formatter commands."""
19        self.buildDsym()
20        self.data_formatter_commands()
21
22    @skipIfLinux # No standard locations for libc++ on Linux, so skip for now
23    @dwarf_test
24    def test_with_dwarf_and_run_command(self):
25        """Test data formatter commands."""
26        self.buildDwarf()
27        self.data_formatter_commands()
28
29    def setUp(self):
30        # Call super's setUp().
31        TestBase.setUp(self)
32        # Find the line number to break at.
33        self.line = line_number('main.cpp', '// Set break point at this line.')
34        self.line2 = line_number('main.cpp', '// Set second break point at this line.')
35
36    def data_formatter_commands(self):
37        """Test that that file and class static variables display correctly."""
38        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
39
40        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
41        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line2, num_expected_locations=-1)
42
43        self.runCmd("run", RUN_SUCCEEDED)
44
45        # The stop reason of the thread should be breakpoint.
46        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
47            substrs = ['stopped',
48                       'stop reason = breakpoint'])
49
50        # This is the function to remove the custom formats in order to have a
51        # clean slate for the next test case.
52        def cleanup():
53            self.runCmd('type format clear', check=False)
54            self.runCmd('type summary clear', check=False)
55            self.runCmd('type filter clear', check=False)
56            self.runCmd('type synth clear', check=False)
57            self.runCmd("settings set target.max-children-count 256", check=False)
58
59        # Execute the cleanup function during test case tear down.
60        self.addTearDownHook(cleanup)
61
62        self.runCmd("frame variable numbers_list --show-types")
63        self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e")
64        self.runCmd("type format add -f hex int")
65
66        self.expect("frame variable numbers_list --raw", matching=False,
67                    substrs = ['list has 0 items',
68                               '{}'])
69
70        self.expect("frame variable numbers_list",
71                    substrs = ['list has 0 items',
72                               '{}'])
73
74        self.expect("p numbers_list",
75                    substrs = ['list has 0 items',
76                               '{}'])
77
78        self.runCmd("n")
79
80        self.expect("frame variable numbers_list",
81                    substrs = ['list has 1 items',
82                               '[0] = ',
83                               '0x12345678'])
84
85        self.runCmd("n");self.runCmd("n");self.runCmd("n");
86
87        self.expect("frame variable numbers_list",
88                    substrs = ['list has 4 items',
89                               '[0] = ',
90                               '0x12345678',
91                               '[1] =',
92                               '0x11223344',
93                               '[2] =',
94                               '0xbeeffeed',
95                               '[3] =',
96                               '0x00abba00'])
97
98        self.runCmd("n");self.runCmd("n");
99
100        self.expect("frame variable numbers_list",
101                    substrs = ['list has 6 items',
102                               '[0] = ',
103                               '0x12345678',
104                               '0x11223344',
105                               '0xbeeffeed',
106                               '0x00abba00',
107                               '[4] =',
108                               '0x0abcdef0',
109                               '[5] =',
110                               '0x0cab0cab'])
111
112        self.expect("p numbers_list",
113                    substrs = ['list has 6 items',
114                               '[0] = ',
115                               '0x12345678',
116                               '0x11223344',
117                               '0xbeeffeed',
118                               '0x00abba00',
119                               '[4] =',
120                               '0x0abcdef0',
121                               '[5] =',
122                               '0x0cab0cab'])
123
124        # check access-by-index
125        self.expect("frame variable numbers_list[0]",
126                    substrs = ['0x12345678']);
127        self.expect("frame variable numbers_list[1]",
128                    substrs = ['0x11223344']);
129
130        self.runCmd("n")
131
132        self.expect("frame variable numbers_list",
133                    substrs = ['list has 0 items',
134                               '{}'])
135
136        self.runCmd("n");self.runCmd("n");self.runCmd("n");self.runCmd("n");
137
138        self.expect("frame variable numbers_list",
139                    substrs = ['list has 4 items',
140                               '[0] = ', '1',
141                               '[1] = ', '2',
142                               '[2] = ', '3',
143                               '[3] = ', '4'])
144
145        # check that MightHaveChildren() gets it right
146        self.assertTrue(self.frame().FindVariable("numbers_list").MightHaveChildren(), "numbers_list.MightHaveChildren() says False for non empty!")
147
148        self.runCmd("type format delete int")
149
150        self.runCmd("c")
151
152        self.expect("frame variable text_list",
153                    substrs = ['list has 3 items',
154                               '[0]', 'goofy',
155                               '[1]', 'is',
156                               '[2]', 'smart'])
157
158        # check that MightHaveChildren() gets it right
159        self.assertTrue(self.frame().FindVariable("text_list").MightHaveChildren(), "text_list.MightHaveChildren() says False for non empty!")
160
161        self.expect("p text_list",
162                    substrs = ['list has 3 items',
163                               '\"goofy\"',
164                               '\"is\"',
165                               '\"smart\"'])
166
167        self.runCmd("n")
168
169        # check access-by-index
170        self.expect("frame variable text_list[0]",
171                    substrs = ['goofy']);
172        self.expect("frame variable text_list[3]",
173                    substrs = ['!!!']);
174
175if __name__ == '__main__':
176    import atexit
177    lldb.SBDebugger.Initialize()
178    atexit.register(lambda: lldb.SBDebugger.Terminate())
179    unittest2.main()
180