Cleaned up the option parsing code to always pass around the short options as integers. Previously we cast this down to "char" and lost some information. I recently added an assert that would detect duplicate short character options which was firing during the test suite. This fix does the following: - make sure all short options are treated as "int" - make sure that short options can be non-printable values when a short option is not required or when an option group is mixed into many commands and a short option is not desired - fix the help printing to "do the right thing" in all cases. Previously if there were duplicate short character options, it would just not emit help for the duplicates - fix option parsing when there are duplicates to parse options correctly. Previously the option parsing, when done for an OptionGroup, would just start parsing options incorrectly by omitting table entries and it would end up setting the wrong option value llvm-svn: 169189
176 lines
6.6 KiB
Python
176 lines
6.6 KiB
Python
"""
|
|
Test using LLDB data formatters with frozen objects coming from the expression parser.
|
|
"""
|
|
|
|
import unittest2
|
|
import lldb
|
|
import lldbutil
|
|
from lldbtest import *
|
|
|
|
class ExprFormattersTestCase(TestBase):
|
|
|
|
mydir = os.path.join("expression_command", "formatters")
|
|
|
|
def setUp(self):
|
|
# Call super's setUp().
|
|
TestBase.setUp(self)
|
|
# Find the line number to break for main.cpp.
|
|
self.line = line_number('main.cpp',
|
|
'// Stop here')
|
|
|
|
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
|
@dsym_test
|
|
def test_with_dsym(self):
|
|
"""Test expr + formatters for good interoperability."""
|
|
self.buildDsym()
|
|
self.do_my_test()
|
|
|
|
@expectedFailureLinux # bugzilla 14437
|
|
@dwarf_test
|
|
def test_with_dwarf(self):
|
|
"""Test expr + formatters for good interoperability."""
|
|
self.buildDwarf()
|
|
self.do_my_test()
|
|
|
|
def do_my_test(self):
|
|
|
|
# This is the function to remove the custom formats in order to have a
|
|
# clean slate for the next test case.
|
|
def cleanup():
|
|
self.runCmd('type summary clear', check=False)
|
|
self.runCmd('type synthetic clear', check=False)
|
|
|
|
# Execute the cleanup function during test case tear down.
|
|
self.addTearDownHook(cleanup)
|
|
|
|
"""Test expr + formatters for good interoperability."""
|
|
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
|
|
|
|
lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, loc_exact=True)
|
|
|
|
self.runCmd("run", RUN_SUCCEEDED)
|
|
self.runCmd("script import formatters")
|
|
self.runCmd("script import foosynth")
|
|
|
|
self.runCmd("frame variable foo1 --show-types")
|
|
self.runCmd("frame variable foo1.b --show-types")
|
|
self.runCmd("frame variable foo1.b.b_ref --show-types")
|
|
|
|
self.expect("expression *(new foo(47))",
|
|
substrs = ['(int) a = 47', '(bar) b = {', '(int) i = 94', '(baz) b = {', '(int) k = 99'])
|
|
|
|
self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
|
|
|
|
self.expect("expression new int(12)",
|
|
substrs = ['(int *) $', ' = 0x'])
|
|
|
|
self.runCmd("type summary add -s \"${var%pointer} -> ${*var%decimal}\" \"int *\"")
|
|
|
|
self.expect("expression new int(12)",
|
|
substrs = ['(int *) $', '= 0x', ' -> 12'])
|
|
|
|
self.expect("expression foo1.a_ptr",
|
|
substrs = ['(int *) $', '= 0x', ' -> 13'])
|
|
|
|
self.expect("expression foo1",
|
|
substrs = ['(foo) $', ' = a = 12, a_ptr = ', ' -> 13, i = 24, i_ptr = ', ' -> 25'])
|
|
|
|
self.expect("expression new foo(47)",
|
|
substrs = ['(foo *) $', ' a = 47, a_ptr = ', ' -> 48, i = 94, i_ptr = ', ' -> 95'])
|
|
|
|
self.expect("expression foo2",
|
|
substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 243'])
|
|
|
|
object_name = self.res.GetOutput()
|
|
object_name = object_name[7:]
|
|
object_name = object_name[0:object_name.find(' =')]
|
|
|
|
self.expect("frame variable foo2",
|
|
substrs = ['(foo)', 'foo2', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 243'])
|
|
|
|
self.expect("expression $" + object_name,
|
|
substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 243', ', h = 245 , k = 247'])
|
|
|
|
self.runCmd("type summary delete foo")
|
|
self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo")
|
|
|
|
self.expect("expression $" + object_name,
|
|
substrs = ['(foo) $', ' = {', '(int) *i_ptr = 243'])
|
|
|
|
self.runCmd("n")
|
|
self.runCmd("n")
|
|
|
|
self.runCmd("type synthetic delete foo")
|
|
self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
|
|
|
|
self.expect("expression foo2",
|
|
substrs = ['(foo) $', ' = a = 7777, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 8888'])
|
|
|
|
self.expect("expression $" + object_name + '.a',
|
|
substrs = ['7777'])
|
|
|
|
self.expect("expression *$" + object_name + '.b.i_ptr',
|
|
substrs = ['8888'])
|
|
|
|
self.expect("expression $" + object_name,
|
|
substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 8888', 'h = 245 , k = 247'])
|
|
|
|
self.runCmd("type summary delete foo")
|
|
self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo")
|
|
|
|
self.expect("expression $" + object_name,
|
|
substrs = ['(foo) $', ' = {', '(int) *i_ptr = 8888'])
|
|
|
|
self.runCmd("n")
|
|
|
|
self.runCmd("type synthetic delete foo")
|
|
self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
|
|
|
|
self.expect("expression $" + object_name,
|
|
substrs = ['(foo) $', ' = a = 121, a_ptr = ', ' -> 122, i = 242, i_ptr = ', ' -> 8888', 'h = 9999 , k = 247'])
|
|
|
|
process = self.dbg.GetSelectedTarget().GetProcess()
|
|
thread = process.GetThreadAtIndex(0)
|
|
frame = thread.GetSelectedFrame()
|
|
|
|
frozen = frame.EvaluateExpression("$" + object_name + ".a_ptr")
|
|
|
|
a_data = frozen.GetPointeeData()
|
|
|
|
error = lldb.SBError()
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 122, '*a_ptr = 122')
|
|
|
|
self.runCmd("n");self.runCmd("n");self.runCmd("n");
|
|
|
|
self.expect("frame variable numbers",
|
|
substrs = ['1','2','3','4','5'])
|
|
|
|
self.expect("expression numbers",
|
|
substrs = ['1','2','3','4','5'])
|
|
|
|
frozen = frame.EvaluateExpression("&numbers")
|
|
|
|
a_data = frozen.GetPointeeData(0, 1)
|
|
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5')
|
|
|
|
frozen = frame.EvaluateExpression("numbers")
|
|
|
|
a_data = frozen.GetData()
|
|
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 0) == 1, 'numbers[0] == 1')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 4) == 2, 'numbers[1] == 2')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 8) == 3, 'numbers[2] == 3')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 12) == 4, 'numbers[3] == 4')
|
|
self.assertTrue(a_data.GetUnsignedInt32(error, 16) == 5, 'numbers[4] == 5')
|
|
|
|
if __name__ == '__main__':
|
|
import atexit
|
|
lldb.SBDebugger.Initialize()
|
|
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
|
unittest2.main()
|