@@ -74,10 +74,10 @@ let s:break_id = 13 " breakpoint number is added to this
7474let s: stopped = 1
7575
7676" Take a breakpoint number as used by GDB and turn it into an integer.
77- " The breakpoint may contain a dot: 123.4
78- func s: Breakpoint2SignNumber (nr)
79- let t = split ( a: nr , ' \. ' )
80- return t [ 0 ] * 1000 + ( len ( t ) == 2 ? t [ 1 ] : 0 )
77+ " The breakpoint may contain a dot: 123.4 -> 123004
78+ " The main breakpoint has a zero subid.
79+ func s: Breakpoint2SignNumber (id, subid )
80+ return s: break_id + a: id * 1000 + a: subid
8181endfunction
8282
8383func s: Highlight (init, old, new )
@@ -362,8 +362,17 @@ func s:StartDebugCommon(dict)
362362
363363 " Contains breakpoints that have been placed, key is a string with the GDB
364364 " breakpoint number.
365+ " Each entry is a dict, containing the sub-breakpoints. Key is the subid.
366+ " For a breakpoint that is just a number the subid is zero.
367+ " For a breakpoint "123.4" the id is "123" and subid is "4".
368+ " Example, when breakpoint "44", "123", "123.1" and "123.2" exist:
369+ " {'44': {'0': entry}, '123': {'0': entry, '1': entry, '2': entry}}
365370 let s: breakpoints = {}
366371
372+ " Contains breakpoints by file/lnum. The key is "fname:lnum".
373+ " Each entry is a list of breakpoint IDs at that position.
374+ let s: breakpoint_locations = {}
375+
367376 augroup TermDebug
368377 au BufRead * call s: BufRead ()
369378 au BufUnload * call s: BufUnloaded ()
@@ -683,10 +692,13 @@ func s:DeleteCommands()
683692 endif
684693
685694 exe ' sign unplace ' . s: pc_id
686- for key in keys (s: breakpoints )
687- exe ' sign unplace ' . (s: break_id + s: Breakpoint2SignNumber (key ))
695+ for [id, entries] in items (s: breakpoints )
696+ for subid in keys (entries)
697+ exe ' sign unplace ' . s: Breakpoint2SignNumber (id, subid)
698+ endfor
688699 endfor
689700 unlet s: breakpoints
701+ unlet s: breakpoint_locations
690702
691703 sign undefine debugPC
692704 for val in s: BreakpointSigns
@@ -721,15 +733,27 @@ endfunc
721733func s: ClearBreakpoint ()
722734 let fname = fnameescape (expand (' %:p' ))
723735 let lnum = line (' .' )
724- for [key , val] in items (s: breakpoints )
725- if val[' fname' ] == fname && val[' lnum' ] == lnum
726- call s: SendCommand (' -break-delete ' . key )
727- " Assume this always wors, the reply is simply "^done".
728- exe ' sign unplace ' . (s: break_id + s: Breakpoint2SignNumber (key ))
729- unlet s: breakpoints [key ]
730- break
736+ let bploc = printf (' %s:%d' , fname, lnum)
737+ if has_key (s: breakpoint_locations , bploc)
738+ let idx = 0
739+ for id in s: breakpoint_locations [bploc]
740+ if has_key (s: breakpoints , id)
741+ " Assume this always works, the reply is simply "^done".
742+ call s: SendCommand (' -break-delete ' . id)
743+ for subid in keys (s: breakpoints [id])
744+ exe ' sign unplace ' . s: Breakpoint2SignNumber (id, subid)
745+ endfor
746+ unlet s: breakpoints [id]
747+ unlet s: breakpoint_locations [bploc][idx]
748+ break
749+ else
750+ let idx += 1
751+ endif
752+ endfor
753+ if empty (s: breakpoint_locations [bploc])
754+ unlet s: breakpoint_locations [bploc]
731755 endif
732- endfor
756+ endif
733757endfunc
734758
735759func s: Run (args )
@@ -873,15 +897,16 @@ endfunc
873897
874898let s: BreakpointSigns = []
875899
876- func s: CreateBreakpoint (nr)
877- if index (s: BreakpointSigns , a: nr ) == -1
878- call add (s: BreakpointSigns , a: nr )
879- exe " sign define debugBreakpoint" . a: nr . " text=" . substitute (a: nr , ' \..*' , ' ' , ' ' ) . " texthl=debugBreakpoint"
900+ func s: CreateBreakpoint (id, subid)
901+ let nr = printf (' %d.%d' , a: id , a: subid )
902+ if index (s: BreakpointSigns , nr) == -1
903+ call add (s: BreakpointSigns , nr)
904+ exe " sign define debugBreakpoint" . nr . " text=" . substitute (nr, ' \..*' , ' ' , ' ' ) . " texthl=debugBreakpoint"
880905 endif
881906endfunc
882907
883- func s: SplitMsg (s )
884- return split (a: s , ' {\%([a-z-]\+=[^,]\+,*\)\+ }\zs' )
908+ func ! s: SplitMsg (s )
909+ return split (a: s , ' {.\{-} }\zs' )
885910endfunction
886911
887912" Handle setting a breakpoint
@@ -900,48 +925,63 @@ func s:HandleNewBreakpoint(msg)
900925 if empty (nr)
901926 return
902927 endif
903- call s: CreateBreakpoint (nr)
904928
905- if has_key (s: breakpoints , nr)
906- let entry = s: breakpoints [nr]
929+ " If "nr" is 123 it becomes "123.0" and subid is "0".
930+ " If "nr" is 123.4 it becomes "123.4.0" and subid is "4"; "0" is discarded.
931+ let [id, subid; _] = map (split (nr . ' .0' , ' \.' ), ' v:val + 0' )
932+ call s: CreateBreakpoint (id, subid)
933+
934+ if has_key (s: breakpoints , id)
935+ let entries = s: breakpoints [id]
936+ else
937+ let entries = {}
938+ let s: breakpoints [id] = entries
939+ endif
940+ if has_key (entries, subid)
941+ let entry = entries[subid]
907942 else
908943 let entry = {}
909- let s: breakpoints [nr ] = entry
944+ let entries[subid ] = entry
910945 endif
911946
912947 let lnum = substitute (msg, ' .*line="\([^"]*\)".*' , ' \1' , ' ' )
913948 let entry[' fname' ] = fname
914949 let entry[' lnum' ] = lnum
915950
951+ let bploc = printf (' %s:%d' , fname, lnum)
952+ if ! has_key (s: breakpoint_locations , bploc)
953+ let s: breakpoint_locations [bploc] = []
954+ endif
955+ let s: breakpoint_locations [bploc] += [id]
956+
916957 if bufloaded (fname)
917- call s: PlaceSign (nr , entry)
958+ call s: PlaceSign (id, subid , entry)
918959 endif
919960 endfor
920961endfunc
921962
922- func s: PlaceSign (nr, entry)
923- exe ' sign place ' . (s: break_id + s: Breakpoint2SignNumber (a: nr )) . ' line=' . a: entry [' lnum' ] . ' name=debugBreakpoint' . a: nr . ' file=' . a: entry [' fname' ]
963+ func s: PlaceSign (id, subid, entry)
964+ let nr = printf (' %d.%d' , a: id , a: subid )
965+ exe ' sign place ' . s: Breakpoint2SignNumber (a: id , a: subid ) . ' line=' . a: entry [' lnum' ] . ' name=debugBreakpoint' . nr . ' file=' . a: entry [' fname' ]
924966 let a: entry [' placed' ] = 1
925967endfunc
926968
927969" Handle deleting a breakpoint
928970" Will remove the sign that shows the breakpoint
929971func s: HandleBreakpointDelete (msg)
930- let key = substitute (a: msg , ' .*id="\([0-9. ]*\)\".*' , ' \1' , ' ' )
931- if empty (key )
972+ let id = substitute (a: msg , ' .*id="\([0-9]*\)\".*' , ' \1' , ' ' ) + 0
973+ if empty (id )
932974 return
933975 endif
934- for [nr, entry] in items (s: breakpoints )
935- if stridx (nr, key ) != 0
936- continue
937- endif
938- let entry = s: breakpoints [nr]
939- if has_key (entry, ' placed' )
940- exe ' sign unplace ' . (s: break_id + s: Breakpoint2SignNumber (nr))
941- unlet entry[' placed' ]
942- endif
943- unlet s: breakpoints [nr]
944- endfor
976+ if has_key (s: breakpoints , id)
977+ for [subid, entry] in items (s: breakpoints [id])
978+ if has_key (entry, ' placed' )
979+ exe ' sign unplace ' . s: Breakpoint2SignNumber (id, subid)
980+ unlet entry[' placed' ]
981+ endif
982+ endfor
983+ unlet s: breakpoints [id]
984+ endif
945985endfunc
946986
947987" Handle the debugged program starting to run.
@@ -958,20 +998,24 @@ endfunc
958998" Handle a BufRead autocommand event: place any signs.
959999func s: BufRead ()
9601000 let fname = expand (' <afile>:p' )
961- for [nr, entry] in items (s: breakpoints )
962- if entry[' fname' ] == fname
963- call s: PlaceSign (nr, entry)
964- endif
1001+ for [id, entries] in items (s: breakpoints )
1002+ for [subid, entry] in items (entries)
1003+ if entry[' fname' ] == fname
1004+ call s: PlaceSign (id, subid, entry)
1005+ endif
1006+ endfor
9651007 endfor
9661008endfunc
9671009
9681010" Handle a BufUnloaded autocommand event: unplace any signs.
9691011func s: BufUnloaded ()
9701012 let fname = expand (' <afile>:p' )
971- for [nr, entry] in items (s: breakpoints )
972- if entry[' fname' ] == fname
973- let entry[' placed' ] = 0
974- endif
1013+ for [id, entries] in items (s: breakpoints )
1014+ for [subid, entry] in items (entries)
1015+ if entry[' fname' ] == fname
1016+ let entry[' placed' ] = 0
1017+ endif
1018+ endfor
9751019 endfor
9761020endfunc
9771021
0 commit comments