changeset 15129:2090f267b311 v8.1.0575

patch 8.1.0575: Termdebug: clearing multi-breakpoint does not work commit https://github.com/vim/vim/commit/37402ed53475166cd988edbea1269fa4e9918dc4 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 9 15:53:01 2018 +0100 patch 8.1.0575: Termdebug: clearing multi-breakpoint does not work Problem: Termdebug: clearing multi-breakpoint does not work. Solution: Delete all X.Y breakpoints. Keep more information about placed breakpoints. (Ozaki Kiichi, closes #3641)
author Bram Moolenaar <Bram@vim.org>
date Sun, 09 Dec 2018 16:00:06 +0100
parents 16186d27897d
children 4bd9c7284010
files runtime/pack/dist/opt/termdebug/plugin/termdebug.vim src/version.c
diffstat 2 files changed, 94 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- 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
 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 "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, nr)
-      let entry = s:breakpoints[nr]
+    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
 
--- 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,