1113bf067SBram Moolenaar" Tests for the Vim script debug commands
2113bf067SBram Moolenaar
3113bf067SBram Moolenaarsource shared.vim
4113bf067SBram Moolenaarsource screendump.vim
58c5a278fSBram Moolenaarsource check.vim
6113bf067SBram Moolenaar
7b7f4fa51SBram MoolenaarCheckRunVimInTerminal
8b7f4fa51SBram Moolenaar
9b7f4fa51SBram Moolenaarfunc CheckCWD()
10b7f4fa51SBram Moolenaar  " Check that the longer lines don't wrap due to the length of the script name
11b7f4fa51SBram Moolenaar  " in cwd
12b7f4fa51SBram Moolenaar  let script_len = len( getcwd() .. '/Xtest1.vim' )
13b7f4fa51SBram Moolenaar  let longest_line = len( 'Breakpoint in "" line 1' )
14b7f4fa51SBram Moolenaar  if script_len > ( 75 - longest_line )
15b7f4fa51SBram Moolenaar    throw 'Skipped: Your CWD has too many characters'
16b7f4fa51SBram Moolenaar  endif
17b7f4fa51SBram Moolenaarendfunc
18b7f4fa51SBram Moolenaarcommand! -nargs=0 -bar CheckCWD call CheckCWD()
19b7f4fa51SBram Moolenaar
2018dc3553SBram Moolenaar" "options" argument can contain:
2118dc3553SBram Moolenaar" 'msec' - time to wait for a match
2218dc3553SBram Moolenaar" 'match' - "pattern" to use "lines" as pattern instead of text
236ca6ca48SBram Moolenaarfunc CheckDbgOutput(buf, lines, options = {})
246ca6ca48SBram Moolenaar  " Verify the expected output
256ca6ca48SBram Moolenaar  let lnum = 20 - len(a:lines)
2618dc3553SBram Moolenaar  let msec = get(a:options, 'msec', 1000)
276ca6ca48SBram Moolenaar  for l in a:lines
286ca6ca48SBram Moolenaar    if get(a:options, 'match', 'equal') ==# 'pattern'
2918dc3553SBram Moolenaar      call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, msec)
306ca6ca48SBram Moolenaar    else
3118dc3553SBram Moolenaar      call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, msec)
326ca6ca48SBram Moolenaar    endif
336ca6ca48SBram Moolenaar    let lnum += 1
346ca6ca48SBram Moolenaar  endfor
356ca6ca48SBram Moolenaarendfunc
366ca6ca48SBram Moolenaar
37113bf067SBram Moolenaar" Run a Vim debugger command
38113bf067SBram Moolenaar" If the expected output argument is supplied, then check for it.
39113bf067SBram Moolenaarfunc RunDbgCmd(buf, cmd, ...)
40113bf067SBram Moolenaar  call term_sendkeys(a:buf, a:cmd . "\r")
416a2c5a7dSBram Moolenaar  call TermWait(a:buf)
42113bf067SBram Moolenaar
43113bf067SBram Moolenaar  if a:0 != 0
446ca6ca48SBram Moolenaar    let options = #{match: 'equal'}
456ca6ca48SBram Moolenaar    if a:0 > 1
466ca6ca48SBram Moolenaar      call extend(options, a:2)
476ca6ca48SBram Moolenaar    endif
486ca6ca48SBram Moolenaar    call CheckDbgOutput(a:buf, a:1, options)
49113bf067SBram Moolenaar  endif
50113bf067SBram Moolenaarendfunc
51113bf067SBram Moolenaar
52113bf067SBram Moolenaar" Debugger tests
53113bf067SBram Moolenaarfunc Test_Debugger()
54113bf067SBram Moolenaar  " Create a Vim script with some functions
55e7eb9270SBram Moolenaar  let lines =<< trim END
56e7eb9270SBram Moolenaar	func Foo()
57e7eb9270SBram Moolenaar	  let var1 = 1
58e7eb9270SBram Moolenaar	  let var2 = Bar(var1) + 9
59e7eb9270SBram Moolenaar	  return var2
60e7eb9270SBram Moolenaar	endfunc
61e7eb9270SBram Moolenaar	func Bar(var)
62e7eb9270SBram Moolenaar	  let var1 = 2 + a:var
63e7eb9270SBram Moolenaar	  let var2 = Bazz(var1) + 4
64e7eb9270SBram Moolenaar	  return var2
65e7eb9270SBram Moolenaar	endfunc
66e7eb9270SBram Moolenaar	func Bazz(var)
67e7eb9270SBram Moolenaar	  try
68e7eb9270SBram Moolenaar	    let var1 = 3 + a:var
69e7eb9270SBram Moolenaar	    let var3 = "another var"
70e7eb9270SBram Moolenaar	    let var3 = "value2"
71e7eb9270SBram Moolenaar	  catch
72e7eb9270SBram Moolenaar	    let var4 = "exception"
73e7eb9270SBram Moolenaar	  endtry
74e7eb9270SBram Moolenaar	  return var1
75e7eb9270SBram Moolenaar	endfunc
76e7eb9270SBram Moolenaar  END
77e7eb9270SBram Moolenaar  call writefile(lines, 'Xtest.vim')
78113bf067SBram Moolenaar
79113bf067SBram Moolenaar  " Start Vim in a terminal
80113bf067SBram Moolenaar  let buf = RunVimInTerminal('-S Xtest.vim', {})
81113bf067SBram Moolenaar
82113bf067SBram Moolenaar  " Start the Vim debugger
83ddd33087SBram Moolenaar  call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
84113bf067SBram Moolenaar
85113bf067SBram Moolenaar  " Create a few stack frames by stepping through functions
86ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
87ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
88ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
89ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
90ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: try'])
91ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
92ddd33087SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
93113bf067SBram Moolenaar
94113bf067SBram Moolenaar  " check backtrace
95113bf067SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
96113bf067SBram Moolenaar	      \ '  2 function Foo[2]',
97113bf067SBram Moolenaar	      \ '  1 Bar[2]',
98113bf067SBram Moolenaar	      \ '->0 Bazz',
990fdd9435SBram Moolenaar	      \ 'line 3: let var3 = "another var"'])
100113bf067SBram Moolenaar
101113bf067SBram Moolenaar  " Check variables in different stack frames
102113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var1', ['6'])
103113bf067SBram Moolenaar
104113bf067SBram Moolenaar  call RunDbgCmd(buf, 'up')
105113bf067SBram Moolenaar  call RunDbgCmd(buf, 'back', [
106113bf067SBram Moolenaar	      \ '  2 function Foo[2]',
107113bf067SBram Moolenaar	      \ '->1 Bar[2]',
108113bf067SBram Moolenaar	      \ '  0 Bazz',
1090fdd9435SBram Moolenaar	      \ 'line 3: let var3 = "another var"'])
110113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var1', ['3'])
111113bf067SBram Moolenaar
112113bf067SBram Moolenaar  call RunDbgCmd(buf, 'u')
113113bf067SBram Moolenaar  call RunDbgCmd(buf, 'bt', [
114113bf067SBram Moolenaar	      \ '->2 function Foo[2]',
115113bf067SBram Moolenaar	      \ '  1 Bar[2]',
116113bf067SBram Moolenaar	      \ '  0 Bazz',
1170fdd9435SBram Moolenaar	      \ 'line 3: let var3 = "another var"'])
118113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var1', ['1'])
119113bf067SBram Moolenaar
120113bf067SBram Moolenaar  " Undefined variables
121113bf067SBram Moolenaar  call RunDbgCmd(buf, 'step')
122113bf067SBram Moolenaar  call RunDbgCmd(buf, 'frame 2')
123113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var3', [
124113bf067SBram Moolenaar	\ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
1250fdd9435SBram Moolenaar	\ 'line    4:',
126113bf067SBram Moolenaar	\ 'E121: Undefined variable: var3'])
127113bf067SBram Moolenaar
128113bf067SBram Moolenaar  " var3 is defined in this level with some other value
129113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fr 0')
130113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var3', ['another var'])
131113bf067SBram Moolenaar
132113bf067SBram Moolenaar  call RunDbgCmd(buf, 'step')
1330fdd9435SBram Moolenaar  call RunDbgCmd(buf, '')
1340fdd9435SBram Moolenaar  call RunDbgCmd(buf, '')
1350fdd9435SBram Moolenaar  call RunDbgCmd(buf, '')
1360fdd9435SBram Moolenaar  call RunDbgCmd(buf, '')
137113bf067SBram Moolenaar  call RunDbgCmd(buf, 'step', [
138113bf067SBram Moolenaar	      \ 'function Foo[2]..Bar',
139113bf067SBram Moolenaar	      \ 'line 3: End of function'])
140113bf067SBram Moolenaar  call RunDbgCmd(buf, 'up')
141113bf067SBram Moolenaar
142113bf067SBram Moolenaar  " Undefined var2
143113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var2', [
144113bf067SBram Moolenaar	      \ 'Error detected while processing function Foo[2]..Bar:',
145113bf067SBram Moolenaar	      \ 'line    3:',
146113bf067SBram Moolenaar	      \ 'E121: Undefined variable: var2'])
147113bf067SBram Moolenaar
148113bf067SBram Moolenaar  " Var2 is defined with 10
149113bf067SBram Moolenaar  call RunDbgCmd(buf, 'down')
150113bf067SBram Moolenaar  call RunDbgCmd(buf, 'echo var2', ['10'])
151113bf067SBram Moolenaar
152113bf067SBram Moolenaar  " Backtrace movements
153113bf067SBram Moolenaar  call RunDbgCmd(buf, 'b', [
154113bf067SBram Moolenaar	      \ '  1 function Foo[2]',
155113bf067SBram Moolenaar	      \ '->0 Bar',
156113bf067SBram Moolenaar	      \ 'line 3: End of function'])
157113bf067SBram Moolenaar
158113bf067SBram Moolenaar  " next command cannot go down, we are on bottom
159113bf067SBram Moolenaar  call RunDbgCmd(buf, 'down', ['frame is zero'])
160113bf067SBram Moolenaar  call RunDbgCmd(buf, 'up')
161113bf067SBram Moolenaar
162113bf067SBram Moolenaar  " next command cannot go up, we are on top
163113bf067SBram Moolenaar  call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
164113bf067SBram Moolenaar  call RunDbgCmd(buf, 'where', [
165113bf067SBram Moolenaar	      \ '->1 function Foo[2]',
166113bf067SBram Moolenaar	      \ '  0 Bar',
167113bf067SBram Moolenaar	      \ 'line 3: End of function'])
168113bf067SBram Moolenaar
169113bf067SBram Moolenaar  " fil is not frame or finish, it is file
170113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
171113bf067SBram Moolenaar
172113bf067SBram Moolenaar  " relative backtrace movement
173113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fr -1')
174113bf067SBram Moolenaar  call RunDbgCmd(buf, 'frame', [
175113bf067SBram Moolenaar	      \ '  1 function Foo[2]',
176113bf067SBram Moolenaar	      \ '->0 Bar',
177113bf067SBram Moolenaar	      \ 'line 3: End of function'])
178113bf067SBram Moolenaar
179113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fr +1')
180113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fram', [
181113bf067SBram Moolenaar	      \ '->1 function Foo[2]',
182113bf067SBram Moolenaar	      \ '  0 Bar',
183113bf067SBram Moolenaar	      \ 'line 3: End of function'])
184113bf067SBram Moolenaar
185113bf067SBram Moolenaar  " go beyond limits does not crash
186113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
187113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fra', [
188113bf067SBram Moolenaar	      \ '->1 function Foo[2]',
189113bf067SBram Moolenaar	      \ '  0 Bar',
190113bf067SBram Moolenaar	      \ 'line 3: End of function'])
191113bf067SBram Moolenaar
192113bf067SBram Moolenaar  call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
193113bf067SBram Moolenaar  call RunDbgCmd(buf, 'fram', [
194113bf067SBram Moolenaar	      \ '  1 function Foo[2]',
195113bf067SBram Moolenaar	      \ '->0 Bar',
196113bf067SBram Moolenaar	      \ 'line 3: End of function'])
197113bf067SBram Moolenaar
198113bf067SBram Moolenaar  " final result 19
199113bf067SBram Moolenaar  call RunDbgCmd(buf, 'cont', ['19'])
200113bf067SBram Moolenaar
201113bf067SBram Moolenaar  " breakpoints tests
202113bf067SBram Moolenaar
203113bf067SBram Moolenaar  " Start a debug session, so that reading the last line from the terminal
204113bf067SBram Moolenaar  " works properly.
20518dc3553SBram Moolenaar  call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
206113bf067SBram Moolenaar
207113bf067SBram Moolenaar  " No breakpoints
208113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
209113bf067SBram Moolenaar
210113bf067SBram Moolenaar  " Place some breakpoints
211113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breaka func Bar')
212113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breaklis', ['  1  func Bar  line 1'])
213113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakadd func 3 Bazz')
214113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breaklist', ['  1  func Bar  line 1',
215113bf067SBram Moolenaar	      \ '  2  func Bazz  line 3'])
216113bf067SBram Moolenaar
217113bf067SBram Moolenaar  " Check whether the breakpoints are hit
218113bf067SBram Moolenaar  call RunDbgCmd(buf, 'cont', [
219113bf067SBram Moolenaar	      \ 'Breakpoint in "Bar" line 1',
220113bf067SBram Moolenaar	      \ 'function Foo[2]..Bar',
221113bf067SBram Moolenaar	      \ 'line 1: let var1 = 2 + a:var'])
222113bf067SBram Moolenaar  call RunDbgCmd(buf, 'cont', [
223113bf067SBram Moolenaar	      \ 'Breakpoint in "Bazz" line 3',
224113bf067SBram Moolenaar	      \ 'function Foo[2]..Bar[2]..Bazz',
2250fdd9435SBram Moolenaar	      \ 'line 3: let var3 = "another var"'])
226113bf067SBram Moolenaar
227113bf067SBram Moolenaar  " Delete the breakpoints
228113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakd 1')
229113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakli', ['  2  func Bazz  line 3'])
230113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakdel func 3 Bazz')
231113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
232113bf067SBram Moolenaar
233113bf067SBram Moolenaar  call RunDbgCmd(buf, 'cont')
234113bf067SBram Moolenaar
235113bf067SBram Moolenaar  " Make sure the breakpoints are removed
236113bf067SBram Moolenaar  call RunDbgCmd(buf, ':echo Foo()', ['19'])
237113bf067SBram Moolenaar
238113bf067SBram Moolenaar  " Delete a non-existing breakpoint
239113bf067SBram Moolenaar  call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
240113bf067SBram Moolenaar
241113bf067SBram Moolenaar  " Expression breakpoint
242113bf067SBram Moolenaar  call RunDbgCmd(buf, ':breakadd func 2 Bazz')
2430fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':echo Bazz(1)', [
2440fdd9435SBram Moolenaar	      \ 'Entering Debug mode.  Type "cont" to continue.',
2450fdd9435SBram Moolenaar	      \ 'function Bazz',
2460fdd9435SBram Moolenaar	      \ 'line 2: let var1 = 3 + a:var'])
2470fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'step')
248113bf067SBram Moolenaar  call RunDbgCmd(buf, 'step')
249113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breaka expr var3')
2500fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakl', ['  3  func Bazz  line 2',
2510fdd9435SBram Moolenaar	      \ '  4  expr var3'])
2520fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
253113bf067SBram Moolenaar	      \ 'Oldval = "''another var''"',
254113bf067SBram Moolenaar	      \ 'Newval = "''value2''"',
255113bf067SBram Moolenaar	      \ 'function Bazz',
2560fdd9435SBram Moolenaar	      \ 'line 5: catch'])
257113bf067SBram Moolenaar
258113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakdel *')
259113bf067SBram Moolenaar  call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
260113bf067SBram Moolenaar
2610fdd9435SBram Moolenaar  " Check for error cases
2620fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakadd abcd', [
2630fdd9435SBram Moolenaar	      \ 'Error detected while processing function Bazz:',
2640fdd9435SBram Moolenaar	      \ 'line    5:',
2650fdd9435SBram Moolenaar	      \ 'E475: Invalid argument: abcd'])
2660fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
2670fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
2680fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
2690fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
2700fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
2710fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
2720fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
2730fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
274*0325d396SBram Moolenaar  call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x'])
2750fdd9435SBram Moolenaar
276113bf067SBram Moolenaar  " finish the current function
277113bf067SBram Moolenaar  call RunDbgCmd(buf, 'finish', [
278113bf067SBram Moolenaar	      \ 'function Bazz',
2790fdd9435SBram Moolenaar	      \ 'line 8: End of function'])
2800fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'cont')
2810fdd9435SBram Moolenaar
2820fdd9435SBram Moolenaar  " Test for :next
2830fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':debug echo Bar(1)')
2840fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'step')
2850fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'next')
2860fdd9435SBram Moolenaar  call RunDbgCmd(buf, '', [
2870fdd9435SBram Moolenaar	      \ 'function Bar',
2880fdd9435SBram Moolenaar	      \ 'line 3: return var2'])
2890fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'c')
2900fdd9435SBram Moolenaar
2910fdd9435SBram Moolenaar  " Test for :interrupt
2920fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':debug echo Bazz(1)')
2930fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'step')
2940fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'step')
2950fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'interrupt', [
2960fdd9435SBram Moolenaar	      \ 'Exception thrown: Vim:Interrupt',
2970fdd9435SBram Moolenaar	      \ 'function Bazz',
2980fdd9435SBram Moolenaar	      \ 'line 5: catch'])
2990fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'c')
3000fdd9435SBram Moolenaar
3010fdd9435SBram Moolenaar  " Test for :quit
3020fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':debug echo Foo()')
3030fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakdel *')
3040fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakadd func 3 Foo')
3050fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakadd func 3 Bazz')
3060fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'cont', [
3070fdd9435SBram Moolenaar	      \ 'Breakpoint in "Bazz" line 3',
3080fdd9435SBram Moolenaar	      \ 'function Foo[2]..Bar[2]..Bazz',
3090fdd9435SBram Moolenaar	      \ 'line 3: let var3 = "another var"'])
3100fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'quit', [
3110fdd9435SBram Moolenaar	      \ 'Breakpoint in "Foo" line 3',
3120fdd9435SBram Moolenaar	      \ 'function Foo',
3130fdd9435SBram Moolenaar	      \ 'line 3: return var2'])
3140fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'breakdel *')
3150fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'quit')
3160fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'enew! | only!')
3170fdd9435SBram Moolenaar
3180fdd9435SBram Moolenaar  call StopVimInTerminal(buf)
319072f1c68SBram Moolenaarendfunc
3200fdd9435SBram Moolenaar
321072f1c68SBram Moolenaarfunc Test_Debugger_breakadd()
3220fdd9435SBram Moolenaar  " Tests for :breakadd file and :breakadd here
3230fdd9435SBram Moolenaar  " Breakpoints should be set before sourcing the file
3240fdd9435SBram Moolenaar
325e7eb9270SBram Moolenaar  let lines =<< trim END
326e7eb9270SBram Moolenaar	let var1 = 10
327e7eb9270SBram Moolenaar	let var2 = 20
328e7eb9270SBram Moolenaar	let var3 = 30
329e7eb9270SBram Moolenaar	let var4 = 40
330e7eb9270SBram Moolenaar  END
331e7eb9270SBram Moolenaar  call writefile(lines, 'Xtest.vim')
3320fdd9435SBram Moolenaar
3330fdd9435SBram Moolenaar  " Start Vim in a terminal
3340fdd9435SBram Moolenaar  let buf = RunVimInTerminal('Xtest.vim', {})
3350fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
3360fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':4 | breakadd here')
3370fdd9435SBram Moolenaar  call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
3380fdd9435SBram Moolenaar  call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
339113bf067SBram Moolenaar  call RunDbgCmd(buf, 'cont')
340113bf067SBram Moolenaar
341113bf067SBram Moolenaar  call StopVimInTerminal(buf)
342113bf067SBram Moolenaar
343113bf067SBram Moolenaar  call delete('Xtest.vim')
34416c6232cSBram Moolenaar  %bw!
345072f1c68SBram Moolenaar
34616c6232cSBram Moolenaar  call assert_fails('breakadd here', 'E32:')
347531be47aSBram Moolenaar  call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
348113bf067SBram Moolenaarendfunc
3496ca6ca48SBram Moolenaar
350072f1c68SBram Moolenaardef Test_Debugger_breakadd_expr()
351072f1c68SBram Moolenaar  var lines =<< trim END
352072f1c68SBram Moolenaar      vim9script
353072f1c68SBram Moolenaar      func g:EarlyFunc()
354072f1c68SBram Moolenaar      endfunc
355072f1c68SBram Moolenaar      breakadd expr DoesNotExist()
356072f1c68SBram Moolenaar      func g:LaterFunc()
357072f1c68SBram Moolenaar      endfunc
358072f1c68SBram Moolenaar      breakdel *
359072f1c68SBram Moolenaar  END
360072f1c68SBram Moolenaar  writefile(lines, 'Xtest.vim')
361072f1c68SBram Moolenaar
362072f1c68SBram Moolenaar  # Start Vim in a terminal
363072f1c68SBram Moolenaar  var buf = RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
364072f1c68SBram Moolenaar  call TermWait(buf)
365072f1c68SBram Moolenaar
366072f1c68SBram Moolenaar  # Despite the failure the functions are defined
367072f1c68SBram Moolenaar  RunDbgCmd(buf, ':function g:EarlyFunc',
368072f1c68SBram Moolenaar     ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
369072f1c68SBram Moolenaar  RunDbgCmd(buf, ':function g:LaterFunc',
370072f1c68SBram Moolenaar     ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
371072f1c68SBram Moolenaar
372072f1c68SBram Moolenaar  call StopVimInTerminal(buf)
373072f1c68SBram Moolenaar  call delete('Xtest.vim')
374072f1c68SBram Moolenaarenddef
375072f1c68SBram Moolenaar
3766ca6ca48SBram Moolenaarfunc Test_Backtrace_Through_Source()
377b7f4fa51SBram Moolenaar  CheckCWD
3786ca6ca48SBram Moolenaar  let file1 =<< trim END
3796ca6ca48SBram Moolenaar    func SourceAnotherFile()
3806ca6ca48SBram Moolenaar      source Xtest2.vim
3816ca6ca48SBram Moolenaar    endfunc
3826ca6ca48SBram Moolenaar
3836ca6ca48SBram Moolenaar    func CallAFunction()
3846ca6ca48SBram Moolenaar      call SourceAnotherFile()
3856ca6ca48SBram Moolenaar      call File2Function()
3866ca6ca48SBram Moolenaar    endfunc
3876ca6ca48SBram Moolenaar
3886ca6ca48SBram Moolenaar    func GlobalFunction()
3896ca6ca48SBram Moolenaar      call CallAFunction()
3906ca6ca48SBram Moolenaar    endfunc
3916ca6ca48SBram Moolenaar  END
3926ca6ca48SBram Moolenaar  call writefile(file1, 'Xtest1.vim')
3936ca6ca48SBram Moolenaar
3946ca6ca48SBram Moolenaar  let file2 =<< trim END
3956ca6ca48SBram Moolenaar    func DoAThing()
3966ca6ca48SBram Moolenaar      echo "DoAThing"
3976ca6ca48SBram Moolenaar    endfunc
3986ca6ca48SBram Moolenaar
3996ca6ca48SBram Moolenaar    func File2Function()
4006ca6ca48SBram Moolenaar      call DoAThing()
4016ca6ca48SBram Moolenaar    endfunc
4026ca6ca48SBram Moolenaar
4036ca6ca48SBram Moolenaar    call File2Function()
4046ca6ca48SBram Moolenaar  END
4056ca6ca48SBram Moolenaar  call writefile(file2, 'Xtest2.vim')
4066ca6ca48SBram Moolenaar
4076ca6ca48SBram Moolenaar  let buf = RunVimInTerminal('-S Xtest1.vim', {})
4086ca6ca48SBram Moolenaar
4096ca6ca48SBram Moolenaar  call RunDbgCmd(buf,
4106ca6ca48SBram Moolenaar                \ ':debug call GlobalFunction()',
4116ca6ca48SBram Moolenaar                \ ['cmd: call GlobalFunction()'])
4126ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
4136ca6ca48SBram Moolenaar
4146ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', ['>backtrace',
4156ca6ca48SBram Moolenaar                                    \ '->0 function GlobalFunction',
4166ca6ca48SBram Moolenaar                                    \ 'line 1: call CallAFunction()'])
4176ca6ca48SBram Moolenaar
4186ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
4196ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
4206ca6ca48SBram Moolenaar
4216ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', ['>backtrace',
4226ca6ca48SBram Moolenaar                                    \ '  2 function GlobalFunction[1]',
4236ca6ca48SBram Moolenaar                                    \ '  1 CallAFunction[1]',
4246ca6ca48SBram Moolenaar                                    \ '->0 SourceAnotherFile',
4256ca6ca48SBram Moolenaar                                    \ 'line 1: source Xtest2.vim'])
4266ca6ca48SBram Moolenaar
4276ca6ca48SBram Moolenaar  " Step into the 'source' command. Note that we print the full trace all the
4286ca6ca48SBram Moolenaar  " way though the source command.
4296ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
4306ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
4316ca6ca48SBram Moolenaar        \ '>backtrace',
4326ca6ca48SBram Moolenaar        \ '  3 function GlobalFunction[1]',
4336ca6ca48SBram Moolenaar        \ '  2 CallAFunction[1]',
4346ca6ca48SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
4356ca6ca48SBram Moolenaar        \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
4366ca6ca48SBram Moolenaar        \ 'line 1: func DoAThing()'])
4376ca6ca48SBram Moolenaar
438b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'up' )
439b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
440b7f4fa51SBram Moolenaar        \ '>backtrace',
441b7f4fa51SBram Moolenaar        \ '  3 function GlobalFunction[1]',
442b7f4fa51SBram Moolenaar        \ '  2 CallAFunction[1]',
443b7f4fa51SBram Moolenaar        \ '->1 SourceAnotherFile[1]',
444b7f4fa51SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
445b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
446b7f4fa51SBram Moolenaar
447b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'up' )
448b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
449b7f4fa51SBram Moolenaar        \ '>backtrace',
450b7f4fa51SBram Moolenaar        \ '  3 function GlobalFunction[1]',
451b7f4fa51SBram Moolenaar        \ '->2 CallAFunction[1]',
452b7f4fa51SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
453b7f4fa51SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
454b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
455b7f4fa51SBram Moolenaar
456b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'up' )
457b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
458b7f4fa51SBram Moolenaar        \ '>backtrace',
459b7f4fa51SBram Moolenaar        \ '->3 function GlobalFunction[1]',
460b7f4fa51SBram Moolenaar        \ '  2 CallAFunction[1]',
461b7f4fa51SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
462b7f4fa51SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
463b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
464b7f4fa51SBram Moolenaar
465b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
466b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
467b7f4fa51SBram Moolenaar        \ '>backtrace',
468b7f4fa51SBram Moolenaar        \ '->3 function GlobalFunction[1]',
469b7f4fa51SBram Moolenaar        \ '  2 CallAFunction[1]',
470b7f4fa51SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
471b7f4fa51SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
472b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
473b7f4fa51SBram Moolenaar
474b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'down' )
475b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
476b7f4fa51SBram Moolenaar        \ '>backtrace',
477b7f4fa51SBram Moolenaar        \ '  3 function GlobalFunction[1]',
478b7f4fa51SBram Moolenaar        \ '->2 CallAFunction[1]',
479b7f4fa51SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
480b7f4fa51SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
481b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
482b7f4fa51SBram Moolenaar
483b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'down' )
484b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
485b7f4fa51SBram Moolenaar        \ '>backtrace',
486b7f4fa51SBram Moolenaar        \ '  3 function GlobalFunction[1]',
487b7f4fa51SBram Moolenaar        \ '  2 CallAFunction[1]',
488b7f4fa51SBram Moolenaar        \ '->1 SourceAnotherFile[1]',
489b7f4fa51SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
490b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
491b7f4fa51SBram Moolenaar
492b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'down' )
493b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
494b7f4fa51SBram Moolenaar        \ '>backtrace',
495b7f4fa51SBram Moolenaar        \ '  3 function GlobalFunction[1]',
496b7f4fa51SBram Moolenaar        \ '  2 CallAFunction[1]',
497b7f4fa51SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
498b7f4fa51SBram Moolenaar        \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
499b7f4fa51SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
500b7f4fa51SBram Moolenaar
501b7f4fa51SBram Moolenaar  call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
502b7f4fa51SBram Moolenaar
5036ca6ca48SBram Moolenaar  " step until we have another meaninfgul trace
5046ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
5056ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
5066ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
5076ca6ca48SBram Moolenaar        \ '>backtrace',
5086ca6ca48SBram Moolenaar        \ '  3 function GlobalFunction[1]',
5096ca6ca48SBram Moolenaar        \ '  2 CallAFunction[1]',
5106ca6ca48SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
5116ca6ca48SBram Moolenaar        \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
5126ca6ca48SBram Moolenaar        \ 'line 9: call File2Function()'])
5136ca6ca48SBram Moolenaar
5146ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
5156ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
5166ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
5176ca6ca48SBram Moolenaar        \ '>backtrace',
5186ca6ca48SBram Moolenaar        \ '  5 function GlobalFunction[1]',
5196ca6ca48SBram Moolenaar        \ '  4 CallAFunction[1]',
5206ca6ca48SBram Moolenaar        \ '  3 SourceAnotherFile[1]',
5216ca6ca48SBram Moolenaar        \ '  2 script ' .. getcwd() .. '/Xtest2.vim[9]',
5226ca6ca48SBram Moolenaar        \ '  1 function File2Function[1]',
5236ca6ca48SBram Moolenaar        \ '->0 DoAThing',
5246ca6ca48SBram Moolenaar        \ 'line 1: echo "DoAThing"'])
5256ca6ca48SBram Moolenaar
5266ca6ca48SBram Moolenaar  " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
5276ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: End of function'])
5286ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: End of function'])
5296ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
5306ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: End of function'])
5316ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
5326ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
5336ca6ca48SBram Moolenaar        \ '>backtrace',
5346ca6ca48SBram Moolenaar        \ '  1 function GlobalFunction[1]',
5356ca6ca48SBram Moolenaar        \ '->0 CallAFunction',
5366ca6ca48SBram Moolenaar        \ 'line 2: call File2Function()'])
5376ca6ca48SBram Moolenaar
5386ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
5396ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
5406ca6ca48SBram Moolenaar        \ '>backtrace',
5416ca6ca48SBram Moolenaar        \ '  2 function GlobalFunction[1]',
5426ca6ca48SBram Moolenaar        \ '  1 CallAFunction[2]',
5436ca6ca48SBram Moolenaar        \ '->0 File2Function',
5446ca6ca48SBram Moolenaar        \ 'line 1: call DoAThing()'])
5456ca6ca48SBram Moolenaar
5466ca6ca48SBram Moolenaar  call StopVimInTerminal(buf)
5476ca6ca48SBram Moolenaar  call delete('Xtest1.vim')
5486ca6ca48SBram Moolenaar  call delete('Xtest2.vim')
5496ca6ca48SBram Moolenaarendfunc
5506ca6ca48SBram Moolenaar
5516ca6ca48SBram Moolenaarfunc Test_Backtrace_Autocmd()
552b7f4fa51SBram Moolenaar  CheckCWD
5536ca6ca48SBram Moolenaar  let file1 =<< trim END
5546ca6ca48SBram Moolenaar    func SourceAnotherFile()
5556ca6ca48SBram Moolenaar      source Xtest2.vim
5566ca6ca48SBram Moolenaar    endfunc
5576ca6ca48SBram Moolenaar
5586ca6ca48SBram Moolenaar    func CallAFunction()
5596ca6ca48SBram Moolenaar      call SourceAnotherFile()
5606ca6ca48SBram Moolenaar      call File2Function()
5616ca6ca48SBram Moolenaar    endfunc
5626ca6ca48SBram Moolenaar
5636ca6ca48SBram Moolenaar    func GlobalFunction()
5646ca6ca48SBram Moolenaar      call CallAFunction()
5656ca6ca48SBram Moolenaar    endfunc
5666ca6ca48SBram Moolenaar
5676ca6ca48SBram Moolenaar    au User TestGlobalFunction :call GlobalFunction() | echo "Done"
5686ca6ca48SBram Moolenaar  END
5696ca6ca48SBram Moolenaar  call writefile(file1, 'Xtest1.vim')
5706ca6ca48SBram Moolenaar
5716ca6ca48SBram Moolenaar  let file2 =<< trim END
5726ca6ca48SBram Moolenaar    func DoAThing()
5736ca6ca48SBram Moolenaar      echo "DoAThing"
5746ca6ca48SBram Moolenaar    endfunc
5756ca6ca48SBram Moolenaar
5766ca6ca48SBram Moolenaar    func File2Function()
5776ca6ca48SBram Moolenaar      call DoAThing()
5786ca6ca48SBram Moolenaar    endfunc
5796ca6ca48SBram Moolenaar
5806ca6ca48SBram Moolenaar    call File2Function()
5816ca6ca48SBram Moolenaar  END
5826ca6ca48SBram Moolenaar  call writefile(file2, 'Xtest2.vim')
5836ca6ca48SBram Moolenaar
5846ca6ca48SBram Moolenaar  let buf = RunVimInTerminal('-S Xtest1.vim', {})
5856ca6ca48SBram Moolenaar
5866ca6ca48SBram Moolenaar  call RunDbgCmd(buf,
5876ca6ca48SBram Moolenaar                \ ':debug doautocmd User TestGlobalFunction',
5886ca6ca48SBram Moolenaar                \ ['cmd: doautocmd User TestGlobalFunction'])
5896ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
5906ca6ca48SBram Moolenaar
5916ca6ca48SBram Moolenaar  " At this point the ontly thing in the stack is the autocommand
5926ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
5936ca6ca48SBram Moolenaar        \ '>backtrace',
5946ca6ca48SBram Moolenaar        \ '->0 User Autocommands for "TestGlobalFunction"',
5956ca6ca48SBram Moolenaar        \ 'cmd: call GlobalFunction() | echo "Done"'])
5966ca6ca48SBram Moolenaar
5976ca6ca48SBram Moolenaar  " And now we're back into the call stack
5986ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
5996ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
6006ca6ca48SBram Moolenaar        \ '>backtrace',
6016ca6ca48SBram Moolenaar        \ '  1 User Autocommands for "TestGlobalFunction"',
6026ca6ca48SBram Moolenaar        \ '->0 function GlobalFunction',
6036ca6ca48SBram Moolenaar        \ 'line 1: call CallAFunction()'])
6046ca6ca48SBram Moolenaar
6056ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
6066ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
6076ca6ca48SBram Moolenaar
6086ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
6096ca6ca48SBram Moolenaar        \ '>backtrace',
6106ca6ca48SBram Moolenaar        \ '  3 User Autocommands for "TestGlobalFunction"',
6116ca6ca48SBram Moolenaar        \ '  2 function GlobalFunction[1]',
6126ca6ca48SBram Moolenaar        \ '  1 CallAFunction[1]',
6136ca6ca48SBram Moolenaar        \ '->0 SourceAnotherFile',
6146ca6ca48SBram Moolenaar        \ 'line 1: source Xtest2.vim'])
6156ca6ca48SBram Moolenaar
6166ca6ca48SBram Moolenaar  " Step into the 'source' command. Note that we print the full trace all the
6176ca6ca48SBram Moolenaar  " way though the source command.
6186ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
6196ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
6206ca6ca48SBram Moolenaar        \ '>backtrace',
6216ca6ca48SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
6226ca6ca48SBram Moolenaar        \ '  3 function GlobalFunction[1]',
6236ca6ca48SBram Moolenaar        \ '  2 CallAFunction[1]',
6246ca6ca48SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
6256ca6ca48SBram Moolenaar        \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
6266ca6ca48SBram Moolenaar        \ 'line 1: func DoAThing()'])
6276ca6ca48SBram Moolenaar
628c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'up' )
629c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
630c63b72b6SBram Moolenaar        \ '>backtrace',
631c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
632c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
633c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
634c63b72b6SBram Moolenaar        \ '->1 SourceAnotherFile[1]',
635c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
636c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
637c63b72b6SBram Moolenaar
638c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'up' )
639c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
640c63b72b6SBram Moolenaar        \ '>backtrace',
641c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
642c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
643c63b72b6SBram Moolenaar        \ '->2 CallAFunction[1]',
644c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
645c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
646c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
647c63b72b6SBram Moolenaar
648c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'up' )
649c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
650c63b72b6SBram Moolenaar        \ '>backtrace',
651c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
652c63b72b6SBram Moolenaar        \ '->3 function GlobalFunction[1]',
653c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
654c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
655c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
656c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
657c63b72b6SBram Moolenaar
658c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'up' )
659c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
660c63b72b6SBram Moolenaar        \ '>backtrace',
661c63b72b6SBram Moolenaar        \ '->4 User Autocommands for "TestGlobalFunction"',
662c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
663c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
664c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
665c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
666c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
667c63b72b6SBram Moolenaar
668c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
669c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
670c63b72b6SBram Moolenaar        \ '>backtrace',
671c63b72b6SBram Moolenaar        \ '->4 User Autocommands for "TestGlobalFunction"',
672c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
673c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
674c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
675c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
676c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
677c63b72b6SBram Moolenaar
678c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'down' )
679c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
680c63b72b6SBram Moolenaar        \ '>backtrace',
681c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
682c63b72b6SBram Moolenaar        \ '->3 function GlobalFunction[1]',
683c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
684c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
685c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
686c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
687c63b72b6SBram Moolenaar
688c63b72b6SBram Moolenaar
689c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'down' )
690c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
691c63b72b6SBram Moolenaar        \ '>backtrace',
692c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
693c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
694c63b72b6SBram Moolenaar        \ '->2 CallAFunction[1]',
695c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
696c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
697c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
698c63b72b6SBram Moolenaar
699c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'down' )
700c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
701c63b72b6SBram Moolenaar        \ '>backtrace',
702c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
703c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
704c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
705c63b72b6SBram Moolenaar        \ '->1 SourceAnotherFile[1]',
706c63b72b6SBram Moolenaar        \ '  0 script ' .. getcwd() .. '/Xtest2.vim',
707c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
708c63b72b6SBram Moolenaar
709c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'down' )
710c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'backtrace', [
711c63b72b6SBram Moolenaar        \ '>backtrace',
712c63b72b6SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
713c63b72b6SBram Moolenaar        \ '  3 function GlobalFunction[1]',
714c63b72b6SBram Moolenaar        \ '  2 CallAFunction[1]',
715c63b72b6SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
716c63b72b6SBram Moolenaar        \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
717c63b72b6SBram Moolenaar        \ 'line 1: func DoAThing()' ] )
718c63b72b6SBram Moolenaar
719c63b72b6SBram Moolenaar  call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
720c63b72b6SBram Moolenaar
7216ca6ca48SBram Moolenaar  " step until we have another meaninfgul trace
7226ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
7236ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
7246ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7256ca6ca48SBram Moolenaar        \ '>backtrace',
7266ca6ca48SBram Moolenaar        \ '  4 User Autocommands for "TestGlobalFunction"',
7276ca6ca48SBram Moolenaar        \ '  3 function GlobalFunction[1]',
7286ca6ca48SBram Moolenaar        \ '  2 CallAFunction[1]',
7296ca6ca48SBram Moolenaar        \ '  1 SourceAnotherFile[1]',
7306ca6ca48SBram Moolenaar        \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
7316ca6ca48SBram Moolenaar        \ 'line 9: call File2Function()'])
7326ca6ca48SBram Moolenaar
7336ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
7346ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
7356ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7366ca6ca48SBram Moolenaar        \ '>backtrace',
7376ca6ca48SBram Moolenaar        \ '  6 User Autocommands for "TestGlobalFunction"',
7386ca6ca48SBram Moolenaar        \ '  5 function GlobalFunction[1]',
7396ca6ca48SBram Moolenaar        \ '  4 CallAFunction[1]',
7406ca6ca48SBram Moolenaar        \ '  3 SourceAnotherFile[1]',
7416ca6ca48SBram Moolenaar        \ '  2 script ' .. getcwd() .. '/Xtest2.vim[9]',
7426ca6ca48SBram Moolenaar        \ '  1 function File2Function[1]',
7436ca6ca48SBram Moolenaar        \ '->0 DoAThing',
7446ca6ca48SBram Moolenaar        \ 'line 1: echo "DoAThing"'])
7456ca6ca48SBram Moolenaar
7466ca6ca48SBram Moolenaar  " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
7476ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: End of function'])
7486ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: End of function'])
7496ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
7506ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: End of function'])
7516ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
7526ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7536ca6ca48SBram Moolenaar        \ '>backtrace',
7546ca6ca48SBram Moolenaar        \ '  2 User Autocommands for "TestGlobalFunction"',
7556ca6ca48SBram Moolenaar        \ '  1 function GlobalFunction[1]',
7566ca6ca48SBram Moolenaar        \ '->0 CallAFunction',
7576ca6ca48SBram Moolenaar        \ 'line 2: call File2Function()'])
7586ca6ca48SBram Moolenaar
7596ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
7606ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7616ca6ca48SBram Moolenaar        \ '>backtrace',
7626ca6ca48SBram Moolenaar        \ '  3 User Autocommands for "TestGlobalFunction"',
7636ca6ca48SBram Moolenaar        \ '  2 function GlobalFunction[1]',
7646ca6ca48SBram Moolenaar        \ '  1 CallAFunction[2]',
7656ca6ca48SBram Moolenaar        \ '->0 File2Function',
7666ca6ca48SBram Moolenaar        \ 'line 1: call DoAThing()'])
7676ca6ca48SBram Moolenaar
7686ca6ca48SBram Moolenaar
7696ca6ca48SBram Moolenaar  " Now unwind so that we get back to the original autocommand (and the second
7706ca6ca48SBram Moolenaar  " cmd echo "Done")
7716ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
7726ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7736ca6ca48SBram Moolenaar        \ '>backtrace',
7746ca6ca48SBram Moolenaar        \ '  3 User Autocommands for "TestGlobalFunction"',
7756ca6ca48SBram Moolenaar        \ '  2 function GlobalFunction[1]',
7766ca6ca48SBram Moolenaar        \ '  1 CallAFunction[2]',
7776ca6ca48SBram Moolenaar        \ '->0 File2Function',
7786ca6ca48SBram Moolenaar        \ 'line 1: End of function'])
7796ca6ca48SBram Moolenaar
7806ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
7816ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7826ca6ca48SBram Moolenaar        \ '>backtrace',
7836ca6ca48SBram Moolenaar        \ '  2 User Autocommands for "TestGlobalFunction"',
7846ca6ca48SBram Moolenaar        \ '  1 function GlobalFunction[1]',
7856ca6ca48SBram Moolenaar        \ '->0 CallAFunction',
7866ca6ca48SBram Moolenaar        \ 'line 2: End of function'])
7876ca6ca48SBram Moolenaar
7886ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
7896ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7906ca6ca48SBram Moolenaar        \ '>backtrace',
7916ca6ca48SBram Moolenaar        \ '  1 User Autocommands for "TestGlobalFunction"',
7926ca6ca48SBram Moolenaar        \ '->0 function GlobalFunction',
7936ca6ca48SBram Moolenaar        \ 'line 1: End of function'])
7946ca6ca48SBram Moolenaar
7956ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
7966ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
7976ca6ca48SBram Moolenaar        \ '>backtrace',
7986ca6ca48SBram Moolenaar        \ '->0 User Autocommands for "TestGlobalFunction"',
7996ca6ca48SBram Moolenaar        \ 'cmd: echo "Done"'])
8006ca6ca48SBram Moolenaar
8016ca6ca48SBram Moolenaar  call StopVimInTerminal(buf)
8026ca6ca48SBram Moolenaar  call delete('Xtest1.vim')
8036ca6ca48SBram Moolenaar  call delete('Xtest2.vim')
8046ca6ca48SBram Moolenaarendfunc
8056ca6ca48SBram Moolenaar
8066ca6ca48SBram Moolenaarfunc Test_Backtrace_CmdLine()
807b7f4fa51SBram Moolenaar  CheckCWD
8086ca6ca48SBram Moolenaar  let file1 =<< trim END
8096ca6ca48SBram Moolenaar    func SourceAnotherFile()
8106ca6ca48SBram Moolenaar      source Xtest2.vim
8116ca6ca48SBram Moolenaar    endfunc
8126ca6ca48SBram Moolenaar
8136ca6ca48SBram Moolenaar    func CallAFunction()
8146ca6ca48SBram Moolenaar      call SourceAnotherFile()
8156ca6ca48SBram Moolenaar      call File2Function()
8166ca6ca48SBram Moolenaar    endfunc
8176ca6ca48SBram Moolenaar
8186ca6ca48SBram Moolenaar    func GlobalFunction()
8196ca6ca48SBram Moolenaar      call CallAFunction()
8206ca6ca48SBram Moolenaar    endfunc
8216ca6ca48SBram Moolenaar
8226ca6ca48SBram Moolenaar    au User TestGlobalFunction :call GlobalFunction() | echo "Done"
8236ca6ca48SBram Moolenaar  END
8246ca6ca48SBram Moolenaar  call writefile(file1, 'Xtest1.vim')
8256ca6ca48SBram Moolenaar
8266ca6ca48SBram Moolenaar  let file2 =<< trim END
8276ca6ca48SBram Moolenaar    func DoAThing()
8286ca6ca48SBram Moolenaar      echo "DoAThing"
8296ca6ca48SBram Moolenaar    endfunc
8306ca6ca48SBram Moolenaar
8316ca6ca48SBram Moolenaar    func File2Function()
8326ca6ca48SBram Moolenaar      call DoAThing()
8336ca6ca48SBram Moolenaar    endfunc
8346ca6ca48SBram Moolenaar
8356ca6ca48SBram Moolenaar    call File2Function()
8366ca6ca48SBram Moolenaar  END
8376ca6ca48SBram Moolenaar  call writefile(file2, 'Xtest2.vim')
8386ca6ca48SBram Moolenaar
8396ca6ca48SBram Moolenaar  let buf = RunVimInTerminal(
8406ca6ca48SBram Moolenaar        \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
8416ca6ca48SBram Moolenaar        \ {'wait_for_ruler': 0})
8426ca6ca48SBram Moolenaar
84318dc3553SBram Moolenaar  " Need to wait for the vim-in-terminal to be ready.
84418dc3553SBram Moolenaar  " With valgrind this can take quite long.
8456ca6ca48SBram Moolenaar  call CheckDbgOutput(buf, ['command line',
84618dc3553SBram Moolenaar                            \ 'cmd: call GlobalFunction()'], #{msec: 5000})
8476ca6ca48SBram Moolenaar
8486ca6ca48SBram Moolenaar  " At this point the ontly thing in the stack is the cmdline
8496ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
8506ca6ca48SBram Moolenaar        \ '>backtrace',
8516ca6ca48SBram Moolenaar        \ '->0 command line',
8526ca6ca48SBram Moolenaar        \ 'cmd: call GlobalFunction()'])
8536ca6ca48SBram Moolenaar
8546ca6ca48SBram Moolenaar  " And now we're back into the call stack
8556ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
8566ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
8576ca6ca48SBram Moolenaar        \ '>backtrace',
8586ca6ca48SBram Moolenaar        \ '  1 command line',
8596ca6ca48SBram Moolenaar        \ '->0 function GlobalFunction',
8606ca6ca48SBram Moolenaar        \ 'line 1: call CallAFunction()'])
8616ca6ca48SBram Moolenaar
8626ca6ca48SBram Moolenaar  call StopVimInTerminal(buf)
8636ca6ca48SBram Moolenaar  call delete('Xtest1.vim')
8646ca6ca48SBram Moolenaar  call delete('Xtest2.vim')
8656ca6ca48SBram Moolenaarendfunc
8666ca6ca48SBram Moolenaar
8676ca6ca48SBram Moolenaarfunc Test_Backtrace_DefFunction()
868b7f4fa51SBram Moolenaar  CheckCWD
8696ca6ca48SBram Moolenaar  let file1 =<< trim END
8706ca6ca48SBram Moolenaar    vim9script
8716ca6ca48SBram Moolenaar    import File2Function from './Xtest2.vim'
8726ca6ca48SBram Moolenaar
8736ca6ca48SBram Moolenaar    def SourceAnotherFile()
8746ca6ca48SBram Moolenaar      source Xtest2.vim
8756ca6ca48SBram Moolenaar    enddef
8766ca6ca48SBram Moolenaar
8776ca6ca48SBram Moolenaar    def CallAFunction()
8786ca6ca48SBram Moolenaar      SourceAnotherFile()
8796ca6ca48SBram Moolenaar      File2Function()
8806ca6ca48SBram Moolenaar    enddef
8816ca6ca48SBram Moolenaar
8826ca6ca48SBram Moolenaar    def g:GlobalFunction()
883b69c6fb7SBram Moolenaar      var some = "some var"
8846ca6ca48SBram Moolenaar      CallAFunction()
8856ca6ca48SBram Moolenaar    enddef
8866ca6ca48SBram Moolenaar
8876ca6ca48SBram Moolenaar    defcompile
8886ca6ca48SBram Moolenaar  END
8896ca6ca48SBram Moolenaar  call writefile(file1, 'Xtest1.vim')
8906ca6ca48SBram Moolenaar
8916ca6ca48SBram Moolenaar  let file2 =<< trim END
8926ca6ca48SBram Moolenaar    vim9script
8936ca6ca48SBram Moolenaar
8946ca6ca48SBram Moolenaar    def DoAThing(): number
8951bdae403SBram Moolenaar      var a = 100 * 2
8966ca6ca48SBram Moolenaar      a += 3
8976ca6ca48SBram Moolenaar      return a
8986ca6ca48SBram Moolenaar    enddef
8996ca6ca48SBram Moolenaar
9006ca6ca48SBram Moolenaar    export def File2Function()
9016ca6ca48SBram Moolenaar      DoAThing()
9026ca6ca48SBram Moolenaar    enddef
9036ca6ca48SBram Moolenaar
9046ca6ca48SBram Moolenaar    defcompile
9056ca6ca48SBram Moolenaar    File2Function()
9066ca6ca48SBram Moolenaar  END
9076ca6ca48SBram Moolenaar  call writefile(file2, 'Xtest2.vim')
9086ca6ca48SBram Moolenaar
9096ca6ca48SBram Moolenaar  let buf = RunVimInTerminal('-S Xtest1.vim', {})
9106ca6ca48SBram Moolenaar
9116ca6ca48SBram Moolenaar  call RunDbgCmd(buf,
9126ca6ca48SBram Moolenaar                \ ':debug call GlobalFunction()',
9136ca6ca48SBram Moolenaar                \ ['cmd: call GlobalFunction()'])
9146ca6ca48SBram Moolenaar
915b69c6fb7SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
916b69c6fb7SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
917b69c6fb7SBram Moolenaar  call RunDbgCmd(buf, 'echo some', ['some var'])
9186ca6ca48SBram Moolenaar
9196ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
9206ca6ca48SBram Moolenaar        \ '\V>backtrace',
921e99d422bSBram Moolenaar        \ '\V->0 function GlobalFunction',
922b69c6fb7SBram Moolenaar        \ '\Vline 2: CallAFunction()',
923e99d422bSBram Moolenaar        \ ],
9246ca6ca48SBram Moolenaar        \ #{match: 'pattern'})
9256ca6ca48SBram Moolenaar
926e99d422bSBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
927e99d422bSBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
928b69c6fb7SBram Moolenaar  " Repeated line, because we fist are in the compiled function before the
929b69c6fb7SBram Moolenaar  " EXEC and then in do_cmdline() before the :source command.
930e99d422bSBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
9316ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
9326ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
9336ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
9346ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
9356ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
9366ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
9376ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
9386ca6ca48SBram Moolenaar        \ '\V>backtrace',
939b69c6fb7SBram Moolenaar        \ '\V  3 function GlobalFunction[2]',
9406ca6ca48SBram Moolenaar        \ '\V  2 <SNR>\.\*_CallAFunction[1]',
9416ca6ca48SBram Moolenaar        \ '\V  1 <SNR>\.\*_SourceAnotherFile[1]',
9426ca6ca48SBram Moolenaar        \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
9436ca6ca48SBram Moolenaar        \ '\Vline 14: File2Function()'],
9446ca6ca48SBram Moolenaar        \ #{match: 'pattern'})
9456ca6ca48SBram Moolenaar
9466ca6ca48SBram Moolenaar  " Don't step into compiled functions...
947e99d422bSBram Moolenaar  call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
9486ca6ca48SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
9496ca6ca48SBram Moolenaar        \ '\V>backtrace',
950b69c6fb7SBram Moolenaar        \ '\V  3 function GlobalFunction[2]',
9516ca6ca48SBram Moolenaar        \ '\V  2 <SNR>\.\*_CallAFunction[1]',
9526ca6ca48SBram Moolenaar        \ '\V  1 <SNR>\.\*_SourceAnotherFile[1]',
9536ca6ca48SBram Moolenaar        \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
9546ca6ca48SBram Moolenaar        \ '\Vline 15: End of sourced file'],
9556ca6ca48SBram Moolenaar        \ #{match: 'pattern'})
9566ca6ca48SBram Moolenaar
9576ca6ca48SBram Moolenaar  call StopVimInTerminal(buf)
9586ca6ca48SBram Moolenaar  call delete('Xtest1.vim')
9596ca6ca48SBram Moolenaar  call delete('Xtest2.vim')
9606ca6ca48SBram Moolenaarendfunc
961b7f4fa51SBram Moolenaar
96226a4484dSBram Moolenaarfunc Test_DefFunction_expr()
96326a4484dSBram Moolenaar  CheckCWD
96426a4484dSBram Moolenaar  let file3 =<< trim END
96526a4484dSBram Moolenaar      vim9script
96626a4484dSBram Moolenaar      g:someVar = "foo"
96726a4484dSBram Moolenaar      def g:ChangeVar()
96826a4484dSBram Moolenaar        g:someVar = "bar"
96926a4484dSBram Moolenaar        echo "changed"
97026a4484dSBram Moolenaar      enddef
97126a4484dSBram Moolenaar      defcompile
97226a4484dSBram Moolenaar  END
97326a4484dSBram Moolenaar  call writefile(file3, 'Xtest3.vim')
97426a4484dSBram Moolenaar  let buf = RunVimInTerminal('-S Xtest3.vim', {})
97526a4484dSBram Moolenaar
97626a4484dSBram Moolenaar  call RunDbgCmd(buf, ':breakadd expr g:someVar')
97726a4484dSBram Moolenaar  call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
97826a4484dSBram Moolenaar
97926a4484dSBram Moolenaar  call StopVimInTerminal(buf)
98026a4484dSBram Moolenaar  call delete('Xtest3.vim')
98126a4484dSBram Moolenaarendfunc
98226a4484dSBram Moolenaar
98317d868b8SBram Moolenaarfunc Test_debug_def_and_legacy_function()
9844f8f5428SBram Moolenaar  CheckCWD
9854f8f5428SBram Moolenaar  let file =<< trim END
9864f8f5428SBram Moolenaar    vim9script
9874f8f5428SBram Moolenaar    def g:SomeFunc()
9884f8f5428SBram Moolenaar      echo "here"
9894f8f5428SBram Moolenaar      echo "and"
9904f8f5428SBram Moolenaar      echo "there"
9912ac4b253SBram Moolenaar      breakadd func 2 LocalFunc
9922ac4b253SBram Moolenaar      LocalFunc()
9934f8f5428SBram Moolenaar    enddef
9942ac4b253SBram Moolenaar
9952ac4b253SBram Moolenaar    def LocalFunc()
9962ac4b253SBram Moolenaar      echo "first"
9972ac4b253SBram Moolenaar      echo "second"
9988cec9273SBram Moolenaar      breakadd func LegacyFunc
9992ac4b253SBram Moolenaar      LegacyFunc()
10002ac4b253SBram Moolenaar    enddef
10012ac4b253SBram Moolenaar
10022ac4b253SBram Moolenaar    func LegacyFunc()
10032ac4b253SBram Moolenaar      echo "legone"
10042ac4b253SBram Moolenaar      echo "legtwo"
10052ac4b253SBram Moolenaar    endfunc
10062ac4b253SBram Moolenaar
10074f8f5428SBram Moolenaar    breakadd func 2 g:SomeFunc
10084f8f5428SBram Moolenaar  END
10094f8f5428SBram Moolenaar  call writefile(file, 'XtestDebug.vim')
10104f8f5428SBram Moolenaar
10114f8f5428SBram Moolenaar  let buf = RunVimInTerminal('-S XtestDebug.vim', {})
10124f8f5428SBram Moolenaar
10134f8f5428SBram Moolenaar  call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
10144f8f5428SBram Moolenaar  call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
10152ac4b253SBram Moolenaar  call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
10162ac4b253SBram Moolenaar
10172ac4b253SBram Moolenaar  " continue, next breakpoint is in LocalFunc()
10182ac4b253SBram Moolenaar  call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
10192ac4b253SBram Moolenaar
10202ac4b253SBram Moolenaar  " continue, next breakpoint is in LegacyFunc()
10212ac4b253SBram Moolenaar  call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
10224f8f5428SBram Moolenaar
10234f8f5428SBram Moolenaar  call RunDbgCmd(buf, 'cont')
10244f8f5428SBram Moolenaar
10254f8f5428SBram Moolenaar  call StopVimInTerminal(buf)
10266c72fd51SDominique Pelle  call delete('XtestDebug.vim')
10274f8f5428SBram Moolenaarendfunc
10284f8f5428SBram Moolenaar
1029968a5b62SBram Moolenaarfunc Test_debug_def_function()
1030968a5b62SBram Moolenaar  CheckCWD
1031968a5b62SBram Moolenaar  let file =<< trim END
1032968a5b62SBram Moolenaar    vim9script
1033968a5b62SBram Moolenaar    def g:Func()
1034968a5b62SBram Moolenaar      var n: number
1035968a5b62SBram Moolenaar      def Closure(): number
1036968a5b62SBram Moolenaar          return n + 3
1037968a5b62SBram Moolenaar      enddef
1038968a5b62SBram Moolenaar      n += Closure()
1039968a5b62SBram Moolenaar      echo 'result: ' .. n
1040968a5b62SBram Moolenaar    enddef
10416bc30b05SBram Moolenaar
10426bc30b05SBram Moolenaar    def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
10436bc30b05SBram Moolenaar      echo text .. nr
10446bc30b05SBram Moolenaar      for it in items
10456bc30b05SBram Moolenaar        echo it
10466bc30b05SBram Moolenaar      endfor
10476bc30b05SBram Moolenaar      echo "done"
10486bc30b05SBram Moolenaar    enddef
10494cea536bSBram Moolenaar
10504cea536bSBram Moolenaar    def g:FuncWithDict()
10514cea536bSBram Moolenaar      var d = {
10524cea536bSBram Moolenaar         a: 1,
10534cea536bSBram Moolenaar         b: 2,
10544cea536bSBram Moolenaar         }
105559b50c3bSBram Moolenaar         # comment
105659b50c3bSBram Moolenaar         def Inner()
105731e21766SBram Moolenaar           eval 1 + 2
105859b50c3bSBram Moolenaar         enddef
10594cea536bSBram Moolenaar    enddef
1060303215d6SBram Moolenaar
10618cec9273SBram Moolenaar    def g:FuncComment()
10628cec9273SBram Moolenaar      # comment
10638cec9273SBram Moolenaar      echo "first"
10648cec9273SBram Moolenaar         .. "one"
10658cec9273SBram Moolenaar      # comment
10668cec9273SBram Moolenaar      echo "second"
10678cec9273SBram Moolenaar    enddef
1068303215d6SBram Moolenaar
10696fc01616SBram Moolenaar    def g:FuncForLoop()
107031e21766SBram Moolenaar      eval 1 + 2
10716fc01616SBram Moolenaar      for i in [11, 22, 33]
107231e21766SBram Moolenaar        eval i + 2
10736fc01616SBram Moolenaar      endfor
10746fc01616SBram Moolenaar      echo "done"
10756fc01616SBram Moolenaar    enddef
1076303215d6SBram Moolenaar
1077303215d6SBram Moolenaar    def g:FuncWithSplitLine()
107831e21766SBram Moolenaar        eval 1 + 2
107931e21766SBram Moolenaar           | eval 2 + 3
1080303215d6SBram Moolenaar    enddef
1081968a5b62SBram Moolenaar  END
1082968a5b62SBram Moolenaar  call writefile(file, 'Xtest.vim')
1083968a5b62SBram Moolenaar
1084968a5b62SBram Moolenaar  let buf = RunVimInTerminal('-S Xtest.vim', {})
1085968a5b62SBram Moolenaar
1086968a5b62SBram Moolenaar  call RunDbgCmd(buf,
1087968a5b62SBram Moolenaar                \ ':debug call Func()',
1088968a5b62SBram Moolenaar                \ ['cmd: call Func()'])
1089968a5b62SBram Moolenaar  call RunDbgCmd(buf, 'next', ['result: 3'])
1090968a5b62SBram Moolenaar  call term_sendkeys(buf, "\r")
10916bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'cont')
1092968a5b62SBram Moolenaar
10936bc30b05SBram Moolenaar  call RunDbgCmd(buf,
10946bc30b05SBram Moolenaar                \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
10956bc30b05SBram Moolenaar                \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
10966bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
10976bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'echo text', ['asdf'])
10986bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'echo nr', ['42'])
10996bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
11006bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
11016bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'echo it', ['1'])
11026bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 3: echo it'])
11036bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
11046bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
11056bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'echo it', ['2'])
11066bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 3: echo it'])
11076bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
11086bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
11096bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'echo it', ['3'])
11106bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 3: echo it'])
11116bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
11126bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
11134cea536bSBram Moolenaar  call RunDbgCmd(buf, 'cont')
11144cea536bSBram Moolenaar
11154cea536bSBram Moolenaar  call RunDbgCmd(buf,
11164cea536bSBram Moolenaar                \ ':debug call FuncWithDict()',
11174cea536bSBram Moolenaar                \ ['cmd: call FuncWithDict()'])
11184cea536bSBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 1: var d = {  a: 1,  b: 2,  }'])
111959b50c3bSBram Moolenaar  call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
11208cec9273SBram Moolenaar  call RunDbgCmd(buf, 'cont')
11218cec9273SBram Moolenaar
11228cec9273SBram Moolenaar  call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
11238cec9273SBram Moolenaar  call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first"  .. "one"'])
11248cec9273SBram Moolenaar  call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
11258cec9273SBram Moolenaar  call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
11266fc01616SBram Moolenaar  call RunDbgCmd(buf, 'cont')
11276fc01616SBram Moolenaar
11286fc01616SBram Moolenaar  call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
11296fc01616SBram Moolenaar  call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
11306fc01616SBram Moolenaar  call RunDbgCmd(buf, 'echo i', ['11'])
113131e21766SBram Moolenaar  call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
11326fc01616SBram Moolenaar  call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
11336fc01616SBram Moolenaar  call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
11346fc01616SBram Moolenaar  call RunDbgCmd(buf, 'echo i', ['22'])
11356bc30b05SBram Moolenaar
1136303215d6SBram Moolenaar  call RunDbgCmd(buf, 'breakdel *')
1137303215d6SBram Moolenaar  call RunDbgCmd(buf, 'cont')
1138303215d6SBram Moolenaar
1139303215d6SBram Moolenaar  call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
114031e21766SBram Moolenaar  call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
1141303215d6SBram Moolenaar
11426bc30b05SBram Moolenaar  call RunDbgCmd(buf, 'cont')
1143968a5b62SBram Moolenaar  call StopVimInTerminal(buf)
1144968a5b62SBram Moolenaar  call delete('Xtest.vim')
1145968a5b62SBram Moolenaarendfunc
1146968a5b62SBram Moolenaar
114717d868b8SBram Moolenaarfunc Test_debug_def_function_with_lambda()
114817d868b8SBram Moolenaar  CheckCWD
114917d868b8SBram Moolenaar  let lines =<< trim END
115017d868b8SBram Moolenaar     vim9script
115117d868b8SBram Moolenaar     def g:Func()
115217d868b8SBram Moolenaar       var s = 'a'
115317d868b8SBram Moolenaar       ['b']->map((_, v) => s)
115417d868b8SBram Moolenaar       echo "done"
115517d868b8SBram Moolenaar     enddef
115617d868b8SBram Moolenaar     breakadd func 2 g:Func
115717d868b8SBram Moolenaar  END
115817d868b8SBram Moolenaar  call writefile(lines, 'XtestLambda.vim')
115917d868b8SBram Moolenaar
116017d868b8SBram Moolenaar  let buf = RunVimInTerminal('-S XtestLambda.vim', {})
116117d868b8SBram Moolenaar
116217d868b8SBram Moolenaar  call RunDbgCmd(buf,
116317d868b8SBram Moolenaar                \ ':call g:Func()',
116417d868b8SBram Moolenaar                \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
116517d868b8SBram Moolenaar  call RunDbgCmd(buf,
116617d868b8SBram Moolenaar                \ 'next',
116717d868b8SBram Moolenaar                \ ['function Func', 'line 3: echo "done"'])
116817d868b8SBram Moolenaar
116917d868b8SBram Moolenaar  call RunDbgCmd(buf, 'cont')
117017d868b8SBram Moolenaar  call StopVimInTerminal(buf)
117117d868b8SBram Moolenaar  call delete('XtestLambda.vim')
117217d868b8SBram Moolenaarendfunc
117317d868b8SBram Moolenaar
1174b7f4fa51SBram Moolenaarfunc Test_debug_backtrace_level()
1175b7f4fa51SBram Moolenaar  CheckCWD
1176b7f4fa51SBram Moolenaar  let lines =<< trim END
1177b7f4fa51SBram Moolenaar    let s:file1_var = 'file1'
1178b7f4fa51SBram Moolenaar    let g:global_var = 'global'
1179b7f4fa51SBram Moolenaar
1180b7f4fa51SBram Moolenaar    func s:File1Func( arg )
1181b7f4fa51SBram Moolenaar      let s:file1_var .= a:arg
1182b7f4fa51SBram Moolenaar      let local_var = s:file1_var .. ' test1'
1183b7f4fa51SBram Moolenaar      let g:global_var .= local_var
1184b7f4fa51SBram Moolenaar      source Xtest2.vim
1185b7f4fa51SBram Moolenaar    endfunc
1186b7f4fa51SBram Moolenaar
1187b7f4fa51SBram Moolenaar    call s:File1Func( 'arg1' )
1188b7f4fa51SBram Moolenaar  END
1189b7f4fa51SBram Moolenaar  call writefile(lines, 'Xtest1.vim')
1190b7f4fa51SBram Moolenaar
1191b7f4fa51SBram Moolenaar  let lines =<< trim END
1192b7f4fa51SBram Moolenaar    let s:file2_var = 'file2'
1193b7f4fa51SBram Moolenaar
1194b7f4fa51SBram Moolenaar    func s:File2Func( arg )
1195b7f4fa51SBram Moolenaar      let s:file2_var .= a:arg
1196b7f4fa51SBram Moolenaar      let local_var = s:file2_var .. ' test2'
1197b7f4fa51SBram Moolenaar      let g:global_var .= local_var
1198b7f4fa51SBram Moolenaar    endfunc
1199b7f4fa51SBram Moolenaar
1200b7f4fa51SBram Moolenaar    call s:File2Func( 'arg2' )
1201b7f4fa51SBram Moolenaar  END
1202b7f4fa51SBram Moolenaar  call writefile(lines, 'Xtest2.vim')
1203b7f4fa51SBram Moolenaar
1204b7f4fa51SBram Moolenaar  let file1 = getcwd() .. '/Xtest1.vim'
1205b7f4fa51SBram Moolenaar  let file2 = getcwd() .. '/Xtest2.vim'
1206b7f4fa51SBram Moolenaar
1207b7f4fa51SBram Moolenaar  " set a breakpoint and source file1.vim
1208b7f4fa51SBram Moolenaar  let buf = RunVimInTerminal(
1209b7f4fa51SBram Moolenaar        \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
1210b7f4fa51SBram Moolenaar        \ #{wait_for_ruler: 0})
1211b7f4fa51SBram Moolenaar
1212b7f4fa51SBram Moolenaar  call CheckDbgOutput(buf, [
1213b7f4fa51SBram Moolenaar        \ 'Breakpoint in "' .. file1 .. '" line 1',
1214b7f4fa51SBram Moolenaar        \ 'Entering Debug mode.  Type "cont" to continue.',
1215b7f4fa51SBram Moolenaar        \ 'command line..script ' .. file1,
1216b7f4fa51SBram Moolenaar        \ 'line 1: let s:file1_var = ''file1'''
121718dc3553SBram Moolenaar        \ ], #{msec: 5000})
1218b7f4fa51SBram Moolenaar
12198e7d6223SBram Moolenaar  " step through the initial declarations
1220b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1221b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1222b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1223b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1224b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1225b7f4fa51SBram Moolenaar
1226b7f4fa51SBram Moolenaar  " step in to the first function
1227b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1228b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1229b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1230b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1231b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1232b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1233b7f4fa51SBram Moolenaar                \'echo global_var',
1234b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: global_var' ] )
1235b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1236b7f4fa51SBram Moolenaar                \'echo local_var',
1237b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: local_var' ] )
1238b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1239b7f4fa51SBram Moolenaar                \'echo l:local_var',
1240b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: l:local_var' ] )
1241b7f4fa51SBram Moolenaar
1242b7f4fa51SBram Moolenaar  " backtrace up
1243b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
1244b7f4fa51SBram Moolenaar        \ '\V>backtrace',
1245b7f4fa51SBram Moolenaar        \ '\V  2 command line',
1246b7f4fa51SBram Moolenaar        \ '\V  1 script ' .. file1 .. '[11]',
1247b7f4fa51SBram Moolenaar        \ '\V->0 function <SNR>\.\*_File1Func',
1248b7f4fa51SBram Moolenaar        \ '\Vline 1: let s:file1_var .= a:arg',
1249b7f4fa51SBram Moolenaar        \ ],
1250b7f4fa51SBram Moolenaar        \ #{ match: 'pattern' } )
1251b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'up', [ '>up' ] )
1252b7f4fa51SBram Moolenaar
1253b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
1254b7f4fa51SBram Moolenaar        \ '\V>backtrace',
1255b7f4fa51SBram Moolenaar        \ '\V  2 command line',
1256b7f4fa51SBram Moolenaar        \ '\V->1 script ' .. file1 .. '[11]',
1257b7f4fa51SBram Moolenaar        \ '\V  0 function <SNR>\.\*_File1Func',
1258b7f4fa51SBram Moolenaar        \ '\Vline 1: let s:file1_var .= a:arg',
1259b7f4fa51SBram Moolenaar        \ ],
1260b7f4fa51SBram Moolenaar        \ #{ match: 'pattern' } )
1261b7f4fa51SBram Moolenaar
1262b7f4fa51SBram Moolenaar  " Expression evaluation in the script frame (not the function frame)
1263b7f4fa51SBram Moolenaar  " FIXME: Unexpected in this scope (a: should not be visibnle)
1264b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1265b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1266b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1267b7f4fa51SBram Moolenaar  " FIXME: Unexpected in this scope (global should be found)
1268b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1269b7f4fa51SBram Moolenaar                \'echo global_var',
1270b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: global_var' ] )
1271b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1272b7f4fa51SBram Moolenaar                \'echo local_var',
1273b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: local_var' ] )
1274b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1275b7f4fa51SBram Moolenaar                \'echo l:local_var',
1276b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: l:local_var' ] )
1277b7f4fa51SBram Moolenaar
1278b7f4fa51SBram Moolenaar
1279b7f4fa51SBram Moolenaar  " step while backtraced jumps to the latest frame
1280b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [
1281b7f4fa51SBram Moolenaar        \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1282b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
1283b7f4fa51SBram Moolenaar        \ '\V>backtrace',
1284b7f4fa51SBram Moolenaar        \ '\V  2 command line',
1285b7f4fa51SBram Moolenaar        \ '\V  1 script ' .. file1 .. '[11]',
1286b7f4fa51SBram Moolenaar        \ '\V->0 function <SNR>\.\*_File1Func',
1287b7f4fa51SBram Moolenaar        \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1288b7f4fa51SBram Moolenaar        \ ],
1289b7f4fa51SBram Moolenaar        \ #{ match: 'pattern' } )
1290b7f4fa51SBram Moolenaar
1291b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1292b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1293b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1294b7f4fa51SBram Moolenaar
1295b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1296b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1297b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
1298b7f4fa51SBram Moolenaar        \ '\V>backtrace',
1299b7f4fa51SBram Moolenaar        \ '\V  3 command line',
1300b7f4fa51SBram Moolenaar        \ '\V  2 script ' .. file1 .. '[11]',
1301b7f4fa51SBram Moolenaar        \ '\V  1 function <SNR>\.\*_File1Func[4]',
1302b7f4fa51SBram Moolenaar        \ '\V->0 script ' .. file2,
1303b7f4fa51SBram Moolenaar        \ '\Vline 1: let s:file2_var = ''file2''',
1304b7f4fa51SBram Moolenaar        \ ],
1305b7f4fa51SBram Moolenaar        \ #{ match: 'pattern' } )
1306b7f4fa51SBram Moolenaar
1307b7f4fa51SBram Moolenaar  " Expression evaluation in the script frame file2 (not the function frame)
1308b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1309b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1310b7f4fa51SBram Moolenaar        \ 'echo s:file1_var',
1311b7f4fa51SBram Moolenaar        \ [ 'E121: Undefined variable: s:file1_var' ] )
1312b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1313b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1314b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1315b7f4fa51SBram Moolenaar                \'echo local_var',
1316b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: local_var' ] )
1317b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1318b7f4fa51SBram Moolenaar                \'echo l:local_var',
1319b7f4fa51SBram Moolenaar                \[ 'E121: Undefined variable: l:local_var' ] )
1320b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1321b7f4fa51SBram Moolenaar        \ 'echo s:file2_var',
1322b7f4fa51SBram Moolenaar        \ [ 'E121: Undefined variable: s:file2_var' ] )
1323b7f4fa51SBram Moolenaar
1324b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1325b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1326b7f4fa51SBram Moolenaar
1327b7f4fa51SBram Moolenaar  " Up the stack to the other script context
1328b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'up')
1329b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
1330b7f4fa51SBram Moolenaar        \ '\V>backtrace',
1331b7f4fa51SBram Moolenaar        \ '\V  3 command line',
1332b7f4fa51SBram Moolenaar        \ '\V  2 script ' .. file1 .. '[11]',
1333b7f4fa51SBram Moolenaar        \ '\V->1 function <SNR>\.\*_File1Func[4]',
1334b7f4fa51SBram Moolenaar        \ '\V  0 script ' .. file2,
1335b7f4fa51SBram Moolenaar        \ '\Vline 3: func s:File2Func( arg )',
1336b7f4fa51SBram Moolenaar        \ ],
1337b7f4fa51SBram Moolenaar        \ #{ match: 'pattern' } )
1338b7f4fa51SBram Moolenaar  " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1339b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1340b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1341b7f4fa51SBram Moolenaar        \ 'echo l:local_var',
1342b7f4fa51SBram Moolenaar        \ [ 'E121: Undefined variable: l:local_var' ] )
1343b7f4fa51SBram Moolenaar
1344b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'up')
1345b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'backtrace', [
1346b7f4fa51SBram Moolenaar        \ '\V>backtrace',
1347b7f4fa51SBram Moolenaar        \ '\V  3 command line',
1348b7f4fa51SBram Moolenaar        \ '\V->2 script ' .. file1 .. '[11]',
1349b7f4fa51SBram Moolenaar        \ '\V  1 function <SNR>\.\*_File1Func[4]',
1350b7f4fa51SBram Moolenaar        \ '\V  0 script ' .. file2,
1351b7f4fa51SBram Moolenaar        \ '\Vline 3: func s:File2Func( arg )',
1352b7f4fa51SBram Moolenaar        \ ],
1353b7f4fa51SBram Moolenaar        \ #{ match: 'pattern' } )
1354b7f4fa51SBram Moolenaar
1355b7f4fa51SBram Moolenaar  " FIXME: Unexpected (wrong script vars are used)
1356b7f4fa51SBram Moolenaar  call RunDbgCmd(buf,
1357b7f4fa51SBram Moolenaar        \ 'echo s:file1_var',
1358b7f4fa51SBram Moolenaar        \ [ 'E121: Undefined variable: s:file1_var' ] )
1359b7f4fa51SBram Moolenaar  call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1360b7f4fa51SBram Moolenaar
1361e99d422bSBram Moolenaar  call RunDbgCmd(buf, 'cont')
1362b7f4fa51SBram Moolenaar  call StopVimInTerminal(buf)
1363b7f4fa51SBram Moolenaar  call delete('Xtest1.vim')
1364b7f4fa51SBram Moolenaar  call delete('Xtest2.vim')
1365b7f4fa51SBram Moolenaarendfunc
13666d91bcb4SBram Moolenaar
13677ac616cbSBram Moolenaar" Test for setting a breakpoint on a :endif where the :if condition is false
13687ac616cbSBram Moolenaar" and then quit the script. This should generate an interrupt.
13697ac616cbSBram Moolenaarfunc Test_breakpt_endif_intr()
13707ac616cbSBram Moolenaar  func F()
13717ac616cbSBram Moolenaar    let g:Xpath ..= 'a'
13727ac616cbSBram Moolenaar    if v:false
13737ac616cbSBram Moolenaar      let g:Xpath ..= 'b'
13747ac616cbSBram Moolenaar    endif
13757ac616cbSBram Moolenaar    invalid_command
13767ac616cbSBram Moolenaar  endfunc
13777ac616cbSBram Moolenaar
13787ac616cbSBram Moolenaar  let g:Xpath = ''
13797ac616cbSBram Moolenaar  breakadd func 4 F
13807ac616cbSBram Moolenaar  try
13817ac616cbSBram Moolenaar    let caught_intr = 0
13827ac616cbSBram Moolenaar    debuggreedy
13837ac616cbSBram Moolenaar    call feedkeys(":call F()\<CR>quit\<CR>", "xt")
13847ac616cbSBram Moolenaar  catch /^Vim:Interrupt$/
13857ac616cbSBram Moolenaar    call assert_match('\.F, line 4', v:throwpoint)
13867ac616cbSBram Moolenaar    let caught_intr = 1
13877ac616cbSBram Moolenaar  endtry
13887ac616cbSBram Moolenaar  0debuggreedy
13897ac616cbSBram Moolenaar  call assert_equal(1, caught_intr)
13907ac616cbSBram Moolenaar  call assert_equal('a', g:Xpath)
13917ac616cbSBram Moolenaar  breakdel *
13927ac616cbSBram Moolenaar  delfunc F
13937ac616cbSBram Moolenaarendfunc
13947ac616cbSBram Moolenaar
13957ac616cbSBram Moolenaar" Test for setting a breakpoint on a :else where the :if condition is false
13967ac616cbSBram Moolenaar" and then quit the script. This should generate an interrupt.
13977ac616cbSBram Moolenaarfunc Test_breakpt_else_intr()
13987ac616cbSBram Moolenaar  func F()
13997ac616cbSBram Moolenaar    let g:Xpath ..= 'a'
14007ac616cbSBram Moolenaar    if v:false
14017ac616cbSBram Moolenaar      let g:Xpath ..= 'b'
14027ac616cbSBram Moolenaar    else
14037ac616cbSBram Moolenaar      invalid_command
14047ac616cbSBram Moolenaar    endif
14057ac616cbSBram Moolenaar    invalid_command
14067ac616cbSBram Moolenaar  endfunc
14077ac616cbSBram Moolenaar
14087ac616cbSBram Moolenaar  let g:Xpath = ''
14097ac616cbSBram Moolenaar  breakadd func 4 F
14107ac616cbSBram Moolenaar  try
14117ac616cbSBram Moolenaar    let caught_intr = 0
14127ac616cbSBram Moolenaar    debuggreedy
14137ac616cbSBram Moolenaar    call feedkeys(":call F()\<CR>quit\<CR>", "xt")
14147ac616cbSBram Moolenaar  catch /^Vim:Interrupt$/
14157ac616cbSBram Moolenaar    call assert_match('\.F, line 4', v:throwpoint)
14167ac616cbSBram Moolenaar    let caught_intr = 1
14177ac616cbSBram Moolenaar  endtry
14187ac616cbSBram Moolenaar  0debuggreedy
14197ac616cbSBram Moolenaar  call assert_equal(1, caught_intr)
14207ac616cbSBram Moolenaar  call assert_equal('a', g:Xpath)
14217ac616cbSBram Moolenaar  breakdel *
14227ac616cbSBram Moolenaar  delfunc F
14237ac616cbSBram Moolenaarendfunc
14247ac616cbSBram Moolenaar
14257ac616cbSBram Moolenaar" Test for setting a breakpoint on a :endwhile where the :while condition is
14267ac616cbSBram Moolenaar" false and then quit the script. This should generate an interrupt.
14277ac616cbSBram Moolenaarfunc Test_breakpt_endwhile_intr()
14287ac616cbSBram Moolenaar  func F()
14297ac616cbSBram Moolenaar    let g:Xpath ..= 'a'
14307ac616cbSBram Moolenaar    while v:false
14317ac616cbSBram Moolenaar      let g:Xpath ..= 'b'
14327ac616cbSBram Moolenaar    endwhile
14337ac616cbSBram Moolenaar    invalid_command
14347ac616cbSBram Moolenaar  endfunc
14357ac616cbSBram Moolenaar
14367ac616cbSBram Moolenaar  let g:Xpath = ''
14377ac616cbSBram Moolenaar  breakadd func 4 F
14387ac616cbSBram Moolenaar  try
14397ac616cbSBram Moolenaar    let caught_intr = 0
14407ac616cbSBram Moolenaar    debuggreedy
14417ac616cbSBram Moolenaar    call feedkeys(":call F()\<CR>quit\<CR>", "xt")
14427ac616cbSBram Moolenaar  catch /^Vim:Interrupt$/
14437ac616cbSBram Moolenaar    call assert_match('\.F, line 4', v:throwpoint)
14447ac616cbSBram Moolenaar    let caught_intr = 1
14457ac616cbSBram Moolenaar  endtry
14467ac616cbSBram Moolenaar  0debuggreedy
14477ac616cbSBram Moolenaar  call assert_equal(1, caught_intr)
14487ac616cbSBram Moolenaar  call assert_equal('a', g:Xpath)
14497ac616cbSBram Moolenaar  breakdel *
14507ac616cbSBram Moolenaar  delfunc F
14517ac616cbSBram Moolenaarendfunc
14527ac616cbSBram Moolenaar
145316c6232cSBram Moolenaar" Test for setting a breakpoint on a script local function
145416c6232cSBram Moolenaarfunc Test_breakpt_scriptlocal_func()
14557ac616cbSBram Moolenaar  let g:Xpath = ''
145616c6232cSBram Moolenaar  func s:G()
145716c6232cSBram Moolenaar    let g:Xpath ..= 'a'
145816c6232cSBram Moolenaar  endfunc
145916c6232cSBram Moolenaar
146016c6232cSBram Moolenaar  let funcname = expand("<SID>") .. "G"
146116c6232cSBram Moolenaar  exe "breakadd func 1 " .. funcname
14627ac616cbSBram Moolenaar  debuggreedy
146316c6232cSBram Moolenaar  redir => output
146416c6232cSBram Moolenaar  call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
146516c6232cSBram Moolenaar  redir END
14667ac616cbSBram Moolenaar  0debuggreedy
146716c6232cSBram Moolenaar  call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
14687ac616cbSBram Moolenaar  call assert_equal('a', g:Xpath)
14697ac616cbSBram Moolenaar  breakdel *
147016c6232cSBram Moolenaar  exe "delfunc " .. funcname
14717ac616cbSBram Moolenaarendfunc
14727ac616cbSBram Moolenaar
14736d91bcb4SBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
1474