blob: ad397b5bef55a90db559665399525cc464e7e26e [file] [log] [blame]
Sean Callanan816cb3e2014-10-16 23:15:22 +00001import lldb
2from lldbtest import *
3import lldbutil
4import os
5import new
6
7def source_type(filename):
8 _, extension = os.path.splitext(filename)
9 return {
10 '.c' : 'C_SOURCES',
11 '.cpp' : 'CXX_SOURCES',
12 '.cxx' : 'CXX_SOURCES',
13 '.cc' : 'CXX_SOURCES',
14 '.m' : 'OBJC_SOURCES',
15 '.mm' : 'OBJCXX_SOURCES'
16 }.get(extension, None)
17
18class CommandParser:
19 def __init__(self):
20 self.breakpoints = []
21
22 def parse_one_command(self, line):
23 parts = line.split('//%')
24 if len(parts) != 2:
25 return None
26 else:
27 return parts[1].strip() # take off trailing whitespace
28
29 def parse_source_files(self, source_files):
30 for source_file in source_files:
31 file_handle = open(source_file)
32 lines = file_handle.readlines()
33 line_number = 0
34 for line in lines:
35 line_number = line_number + 1 # 1-based, so we do this first
36 command = self.parse_one_command(line)
37 if command != None:
38 breakpoint = {}
39 breakpoint['file_name'] = source_file
40 breakpoint['line_number'] = line_number
41 breakpoint['command'] = command
42 self.breakpoints.append(breakpoint)
43
44 def set_breakpoints(self, target):
45 for breakpoint in self.breakpoints:
46 breakpoint['breakpoint'] = target.BreakpointCreateByLocation(breakpoint['file_name'], breakpoint['line_number'])
47
48 def handle_breakpoint(self, test, breakpoint_id):
49 for breakpoint in self.breakpoints:
50 if breakpoint['breakpoint'].GetID() == breakpoint_id:
51 test.execute_user_command(breakpoint['command'])
52 return
53
54def BuildMakefile(mydir):
55 categories = {}
56
57 for f in os.listdir(os.getcwd()):
58 t = source_type(f)
59 if t:
60 if t in categories.keys():
61 categories[t].append(f)
62 else:
63 categories[t] = [f]
64
65 makefile = open("Makefile", 'w+')
66
67 level = os.sep.join([".."] * len(mydir.split(os.sep))) + os.sep + "make"
68
69 makefile.write("LEVEL = " + level + "\n")
70
71 for t in categories.keys():
72 line = t + " := " + " ".join(categories[t])
73 makefile.write(line + "\n")
74
75 if ('OBJCXX_SOURCES' in categories.keys()) or ('OBJC_SOURCES' in categories.keys()):
76 makefile.write("LDFLAGS = $(CFLAGS) -lobjc -framework Foundation\n")
77
78 if ('CXX_SOURCES' in categories.keys()):
79 makefile.write("CXXFLAGS += -std-c++11\n")
80
81 makefile.write("include $(LEVEL)/Makefile.rules\n")
82 makefile.flush()
83 makefile.close()
84
85def CleanMakefile():
86 if (os.path.isfile("Makefile")):
87 os.unlink("Makefile")
88
89class InlineTest(TestBase):
90 # Internal implementation
91
92 def buildDsymWithImplicitMakefile(self):
93 BuildMakefile(self.mydir)
94 self.buildDsym()
95
96 def buildDwarfWithImplicitMakefile(self):
97 BuildMakefile(self.mydir)
98 self.buildDwarf()
99
100 def test_with_dsym(self):
101 self.buildDsymWithImplicitMakefile()
102 self.do_test()
103
104 def test_with_dwarf(self):
105 self.buildDwarfWithImplicitMakefile()
106 self.do_test()
107
108 def execute_user_command(self, __command):
109 exec __command in globals(), locals()
110
111 def do_test(self):
112 exe_name = "a.out"
113 exe = os.path.join(os.getcwd(), exe_name)
114 source_files = [ f for f in os.listdir(os.getcwd()) if source_type(f) ]
115 target = self.dbg.CreateTarget(exe)
116
117 parser = CommandParser()
118 parser.parse_source_files(source_files)
119 parser.set_breakpoints(target)
120
121 process = target.LaunchSimple(None, None, os.getcwd())
122
123 while lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint):
124 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
125 breakpoint_id = thread.GetStopReasonDataAtIndex (0)
126 parser.handle_breakpoint(self, breakpoint_id)
127 process.Continue()
128
129 @classmethod
130 def classCleanup(cls):
131 CleanMakefile()
132
133 # Utilities for testcases
134
135 def check_expression (self, expression, expected_result, use_summary = True):
136 value = self.frame().EvaluateExpression (expression)
137 self.assertTrue(value.IsValid(), expression+"returned a valid value")
138 if self.TraceOn():
139 print value.GetSummary()
140 print value.GetValue()
141 if use_summary:
142 answer = value.GetSummary()
143 else:
144 answer = value.GetValue()
145 report_str = "%s expected: %s got: %s"%(expression, expected_result, answer)
146 self.assertTrue(answer == expected_result, report_str)
147
148def MakeInlineTest(__file, __globals):
149 # Derive the test name from the current file name
150 file_basename = os.path.basename(__file)
151 InlineTest.mydir = TestBase.compute_mydir(__file)
152
153 test_name, _ = os.path.splitext(file_basename)
154 # Build the test case
155 test = new.classobj(test_name, (InlineTest,), {})
156 test.name = test_name
157 # Add the test case to the globals, and hide InlineTest
158 __globals.update({test_name : test})
159 del globals()["InlineTest"]
160
161