summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-12-09 15:53:01 +0100
committerBram Moolenaar <Bram@vim.org>2018-12-09 15:53:01 +0100
commit37402ed53475166cd988edbea1269fa4e9918dc4 (patch)
tree44f846cd5fb8f62237879832e22fbc57552529d4
parent4af7259b2b35e85c590d54908fcd248d2c733be8 (diff)
downloadvim-git-37402ed53475166cd988edbea1269fa4e9918dc4.tar.gz
patch 8.1.0575: Termdebug: clearing multi-breakpoint does not workv8.1.0575
Problem: Termdebug: clearing multi-breakpoint does not work. Solution: Delete all X.Y breakpoints. Keep more information about placed breakpoints. (Ozaki Kiichi, closes #3641)
-rw-r--r--runtime/pack/dist/opt/termdebug/plugin/termdebug.vim140
-rw-r--r--src/version.c2
2 files changed, 94 insertions, 48 deletions
diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
index 61de9a34b..df89abd7a 100644
--- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
+++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim
@@ -74,10 +74,10 @@ let s:break_id = 13 " breakpoint number is added to this
let s:stopped = 1
" Take a breakpoint number as used by GDB and turn it into an integer.
-" The breakpoint may contain a dot: 123.4
-func s:Breakpoint2SignNumber(nr)
- let t = split(a:nr, '\.')
- return t[0] * 1000 + (len(t) == 2 ? t[1] : 0)
+" The breakpoint may contain a dot: 123.4 -> 123004
+" The main breakpoint has a zero subid.
+func s:Breakpoint2SignNumber(id, subid)
+ return s:break_id + a:id * 1000 + a:subid
endfunction
func s:Highlight(init, old, new)
@@ -362,8 +362,17 @@ func s:StartDebugCommon(dict)
" Contains breakpoints that have been placed, key is a string with the GDB
" breakpoint number.
+ " Each entry is a dict, containing the sub-breakpoints. Key is the subid.
+ " For a breakpoint that is just a number the subid is zero.
+ " For a breakpoint "123.4" the id is "123" and subid is "4".
+ " Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
+ " {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
let s:breakpoints = {}
+ " Contains breakpoints by file/lnum. The key is "fname:lnum".
+ " Each entry is a list of breakpoint IDs at that position.
+ let s:breakpoint_locations = {}
+
augroup TermDebug
au BufRead * call s:BufRead()
au BufUnload * call s:BufUnloaded()
@@ -683,10 +692,13 @@ func s:DeleteCommands()
endif
exe 'sign unplace ' . s:pc_id
- for key in keys(s:breakpoints)
- exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(key))
+ for [id, entries] in items(s:breakpoints)
+ for subid in keys(entries)
+ exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
+ endfor
endfor
unlet s:breakpoints
+ unlet s:breakpoint_locations
sign undefine debugPC
for val in s:BreakpointSigns
@@ -721,15 +733,27 @@ endfunc
func s:ClearBreakpoint()
let fname = fnameescape(expand('%:p'))
let lnum = line('.')
- for [key, val] in items(s:breakpoints)
- if val['fname'] == fname && val['lnum'] == lnum
- call s:SendCommand('-break-delete ' . key)
- " Assume this always wors, the reply is simply "^done".
- exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(key))
- unlet s:breakpoints[key]
- break
+ let bploc = printf('%s:%d', fname, lnum)
+ if has_key(s:breakpoint_locations, bploc)
+ let idx = 0
+ for id in s:breakpoint_locations[bploc]
+ if has_key(s:breakpoints, id)
+ " Assume this always works, the reply is simply "^done".
+ call s:SendCommand('-break-delete ' . id)
+ for subid in keys(s:breakpoints[id])
+ exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
+ endfor
+ unlet s:breakpoints[id]
+ unlet s:breakpoint_locations[bploc][idx]
+ break
+ else
+ let idx += 1
+ endif
+ endfor
+ if empty(s:breakpoint_locations[bploc])
+ unlet s:breakpoint_locations[bploc]
endif
- endfor
+ endif
endfunc
func s:Run(args)
@@ -873,15 +897,16 @@ endfunc
let s:BreakpointSigns = []
-func s:CreateBreakpoint(nr)
- if index(s:BreakpointSigns, a:nr) == -1
- call add(s:BreakpointSigns, a:nr)
- exe "sign define debugBreakpoint" . a:nr . " text=" . substitute(a:nr, '\..*', '', '') . " texthl=debugBreakpoint"
+func s:CreateBreakpoint(id, subid)
+ let nr = printf('%d.%d', a:id, a:subid)
+ if index(s:BreakpointSigns, nr) == -1
+ call add(s:BreakpointSigns, nr)
+ exe "sign define debugBreakpoint" . nr . " text=" . substitute(nr, '\..*', '', '') . " texthl=debugBreakpoint"
endif
endfunc
-func s:SplitMsg(s)
- return split(a:s, '{\%([a-z-]\+=[^,]\+,*\)\+}\zs')
+func! s:SplitMsg(s)
+ return split(a:s, '{.\{-}}\zs')
endfunction
" Handle setting a breakpoint
@@ -900,48 +925,63 @@ func s:HandleNewBreakpoint(msg)
if empty(nr)
return
endif
- call s:CreateBreakpoint(nr)
- if has_key(s:breakpoints, nr)
- let entry = s:breakpoints[nr]
+ " If "nr" is 123 it becomes "123.0" and subid is "0".
+ " If "nr" is 123.4 it becomes "123.4.0" and subid is "4"; "0" is discarded.
+ let [id, subid; _] = map(split(nr . '.0', '\.'), 'v:val + 0')
+ call s:CreateBreakpoint(id, subid)
+
+ if has_key(s:breakpoints, id)
+ let entries = s:breakpoints[id]
+ else
+ let entries = {}
+ let s:breakpoints[id] = entries
+ endif
+ if has_key(entries, subid)
+ let entry = entries[subid]
else
let entry = {}
- let s:breakpoints[nr] = entry
+ let entries[subid] = entry
endif
let lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '')
let entry['fname'] = fname
let entry['lnum'] = lnum
+ let bploc = printf('%s:%d', fname, lnum)
+ if !has_key(s:breakpoint_locations, bploc)
+ let s:breakpoint_locations[bploc] = []
+ endif
+ let s:breakpoint_locations[bploc] += [id]
+
if bufloaded(fname)
- call s:PlaceSign(nr, entry)
+ call s:PlaceSign(id, subid, entry)
endif
endfor
endfunc
-func s:PlaceSign(nr, entry)
- exe 'sign place ' . (s:break_id + s:Breakpoint2SignNumber(a:nr)) . ' line=' . a:entry['lnum'] . ' name=debugBreakpoint' . a:nr . ' file=' . a:entry['fname']
+func s:PlaceSign(id, subid, entry)
+ let nr = printf('%d.%d', a:id, a:subid)
+ exe 'sign place ' . s:Breakpoint2SignNumber(a:id, a:subid) . ' line=' . a:entry['lnum'] . ' name=debugBreakpoint' . nr . ' file=' . a:entry['fname']
let a:entry['placed'] = 1
endfunc
" Handle deleting a breakpoint
" Will remove the sign that shows the breakpoint
func s:HandleBreakpointDelete(msg)
- let key = substitute(a:msg, '.*id="\([0-9.]*\)\".*', '\1', '')
- if empty(key)
+ let id = substitute(a:msg, '.*id="\([0-9]*\)\".*', '\1', '') + 0
+ if empty(id)
return
endif
- for [nr, entry] in items(s:breakpoints)
- if stridx(nr, key) != 0
- continue
- endif
- let entry = s:breakpoints[nr]
- if has_key(entry, 'placed')
- exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(nr))
- unlet entry['placed']
- endif
- unlet s:breakpoints[nr]
- endfor
+ if has_key(s:breakpoints, id)
+ for [subid, entry] in items(s:breakpoints[id])
+ if has_key(entry, 'placed')
+ exe 'sign unplace ' . s:Breakpoint2SignNumber(id, subid)
+ unlet entry['placed']
+ endif
+ endfor
+ unlet s:breakpoints[id]
+ endif
endfunc
" Handle the debugged program starting to run.
@@ -958,20 +998,24 @@ endfunc
" Handle a BufRead autocommand event: place any signs.
func s:BufRead()
let fname = expand('<afile>:p')
- for [nr, entry] in items(s:breakpoints)
- if entry['fname'] == fname
- call s:PlaceSign(nr, entry)
- endif
+ for [id, entries] in items(s:breakpoints)
+ for [subid, entry] in items(entries)
+ if entry['fname'] == fname
+ call s:PlaceSign(id, subid, entry)
+ endif
+ endfor
endfor
endfunc
" Handle a BufUnloaded autocommand event: unplace any signs.
func s:BufUnloaded()
let fname = expand('<afile>:p')
- for [nr, entry] in items(s:breakpoints)
- if entry['fname'] == fname
- let entry['placed'] = 0
- endif
+ for [id, entries] in items(s:breakpoints)
+ for [subid, entry] in items(entries)
+ if entry['fname'] == fname
+ let entry['placed'] = 0
+ endif
+ endfor
endfor
endfunc
diff --git a/src/version.c b/src/version.c
index 45d18587b..981d9187c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -793,6 +793,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 575,
+/**/
574,
/**/
573,