To: vim_dev@googlegroups.com Subject: Patch 8.1.0557 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0557 Problem: Termdebug: gdb may use X.Y for breakpoint number. Solution: Handle X.Y breakpoint numbers. (Yasuhiro Matsumoto, close #3641) Files: runtime/pack/dist/opt/termdebug/plugin/termdebug.vim *** ../vim-8.1.0556/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim 2018-07-19 04:13:30.332453051 +0200 --- runtime/pack/dist/opt/termdebug/plugin/termdebug.vim 2018-12-02 13:31:34.977457347 +0100 *************** *** 73,78 **** --- 73,85 ---- 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) + endfunction + func s:Highlight(init, old, new) let default = a:init ? 'default ' : '' if a:new ==# 'light' && a:old !=# 'light' *************** *** 138,146 **** func s:StartDebug_term(dict) " Open a terminal window without a job, to run the debugged program in. let s:ptybuf = term_start('NONE', { ! \ 'term_name': 'debugged program', ! \ 'vertical': s:vertical, ! \ }) if s:ptybuf == 0 echoerr 'Failed to open the program terminal window' return --- 145,153 ---- func s:StartDebug_term(dict) " Open a terminal window without a job, to run the debugged program in. let s:ptybuf = term_start('NONE', { ! \ 'term_name': 'debugged program', ! \ 'vertical': s:vertical, ! \ }) if s:ptybuf == 0 echoerr 'Failed to open the program terminal window' return *************** *** 155,164 **** " Create a hidden terminal window to communicate with gdb let s:commbuf = term_start('NONE', { ! \ 'term_name': 'gdb communication', ! \ 'out_cb': function('s:CommOutput'), ! \ 'hidden': 1, ! \ }) if s:commbuf == 0 echoerr 'Failed to open the communication terminal window' exe 'bwipe! ' . s:ptybuf --- 162,171 ---- " Create a hidden terminal window to communicate with gdb let s:commbuf = term_start('NONE', { ! \ 'term_name': 'gdb communication', ! \ 'out_cb': function('s:CommOutput'), ! \ 'hidden': 1, ! \ }) if s:commbuf == 0 echoerr 'Failed to open the communication terminal window' exe 'bwipe! ' . s:ptybuf *************** *** 174,182 **** let cmd = [g:termdebugger, '-quiet', '-tty', pty] + gdb_args call ch_log('executing "' . join(cmd) . '"') let s:gdbbuf = term_start(cmd, { ! \ 'exit_cb': function('s:EndTermDebug'), ! \ 'term_finish': 'close', ! \ }) if s:gdbbuf == 0 echoerr 'Failed to open the gdb terminal window' exe 'bwipe! ' . s:ptybuf --- 181,189 ---- let cmd = [g:termdebugger, '-quiet', '-tty', pty] + gdb_args call ch_log('executing "' . join(cmd) . '"') let s:gdbbuf = term_start(cmd, { ! \ 'exit_cb': function('s:EndTermDebug'), ! \ 'term_finish': 'close', ! \ }) if s:gdbbuf == 0 echoerr 'Failed to open the gdb terminal window' exe 'bwipe! ' . s:ptybuf *************** *** 200,217 **** let response = '' for lnum in range(1,200) if term_getline(s:gdbbuf, lnum) =~ 'new-ui mi ' ! " response can be in the same line or the next line ! let response = term_getline(s:gdbbuf, lnum) . term_getline(s:gdbbuf, lnum + 1) ! if response =~ 'Undefined command' ! echoerr 'Sorry, your gdb is too old, gdb 7.12 is required' ! exe 'bwipe! ' . s:ptybuf ! exe 'bwipe! ' . s:commbuf ! return ! endif ! if response =~ 'New UI allocated' ! " Success! ! break ! endif endif endfor if response =~ 'New UI allocated' --- 207,224 ---- let response = '' for lnum in range(1,200) if term_getline(s:gdbbuf, lnum) =~ 'new-ui mi ' ! " response can be in the same line or the next line ! let response = term_getline(s:gdbbuf, lnum) . term_getline(s:gdbbuf, lnum + 1) ! if response =~ 'Undefined command' ! echoerr 'Sorry, your gdb is too old, gdb 7.12 is required' ! exe 'bwipe! ' . s:ptybuf ! exe 'bwipe! ' . s:commbuf ! return ! endif ! if response =~ 'New UI allocated' ! " Success! ! break ! endif endif endfor if response =~ 'New UI allocated' *************** *** 268,276 **** call ch_log('executing "' . join(cmd) . '"') let s:gdbjob = job_start(cmd, { ! \ 'exit_cb': function('s:EndPromptDebug'), ! \ 'out_cb': function('s:GdbOutCallback'), ! \ }) if job_status(s:gdbjob) != "run" echoerr 'Failed to start gdb' exe 'bwipe! ' . s:promptbuf --- 275,283 ---- call ch_log('executing "' . join(cmd) . '"') let s:gdbjob = job_start(cmd, { ! \ 'exit_cb': function('s:EndPromptDebug'), ! \ 'out_cb': function('s:GdbOutCallback'), ! \ }) if job_status(s:gdbjob) != "run" echoerr 'Failed to start gdb' exe 'bwipe! ' . s:promptbuf *************** *** 295,302 **** " Unix: Run the debugged program in a terminal window. Open it below the " gdb window. belowright let s:ptybuf = term_start('NONE', { ! \ 'term_name': 'debugged program', ! \ }) if s:ptybuf == 0 echoerr 'Failed to open the program terminal window' call job_stop(s:gdbjob) --- 302,309 ---- " Unix: Run the debugged program in a terminal window. Open it below the " gdb window. belowright let s:ptybuf = term_start('NONE', { ! \ 'term_name': 'debugged program', ! \ }) if s:ptybuf == 0 echoerr 'Failed to open the program terminal window' call job_stop(s:gdbjob) *************** *** 353,359 **** endif endif ! " Contains breakpoints that have been placed, key is the number. let s:breakpoints = {} augroup TermDebug --- 360,367 ---- endif endif ! " Contains breakpoints that have been placed, key is a string with the GDB ! " breakpoint number. let s:breakpoints = {} augroup TermDebug *************** *** 466,474 **** if a:quotedText[i] == '\' let i += 1 if a:quotedText[i] == 'n' ! " drop \n ! let i += 1 ! continue endif endif let result .= a:quotedText[i] --- 474,482 ---- if a:quotedText[i] == '\' let i += 1 if a:quotedText[i] == 'n' ! " drop \n ! let i += 1 ! continue endif endif let result .= a:quotedText[i] *************** *** 479,484 **** --- 487,495 ---- " Extract the "name" value from a gdb message with fullname="name". func s:GetFullname(msg) + if a:msg !~ 'fullname' + return '' + endif let name = s:DecodeMessage(substitute(a:msg, '.*fullname=', '', '')) if has('win32') && name =~ ':\\\\' " sometimes the name arrives double-escaped *************** *** 549,565 **** endif if msg != '' if msg =~ '^\(\*stopped\|\*running\|=thread-selected\)' ! call s:HandleCursor(msg) elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,' ! call s:HandleNewBreakpoint(msg) elseif msg =~ '^=breakpoint-deleted,' ! call s:HandleBreakpointDelete(msg) elseif msg =~ '^=thread-group-started' ! call s:HandleProgramRun(msg) elseif msg =~ '^\^done,value=' ! call s:HandleEvaluate(msg) elseif msg =~ '^\^error,msg=' ! call s:HandleError(msg) endif endif endfor --- 560,576 ---- endif if msg != '' if msg =~ '^\(\*stopped\|\*running\|=thread-selected\)' ! call s:HandleCursor(msg) elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,' ! call s:HandleNewBreakpoint(msg) elseif msg =~ '^=breakpoint-deleted,' ! call s:HandleBreakpointDelete(msg) elseif msg =~ '^=thread-group-started' ! call s:HandleProgramRun(msg) elseif msg =~ '^\^done,value=' ! call s:HandleEvaluate(msg) elseif msg =~ '^\^error,msg=' ! call s:HandleError(msg) endif endif endfor *************** *** 650,661 **** let curwinid = win_getid(winnr()) for winid in s:winbar_winids if win_gotoid(winid) ! aunmenu WinBar.Step ! aunmenu WinBar.Next ! aunmenu WinBar.Finish ! aunmenu WinBar.Cont ! aunmenu WinBar.Stop ! aunmenu WinBar.Eval endif endfor call win_gotoid(curwinid) --- 661,672 ---- let curwinid = win_getid(winnr()) for winid in s:winbar_winids if win_gotoid(winid) ! aunmenu WinBar.Step ! aunmenu WinBar.Next ! aunmenu WinBar.Finish ! aunmenu WinBar.Cont ! aunmenu WinBar.Stop ! aunmenu WinBar.Eval endif endfor call win_gotoid(curwinid) *************** *** 673,679 **** exe 'sign unplace ' . s:pc_id for key in keys(s:breakpoints) ! exe 'sign unplace ' . (s:break_id + key) endfor unlet s:breakpoints --- 684,690 ---- exe 'sign unplace ' . s:pc_id for key in keys(s:breakpoints) ! exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(key)) endfor unlet s:breakpoints *************** *** 700,706 **** endif " Use the fname:lnum format, older gdb can't handle --source. call s:SendCommand('-break-insert ' ! \ . fnameescape(expand('%:p')) . ':' . line('.')) if do_continue call s:SendCommand('-exec-continue') endif --- 711,717 ---- endif " Use the fname:lnum format, older gdb can't handle --source. call s:SendCommand('-break-insert ' ! \ . fnameescape(expand('%:p')) . ':' . line('.')) if do_continue call s:SendCommand('-exec-continue') endif *************** *** 714,720 **** 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 + key) unlet s:breakpoints[key] break endif --- 725,731 ---- 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 endif *************** *** 839,852 **** if lnum =~ '^[0-9]*$' call s:GotoSourcewinOrCreateIt() if expand('%:p') != fnamemodify(fname, ':p') ! if &modified ! " TODO: find existing window ! exe 'split ' . fnameescape(fname) ! let s:sourcewin = win_getid(winnr()) ! call s:InstallWinbar() ! else ! exe 'edit ' . fnameescape(fname) ! endif endif exe lnum exe 'sign unplace ' . s:pc_id --- 850,863 ---- if lnum =~ '^[0-9]*$' call s:GotoSourcewinOrCreateIt() if expand('%:p') != fnamemodify(fname, ':p') ! if &modified ! " TODO: find existing window ! exe 'split ' . fnameescape(fname) ! let s:sourcewin = win_getid(winnr()) ! call s:InstallWinbar() ! else ! exe 'edit ' . fnameescape(fname) ! endif endif exe lnum exe 'sign unplace ' . s:pc_id *************** *** 865,874 **** func s:CreateBreakpoint(nr) if index(s:BreakpointSigns, a:nr) == -1 call add(s:BreakpointSigns, a:nr) ! exe "sign define debugBreakpoint" . a:nr . " text=" . a:nr . " texthl=debugBreakpoint" endif endfunc " Handle setting a breakpoint " Will update the sign that shows the breakpoint func s:HandleNewBreakpoint(msg) --- 876,889 ---- 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" endif endfunc + func s:SplitMsg(s) + return split(a:s, '{\%([a-z-]\+=[^,]\+,*\)\+}\zs') + endfunction + " Handle setting a breakpoint " Will update the sign that shows the breakpoint func s:HandleNewBreakpoint(msg) *************** *** 876,925 **** " a watch does not have a file name return endif ! let nr = substitute(a:msg, '.*number="\([0-9]\)*\".*', '\1', '') + 0 ! if nr == 0 ! return ! endif ! call s:CreateBreakpoint(nr) ! ! if has_key(s:breakpoints, nr) ! let entry = s:breakpoints[nr] ! else ! let entry = {} ! let s:breakpoints[nr] = entry ! endif ! let fname = s:GetFullname(a:msg) ! let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '') ! let entry['fname'] = fname ! let entry['lnum'] = lnum ! if bufloaded(fname) ! call s:PlaceSign(nr, entry) ! endif endfunc func s:PlaceSign(nr, entry) ! exe 'sign place ' . (s:break_id + a:nr) . ' line=' . a:entry['lnum'] . ' name=debugBreakpoint' . a: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 nr = substitute(a:msg, '.*id="\([0-9]*\)\".*', '\1', '') + 0 ! if nr == 0 return endif ! if has_key(s:breakpoints, nr) let entry = s:breakpoints[nr] if has_key(entry, 'placed') ! exe 'sign unplace ' . (s:break_id + nr) unlet entry['placed'] endif unlet s:breakpoints[nr] ! endif endfunc " Handle the debugged program starting to run. --- 891,947 ---- " a watch does not have a file name return endif + for msg in s:SplitMsg(a:msg) + let fname = s:GetFullname(msg) + if empty(fname) + continue + endif + let nr = substitute(msg, '.*number="\([0-9.]*\)\".*', '\1', '') + if empty(nr) + return + endif + call s:CreateBreakpoint(nr) ! if has_key(s:breakpoints, nr) ! let entry = s:breakpoints[nr] ! else ! let entry = {} ! let s:breakpoints[nr] = entry ! endif ! let lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '') ! let entry['fname'] = fname ! let entry['lnum'] = lnum ! if bufloaded(fname) ! call s:PlaceSign(nr, 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'] 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) 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 endfunc " Handle the debugged program starting to run. *** ../vim-8.1.0556/src/version.c 2018-12-01 21:08:18.019648483 +0100 --- src/version.c 2018-12-02 13:43:56.101322941 +0100 *************** *** 794,795 **** --- 794,797 ---- { /* Add new patch number below this line */ + /**/ + 557, /**/ -- FATAL ERROR! SYSTEM HALTED! - Press any key to continue doing nothing. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///