1 from __future__ import print_function
2 from __future__ import absolute_import
12 from .lldbtest import *
13 from . import lldbutil
15 def source_type(filename):
16 _, extension = os.path.splitext(filename)
19 '.cpp' : 'CXX_SOURCES',
20 '.cxx' : 'CXX_SOURCES',
21 '.cc' : 'CXX_SOURCES',
22 '.m' : 'OBJC_SOURCES',
23 '.mm' : 'OBJCXX_SOURCES'
24 }.get(extension, None)
30 def parse_one_command(self, line):
31 parts = line.split('//%')
37 command = parts[1].strip() # take off whitespace
38 new_breakpoint = parts[0].strip() != ""
40 return (command, new_breakpoint)
42 def parse_source_files(self, source_files):
43 for source_file in source_files:
44 file_handle = open(source_file)
45 lines = file_handle.readlines()
47 current_breakpoint = None # non-NULL means we're looking through whitespace to find additional commands
49 line_number = line_number + 1 # 1-based, so we do this first
50 (command, new_breakpoint) = self.parse_one_command(line)
53 current_breakpoint = None
56 if current_breakpoint == None:
57 current_breakpoint = {}
58 current_breakpoint['file_name'] = source_file
59 current_breakpoint['line_number'] = line_number
60 current_breakpoint['command'] = command
61 self.breakpoints.append(current_breakpoint)
63 current_breakpoint['command'] = current_breakpoint['command'] + "\n" + command
65 def set_breakpoints(self, target):
66 for breakpoint in self.breakpoints:
67 breakpoint['breakpoint'] = target.BreakpointCreateByLocation(breakpoint['file_name'], breakpoint['line_number'])
69 def handle_breakpoint(self, test, breakpoint_id):
70 for breakpoint in self.breakpoints:
71 if breakpoint['breakpoint'].GetID() == breakpoint_id:
72 test.execute_user_command(breakpoint['command'])
75 class InlineTest(TestBase):
76 # Internal implementation
78 def getRerunArgs(self):
79 # The -N option says to NOT run a if it matches the option argument, so
80 # if we are using dSYM we say to NOT run dwarf (-N dwarf) and vice versa.
81 if self.using_dsym is None:
82 # The test was skipped altogether.
85 return "-N dwarf %s" % (self.mydir)
87 return "-N dsym %s" % (self.mydir)
89 def BuildMakefile(self):
90 if os.path.exists("Makefile"):
95 for f in os.listdir(os.getcwd()):
98 if t in list(categories.keys()):
99 categories[t].append(f)
103 makefile = open("Makefile", 'w+')
105 level = os.sep.join([".."] * len(self.mydir.split(os.sep))) + os.sep + "make"
107 makefile.write("LEVEL = " + level + "\n")
109 for t in list(categories.keys()):
110 line = t + " := " + " ".join(categories[t])
111 makefile.write(line + "\n")
113 if ('OBJCXX_SOURCES' in list(categories.keys())) or ('OBJC_SOURCES' in list(categories.keys())):
114 makefile.write("LDFLAGS = $(CFLAGS) -lobjc -framework Foundation\n")
116 if ('CXX_SOURCES' in list(categories.keys())):
117 makefile.write("CXXFLAGS += -std=c++11\n")
119 makefile.write("include $(LEVEL)/Makefile.rules\n")
125 def __test_with_dsym(self):
126 self.using_dsym = True
131 def __test_with_dwarf(self):
132 self.using_dsym = False
137 def __test_with_dwo(self):
138 self.using_dsym = False
143 def execute_user_command(self, __command):
144 exec(__command, globals(), locals())
148 exe = os.path.join(os.getcwd(), exe_name)
149 source_files = [ f for f in os.listdir(os.getcwd()) if source_type(f) ]
150 target = self.dbg.CreateTarget(exe)
152 parser = CommandParser()
153 parser.parse_source_files(source_files)
154 parser.set_breakpoints(target)
156 process = target.LaunchSimple(None, None, os.getcwd())
158 while lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint):
159 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
160 breakpoint_id = thread.GetStopReasonDataAtIndex (0)
161 parser.handle_breakpoint(self, breakpoint_id)
165 # Utilities for testcases
167 def check_expression (self, expression, expected_result, use_summary = True):
168 value = self.frame().EvaluateExpression (expression)
169 self.assertTrue(value.IsValid(), expression+"returned a valid value")
171 print(value.GetSummary())
172 print(value.GetValue())
174 answer = value.GetSummary()
176 answer = value.GetValue()
177 report_str = "%s expected: %s got: %s"%(expression, expected_result, answer)
178 self.assertTrue(answer == expected_result, report_str)
180 def ApplyDecoratorsToFunction(func, decorators):
182 if type(decorators) == list:
183 for decorator in decorators:
185 elif hasattr(decorators, '__call__'):
186 tmp = decorators(tmp)
190 def MakeInlineTest(__file, __globals, decorators=None):
191 # Derive the test name from the current file name
192 file_basename = os.path.basename(__file)
193 InlineTest.mydir = TestBase.compute_mydir(__file)
195 test_name, _ = os.path.splitext(file_basename)
196 # Build the test case
197 test = type(test_name, (InlineTest,), {'using_dsym': None})
198 test.name = test_name
200 test.test_with_dsym = ApplyDecoratorsToFunction(test._InlineTest__test_with_dsym, decorators)
201 test.test_with_dwarf = ApplyDecoratorsToFunction(test._InlineTest__test_with_dwarf, decorators)
202 test.test_with_dwo = ApplyDecoratorsToFunction(test._InlineTest__test_with_dwo, decorators)
204 # Add the test case to the globals, and hide InlineTest
205 __globals.update({test_name : test})
207 # Store the name of the originating file.o
208 test.test_filename = __file