1#!/usr/bin/python
2
3# Copyright 2016 Steven Watanabe
4# Distributed under the Boost Software License, Version 1.0.
5# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
6
7# Test the mi interface for the debugger
8
9import BoostBuild
10import TestCmd
11import re
12
13def split_stdin_stdout(text):
14    """stdin is all text after the prompt up to and including
15    the next newline.  Everything else is stdout.  stdout
16    may contain regular expressions enclosed in {{}}."""
17    prompt = re.escape('(gdb) \n')
18    pattern = re.compile('(?<=%s)((?:\d*-.*)\n)' % prompt)
19    stdin = ''.join(re.findall(pattern, text))
20    stdout = re.sub(pattern, '', text)
21    outside_pattern = re.compile(r'(?:\A|(?<=\}\}))(?:[^\{]|(?:\{(?!\{)))*(?:(?=\{\{)|\Z)')
22
23    def escape_line(line):
24        line = re.sub(outside_pattern, lambda m: re.escape(m.group(0)), line)
25        return re.sub(r'\{\{|\}\}', '', line)
26
27    stdout = '\n'.join([escape_line(line) for line in stdout.split('\n')])
28    return (stdin,stdout)
29
30def run(tester, io):
31    (input,output) = split_stdin_stdout(io)
32    tester.run_build_system(stdin=input, stdout=output, match=TestCmd.match_re)
33
34def make_tester():
35    return BoostBuild.Tester(["-dmi"], pass_toolset=False, pass_d0=False,
36        use_test_config=False, ignore_toolset_requirements=False, match=TestCmd.match_re)
37
38def test_exec_run():
39    t = make_tester()
40    t.write("test.jam", """\
41        UPDATE ;
42    """)
43
44    run(t, """\
45=thread-group-added,id="i1"
46(gdb)
4772-exec-run -ftest.jam
48=thread-created,id="1",group-id="i1"
4972^running
50(gdb)
51*stopped,reason="exited-normally"
52(gdb)
5373-gdb-exit
5473^exit
55""")
56
57    t.cleanup()
58
59def test_exit_status():
60    t = make_tester()
61    t.write("test.jam", """\
62        EXIT : 1 ;
63    """)
64    run(t, """\
65=thread-group-added,id="i1"
66(gdb)
6772-exec-run -ftest.jam
68=thread-created,id="1",group-id="i1"
6972^running
70(gdb)
71
72*stopped,reason="exited",exit-code="1"
73(gdb)
7473-gdb-exit
7573^exit
76""")
77    t.cleanup()
78
79def test_exec_step():
80    t = make_tester()
81    t.write("test.jam", """\
82        rule g ( )
83        {
84            a = 1 ;
85            b = 2 ;
86        }
87        rule f ( )
88        {
89            g ;
90            c = 3 ;
91        }
92        f ;
93    """)
94    run(t, """\
95=thread-group-added,id="i1"
96(gdb)
97-break-insert f
98^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
99(gdb)
10072-exec-run -ftest.jam
101=thread-created,id="1",group-id="i1"
10272^running
103(gdb)
104*stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="8"},thread-id="1",stopped-threads="all"
105(gdb)
1061-exec-step
1071^running
108(gdb)
109*stopped,reason="end-stepping-range",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1"
110(gdb)
1112-exec-step
1122^running
113(gdb)
114*stopped,reason="end-stepping-range",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="4"},thread-id="1"
115(gdb)
1163-exec-step
1173^running
118(gdb)
119*stopped,reason="end-stepping-range",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="9"},thread-id="1"
120(gdb)
12173-gdb-exit
12273^exit
123""")
124    t.cleanup()
125
126def test_exec_next():
127    t = make_tester()
128    t.write("test.jam", """\
129        rule g ( )
130        {
131            a = 1 ;
132        }
133        rule f ( )
134        {
135            g ;
136            b = 2 ;
137            c = 3 ;
138        }
139        rule h ( )
140        {
141            f ;
142            g ;
143        }
144        h ;
145        d = 4 ;
146    """)
147    run(t, """\
148=thread-group-added,id="i1"
149(gdb)
150-break-insert f
151^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
152(gdb)
15372-exec-run -ftest.jam
154=thread-created,id="1",group-id="i1"
15572^running
156(gdb)
157*stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="7"},thread-id="1",stopped-threads="all"
158(gdb)
1591-exec-next
1601^running
161(gdb)
162*stopped,reason="end-stepping-range",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="8"},thread-id="1"
163(gdb)
1642-exec-next
1652^running
166(gdb)
167*stopped,reason="end-stepping-range",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="9"},thread-id="1"
168(gdb)
1693-exec-next
1703^running
171(gdb)
172*stopped,reason="end-stepping-range",frame={func="h",args=[],file="test.jam",fullname="{{.*}}test.jam",line="14"},thread-id="1"
173(gdb)
1744-exec-next
1754^running
176(gdb)
177*stopped,reason="end-stepping-range",frame={func="module scope",args=[],file="test.jam",fullname="{{.*}}test.jam",line="17"},thread-id="1"
178(gdb)
17973-gdb-exit
18073^exit
181""")
182    t.cleanup()
183
184def test_exec_finish():
185    t = make_tester()
186    t.write("test.jam", """\
187        rule f ( )
188        {
189            a = 1 ;
190        }
191        rule g ( )
192        {
193            f ;
194            b = 2 ;
195            i ;
196        }
197        rule h ( )
198        {
199            g ;
200            i ;
201        }
202        rule i ( )
203        {
204            c = 3 ;
205        }
206        h ;
207        d = 4 ;
208    """)
209    run(t, """\
210=thread-group-added,id="i1"
211(gdb)
212-break-insert f
213^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
214(gdb)
21572-exec-run -ftest.jam
216=thread-created,id="1",group-id="i1"
21772^running
218(gdb)
219*stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1",stopped-threads="all"
220(gdb)
2211-exec-finish
2221^running
223(gdb)
224*stopped,reason="end-stepping-range",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="8"},thread-id="1"
225(gdb)
2262-exec-finish
2272^running
228(gdb)
229*stopped,reason="end-stepping-range",frame={func="h",args=[],file="test.jam",fullname="{{.*}}test.jam",line="14"},thread-id="1"
230(gdb)
2313-exec-finish
2323^running
233(gdb)
234*stopped,reason="end-stepping-range",frame={func="module scope",args=[],file="test.jam",fullname="{{.*}}test.jam",line="21"},thread-id="1"
235(gdb)
23673-gdb-exit
23773^exit
238""")
239    t.cleanup()
240
241
242def test_breakpoints():
243    """Tests the interaction between the following commands:
244    break, clear, delete, disable, enable"""
245    t = make_tester()
246    t.write("test.jam", """\
247        rule f ( )
248        {
249            a = 1 ;
250        }
251        rule g ( )
252        {
253            b = 2 ;
254        }
255        rule h ( )
256        {
257            c = 3 ;
258            d = 4 ;
259        }
260        f ;
261        g ;
262        h ;
263        UPDATE ;
264    """)
265    run(t, """\
266=thread-group-added,id="i1"
267(gdb)
268-break-insert f
269^done,bkpt={number="1",type="breakpoint",disp="keep",enabled="y",func="f"}
270(gdb)
27172-exec-run -ftest.jam
272=thread-created,id="1",group-id="i1"
27372^running
274(gdb)
275*stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1",stopped-threads="all"
276(gdb)
277-interpreter-exec console kill
278^done
279(gdb)
280-break-insert g
281^done,bkpt={number="2",type="breakpoint",disp="keep",enabled="y",func="g"}
282(gdb)
283-break-disable 1
284^done
285(gdb)
28673-exec-run -ftest.jam
287=thread-created,id="1",group-id="i1"
28873^running
289(gdb)
290*stopped,reason="breakpoint-hit",bkptno="2",disp="keep",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="7"},thread-id="1",stopped-threads="all"
291(gdb)
292-interpreter-exec console kill
293^done
294(gdb)
295-break-enable 1
296^done
297(gdb)
29874-exec-run -ftest.jam
299=thread-created,id="1",group-id="i1"
30074^running
301(gdb)
302*stopped,reason="breakpoint-hit",bkptno="1",disp="keep",frame={func="f",args=[],file="test.jam",fullname="{{.*}}test.jam",line="3"},thread-id="1",stopped-threads="all"
303(gdb)
304-interpreter-exec console kill
305^done
306(gdb)
307-break-delete 1
308^done
309(gdb)
31075-exec-run -ftest.jam
311=thread-created,id="1",group-id="i1"
31275^running
313(gdb)
314*stopped,reason="breakpoint-hit",bkptno="2",disp="keep",frame={func="g",args=[],file="test.jam",fullname="{{.*}}test.jam",line="7"},thread-id="1",stopped-threads="all"
315(gdb)
31676-gdb-exit
31776^exit
318""")
319    t.cleanup()
320
321test_exec_run()
322test_exit_status()
323test_exec_step()
324test_exec_next()
325test_exec_finish()
326test_breakpoints()
327