|
1 | 1 | function! vebugger#mdbg#searchAndAttach(binaryFile,srcpath) |
2 | | - let l:processId=vebugger#util#selectProcessOfFile(a:binaryFile) |
3 | | - if 0<l:processId |
4 | | - call vebugger#mdbg#start(a:binaryFile,{'srcpath':a:srcpath,'pid':l:processId}) |
5 | | - endif |
| 2 | + let l:processId=vebugger#util#selectProcessOfFile(a:binaryFile) |
| 3 | + if 0<l:processId |
| 4 | + call vebugger#mdbg#start(a:binaryFile,{'srcpath':a:srcpath,'pid':l:processId}) |
| 5 | + endif |
6 | 6 | endfunction |
7 | 7 |
|
8 | 8 | function! vebugger#mdbg#start(binaryFile,args) |
9 | | - let l:debugger=vebugger#std#startDebugger(shellescape(vebugger#util#getToolFullPath('mdbg',get(a:args,'version'),'Mdbg'))) |
10 | | - let l:debugger.state.mdbg={'breakpointNumbers':{}} |
11 | | - let l:debugger.readResultTemplate.mdbg={'breakpointBound':{}} |
12 | | - |
13 | | - if has_key(a:args,'srcpath') |
14 | | - let l:debugger.state.mdbg.srcpath=a:args.srcpath |
15 | | - else |
16 | | - let l:debugger.state.mdbg.srcpath='.' |
17 | | - endif |
| 9 | + let l:debugger=vebugger#std#startDebugger(shellescape(vebugger#util#getToolFullPath('mdbg',get(a:args,'version'),'Mdbg'))) |
| 10 | + let l:debugger.state.mdbg={'breakpointNumbers':{}} |
| 11 | + let l:debugger.readResultTemplate.mdbg={'breakpointBound':{}} |
18 | 12 |
|
19 | | - call l:debugger.writeLine('when StepComplete do where') |
20 | | - call l:debugger.writeLine('when BreakpointHit do where') |
| 13 | + if has_key(a:args,'srcpath') |
| 14 | + let l:debugger.state.mdbg.srcpath=a:args.srcpath |
| 15 | + else |
| 16 | + let l:debugger.state.mdbg.srcpath='.' |
| 17 | + endif |
21 | 18 |
|
| 19 | + call l:debugger.writeLine('when StepComplete do where') |
| 20 | + call l:debugger.writeLine('when BreakpointHit do where') |
22 | 21 |
|
23 | | - if get(a:args,'pid') "Attach to process |
24 | | - call l:debugger.writeLine('attach '.string(a:args.pid)) |
25 | | - else |
26 | | - if !get(a:args,'noConsole') |
27 | | - call l:debugger.writeLine('mode nc on') |
28 | | - endif |
29 | | - call l:debugger.writeLine('run '.shellescape(fnamemodify(a:binaryFile,':p')).' '.vebugger#util#commandLineArgsForProgram(a:args)) |
30 | | - call l:debugger.writeLine('where') |
31 | | - end |
32 | 22 |
|
| 23 | + if get(a:args,'pid') "Attach to process |
| 24 | + call l:debugger.writeLine('attach '.string(a:args.pid)) |
| 25 | + else |
| 26 | + if !get(a:args,'noConsole') |
| 27 | + call l:debugger.writeLine('mode nc on') |
| 28 | + endif |
| 29 | + call l:debugger.writeLine('run "'.s:pathToMdbgStyle(fnamemodify(a:binaryFile, ':p')).'" '.vebugger#util#commandLineArgsForProgram(a:args)) |
| 30 | + call l:debugger.writeLine('where') |
| 31 | + end |
| 32 | + call l:debugger.addReadHandler(function('s:readProgramOutput')) |
| 33 | + call l:debugger.addReadHandler(function('s:readWhere')) |
| 34 | + call l:debugger.addReadHandler(function('s:readFinish')) |
| 35 | + call l:debugger.addReadHandler(function('s:readEvaluatedExpressions')) |
| 36 | + call l:debugger.addReadHandler(function('s:readBreakpointBound')) |
33 | 37 |
|
34 | | - call l:debugger.addReadHandler(function('s:readProgramOutput')) |
35 | | - call l:debugger.addReadHandler(function('s:readWhere')) |
36 | | - call l:debugger.addReadHandler(function('s:readFinish')) |
37 | | - call l:debugger.addReadHandler(function('s:readEvaluatedExpressions')) |
38 | | - call l:debugger.addReadHandler(function('s:readBreakpointBound')) |
| 38 | + call l:debugger.addThinkHandler(function('s:breakpointAdded')) |
39 | 39 |
|
40 | | - call l:debugger.addThinkHandler(function('s:breakpointAdded')) |
| 40 | + call l:debugger.setWriteHandler('std','flow',function('s:writeFlow')) |
| 41 | + call l:debugger.setWriteHandler('std','breakpoints',function('s:writeBreakpoints')) |
| 42 | + call l:debugger.setWriteHandler('std','closeDebugger',function('s:closeDebugger')) |
| 43 | + call l:debugger.setWriteHandler('std','evaluateExpressions',function('s:requestEvaluateExpression')) |
| 44 | + call l:debugger.setWriteHandler('std','executeStatements',function('s:executeStatements')) |
41 | 45 |
|
42 | | - call l:debugger.setWriteHandler('std','flow',function('s:writeFlow')) |
43 | | - call l:debugger.setWriteHandler('std','breakpoints',function('s:writeBreakpoints')) |
44 | | - call l:debugger.setWriteHandler('std','closeDebugger',function('s:closeDebugger')) |
45 | | - call l:debugger.setWriteHandler('std','evaluateExpressions',function('s:requestEvaluateExpression')) |
46 | | - call l:debugger.setWriteHandler('std','executeStatements',function('s:executeStatements')) |
| 46 | + call l:debugger.generateWriteActionsFromTemplate() |
47 | 47 |
|
48 | | - call l:debugger.generateWriteActionsFromTemplate() |
| 48 | + call l:debugger.std_addAllBreakpointActions(g:vebugger_breakpoints) |
49 | 49 |
|
50 | | - call l:debugger.std_addAllBreakpointActions(g:vebugger_breakpoints) |
| 50 | + return l:debugger |
| 51 | +endfunction |
51 | 52 |
|
52 | | - return l:debugger |
| 53 | +function! s:pathToMdbgStyle(path) |
| 54 | + if has('win32unix') |
| 55 | + return substitute(system('cygpath -w '.shellescape(a:path)),'\n$','','') |
| 56 | + else |
| 57 | + return a:path |
| 58 | + endif |
| 59 | +endfunction |
| 60 | + |
| 61 | +function! s:pathToVimStyle(path) |
| 62 | + if has('win32unix') |
| 63 | + return substitute(system('cygpath -u '.shellescape(a:path)),'\n$','','') |
| 64 | + else |
| 65 | + return a:path |
| 66 | + endif |
53 | 67 | endfunction |
54 | 68 |
|
55 | 69 | function! s:findFilePath(src,fileName,methodName) |
56 | | - if vebugger#util#isPathAbsolute(a:fileName) |
57 | | - return fnamemodify(a:fileName,':p') "Return the normalized full path |
| 70 | + let l:fileName = s:pathToVimStyle(a:fileName) |
| 71 | + if vebugger#util#isPathAbsolute(l:fileName) |
| 72 | + return fnamemodify(l:fileName,':p') "Return the normalized full path |
| 73 | + endif |
| 74 | + let l:path=fnamemodify(a:src,':p') |
| 75 | + let l:files=glob(l:path.'**/'.l:fileName,0,1) |
| 76 | + for l:dirname in split(a:methodName,'\.') |
| 77 | + if empty(l:files) |
| 78 | + return '' |
58 | 79 | endif |
59 | | - let l:path=fnamemodify(a:src,':p') |
60 | | - let l:files=glob(l:path.'**/'.a:fileName,0,1) |
61 | | - for l:dirname in split(a:methodName,'\.') |
62 | | - if empty(l:files) |
63 | | - return '' |
64 | | - endif |
65 | | - if 1==len(l:files) |
66 | | - return l:files[0] |
67 | | - endif |
68 | | - let l:path=fnamemodify(l:path.l:dirname,':p') |
69 | | - let l:files=filter(l:files,'-1<stridx(v:val,l:path)') |
70 | | - endfor |
71 | | - return '' |
| 80 | + if 1==len(l:files) |
| 81 | + return l:files[0] |
| 82 | + endif |
| 83 | + let l:path=fnamemodify(l:path.l:dirname,':p') |
| 84 | + let l:files=filter(l:files,'-1<stridx(v:val,l:path)') |
| 85 | + endfor |
| 86 | + return '' |
72 | 87 | endfunction |
73 | 88 |
|
74 | 89 | function! s:readProgramOutput(pipeName,line,readResult,debugger) |
75 | 90 | endfunction |
76 | 91 |
|
77 | 92 | function! s:readWhere(pipeName,line,readResult,debugger) |
78 | | - if 'out'==a:pipeName |
79 | | - let l:matches=matchlist(a:line,'\v^\*(\d+)\.\s*([A-Za-z0-9_.+<>]+)\s*\((.+):(\d+)\)') |
80 | | - if 3<len(l:matches) |
81 | | - let l:frameNumber=str2nr(l:matches[1]) |
82 | | - let l:file=s:findFilePath(a:debugger.state.mdbg.srcpath,l:matches[3],l:matches[2]) |
83 | | - let l:file=fnamemodify(l:file,':~:.') |
84 | | - if 0==l:frameNumber " first stackframe is the current location |
85 | | - let a:readResult.std.location={ |
86 | | - \'file':(l:file), |
87 | | - \'line':str2nr(l:matches[4])} |
88 | | - endif |
89 | | - let a:readResult.std.callstack={ |
90 | | - \'clearOld':('0'==l:frameNumber), |
91 | | - \'add':'after', |
92 | | - \'file':(l:file), |
93 | | - \'line':str2nr(l:matches[4])} |
94 | | - endif |
| 93 | + if 'out'==a:pipeName |
| 94 | + let l:matches=matchlist(a:line,'\v^\*(\d+)\.\s*([A-Za-z0-9_.+<>]+)\s*\((.+):(\d+)\)') |
| 95 | + if 3<len(l:matches) |
| 96 | + let l:frameNumber=str2nr(l:matches[1]) |
| 97 | + let l:file=s:findFilePath(a:debugger.state.mdbg.srcpath,l:matches[3],l:matches[2]) |
| 98 | + let l:file=fnamemodify(l:file,':~:.') |
| 99 | + if 0==l:frameNumber " first stackframe is the current location |
| 100 | + let a:readResult.std.location={ |
| 101 | + \'file':(l:file), |
| 102 | + \'line':str2nr(l:matches[4])} |
| 103 | + endif |
| 104 | + let a:readResult.std.callstack={ |
| 105 | + \'clearOld':('0'==l:frameNumber), |
| 106 | + \'add':'after', |
| 107 | + \'file':(l:file), |
| 108 | + \'line':str2nr(l:matches[4])} |
95 | 109 | endif |
| 110 | + endif |
96 | 111 | endfunction |
97 | 112 |
|
98 | 113 | function! s:readFinish(pipeName,line,readResult,debugger) |
99 | | - if a:line=~'\VSTOP: Process Exited\$' |
100 | | - let a:readResult.std.programFinish={'finish':1} |
101 | | - endif |
| 114 | + if a:line=~'\VSTOP: Process Exited\$' |
| 115 | + let a:readResult.std.programFinish={'finish':1} |
| 116 | + endif |
102 | 117 | endfunction |
103 | 118 |
|
104 | 119 | function! s:writeFlow(writeAction,debugger) |
105 | | - if 'stepin'==a:writeAction |
106 | | - call a:debugger.writeLine('step') |
107 | | - elseif 'stepover'==a:writeAction |
108 | | - call a:debugger.writeLine('next') |
109 | | - elseif 'stepout'==a:writeAction |
110 | | - call a:debugger.writeLine('out') |
111 | | - elseif 'continue'==a:writeAction |
112 | | - call a:debugger.writeLine('go') |
113 | | - endif |
| 120 | + if 'stepin'==a:writeAction |
| 121 | + call a:debugger.writeLine('step') |
| 122 | + elseif 'stepover'==a:writeAction |
| 123 | + call a:debugger.writeLine('next') |
| 124 | + elseif 'stepout'==a:writeAction |
| 125 | + call a:debugger.writeLine('out') |
| 126 | + elseif 'continue'==a:writeAction |
| 127 | + call a:debugger.writeLine('go') |
| 128 | + endif |
114 | 129 | endfunction |
115 | 130 |
|
116 | 131 | function! s:closeDebugger(writeAction,debugger) |
117 | | - call a:debugger.writeLine('quit') |
| 132 | + call a:debugger.writeLine('quit') |
118 | 133 | endfunction |
119 | 134 |
|
120 | 135 | function! s:writeBreakpoints(writeAction,debugger) |
121 | | - for l:breakpoint in a:writeAction |
122 | | - let l:fullFileName=fnamemodify(l:breakpoint.file,':p') |
123 | | - if 'add'==(l:breakpoint.action) |
124 | | - call a:debugger.writeLine('break '.fnameescape(l:fullFileName).':'.l:breakpoint.line) |
125 | | - let a:debugger.state.mdbg.breakpointNumbers[l:fullFileName.':'.l:breakpoint.line]={} |
126 | | - elseif 'remove'==l:breakpoint.action |
127 | | - call a:debugger.writeLine('delete '.a:debugger.state.mdbg.breakpointNumbers[l:fullFileName.':'.l:breakpoint.line].number) |
128 | | - call remove(a:debugger.state.mdbg.breakpointNumbers,l:fullFileName.':'.l:breakpoint.line) |
129 | | - endif |
130 | | - endfor |
| 136 | + for l:breakpoint in a:writeAction |
| 137 | + let l:fullFileName=fnamemodify(l:breakpoint.file,':p') |
| 138 | + if 'add'==(l:breakpoint.action) |
| 139 | + call a:debugger.writeLine('break '.s:pathToMdbgStyle(l:fullFileName).':'.l:breakpoint.line) |
| 140 | + let a:debugger.state.mdbg.breakpointNumbers[s:pathToVimStyle(l:fullFileName).':'.l:breakpoint.line]={} |
| 141 | + elseif 'remove'==l:breakpoint.action |
| 142 | + call a:debugger.writeLine('delete '.a:debugger.state.mdbg.breakpointNumbers[l:fullFileName.':'.l:breakpoint.line].number) |
| 143 | + call remove(a:debugger.state.mdbg.breakpointNumbers,l:fullFileName.':'.l:breakpoint.line) |
| 144 | + endif |
| 145 | + endfor |
131 | 146 | endfunction |
132 | 147 |
|
133 | 148 | function! s:readBreakpointBound(pipeName,line,readResult,debugger) |
134 | | - if 'out'==a:pipeName |
135 | | - let l:matches=matchlist(a:line,'\vBreakpoint \#(\d+) bound\s*\(line (\d+) in ([^)]+)\)') |
136 | | - if 3<len(l:matches) |
137 | | - let a:readResult.mdbg.breakpointBound={ |
138 | | - \'fileNameTail':l:matches[3], |
139 | | - \'line':l:matches[2], |
140 | | - \'breakpointNumber':l:matches[1]} |
141 | | - endif |
| 149 | + if 'out'==a:pipeName |
| 150 | + let l:matches=matchlist(a:line,'\vBreakpoint \#(\d+) bound\s*\(line (\d+) in ([^)]+)\)') |
| 151 | + if 3<len(l:matches) |
| 152 | + let a:readResult.mdbg.breakpointBound={ |
| 153 | + \'fileNameTail':s:pathToVimStyle(l:matches[3]), |
| 154 | + \'line':l:matches[2], |
| 155 | + \'breakpointNumber':l:matches[1]} |
142 | 156 | endif |
| 157 | + endif |
143 | 158 | endfunction |
144 | 159 |
|
145 | 160 | function! s:breakpointAdded(readResult,debugger) |
146 | | - if !empty(a:readResult.mdbg.breakpointBound) |
147 | | - let l:breakpointBound=a:readResult.mdbg.breakpointBound |
148 | | - let l:lookFor=l:breakpointBound.fileNameTail.':'.l:breakpointBound.line |
149 | | - let l:lookForRegex='\V'.escape(l:lookFor,'\').'\$' |
150 | | - let l:matchingKeys=filter(keys(a:debugger.state.mdbg.breakpointNumbers),'v:val=~l:lookForRegex') |
151 | | - for l:key in l:matchingKeys |
152 | | - if empty(a:debugger.state.mdbg.breakpointNumbers[l:key]) |
153 | | - let a:debugger.state.mdbg.breakpointNumbers[l:key]={'number':l:breakpointBound.breakpointNumber} |
154 | | - endif |
155 | | - endfor |
156 | | - endif |
| 161 | + if !empty(a:readResult.mdbg.breakpointBound) |
| 162 | + let l:breakpointBound=a:readResult.mdbg.breakpointBound |
| 163 | + let l:lookFor=l:breakpointBound.fileNameTail.':'.l:breakpointBound.line |
| 164 | + let l:lookForRegex='\V'.escape(l:lookFor,'\').'\$' |
| 165 | + let l:matchingKeys=filter(keys(a:debugger.state.mdbg.breakpointNumbers),'v:val=~l:lookForRegex') |
| 166 | + for l:key in l:matchingKeys |
| 167 | + if empty(a:debugger.state.mdbg.breakpointNumbers[l:key]) |
| 168 | + let a:debugger.state.mdbg.breakpointNumbers[l:key]={'number':l:breakpointBound.breakpointNumber} |
| 169 | + endif |
| 170 | + endfor |
| 171 | + endif |
157 | 172 | endfunction |
158 | 173 |
|
159 | 174 | function! s:requestEvaluateExpression(writeAction,debugger) |
160 | | - for l:evalAction in a:writeAction |
161 | | - call a:debugger.writeLine('print '.l:evalAction.expression) |
162 | | - endfor |
| 175 | + for l:evalAction in a:writeAction |
| 176 | + call a:debugger.writeLine('print '.l:evalAction.expression) |
| 177 | + endfor |
163 | 178 | endfunction |
164 | 179 |
|
165 | 180 | function! s:executeStatements(writeAction,debugger) |
166 | | - for l:evalAction in a:writeAction |
167 | | - if has_key(l:evalAction,'statement') |
168 | | - call a:debugger.writeLine('set '.substitute(l:evalAction.statement,'\v;\s*$','','')) |
169 | | - endif |
170 | | - endfor |
| 181 | + for l:evalAction in a:writeAction |
| 182 | + if has_key(l:evalAction,'statement') |
| 183 | + call a:debugger.writeLine('set '.substitute(l:evalAction.statement,'\v;\s*$','','')) |
| 184 | + endif |
| 185 | + endfor |
171 | 186 | endfunction |
172 | 187 |
|
173 | 188 | function! s:readEvaluatedExpressions(pipeName,line,readResult,debugger) dict |
174 | | - if 'out'==a:pipeName |
175 | | - let l:matches=matchlist(a:line,'\v\[[^\]]*\]\s*mdbg\>\s*([^=]+)\=(.*)$') |
176 | | - if 2<len(l:matches) |
177 | | - let l:expression=l:matches[1] |
178 | | - let l:value=l:matches[2] |
179 | | - let a:readResult.std.evaluatedExpression={ |
180 | | - \'expression':l:expression, |
181 | | - \'value':l:value} |
182 | | - endif |
| 189 | + if 'out'==a:pipeName |
| 190 | + let l:matches=matchlist(a:line,'\v\[[^\]]*\]\s*mdbg\>\s*([^=]+)\=(.*)$') |
| 191 | + if 2<len(l:matches) |
| 192 | + let l:expression=l:matches[1] |
| 193 | + let l:value=l:matches[2] |
| 194 | + let a:readResult.std.evaluatedExpression={ |
| 195 | + \'expression':l:expression, |
| 196 | + \'value':l:value} |
183 | 197 | endif |
| 198 | + endif |
184 | 199 | endfunction |
0 commit comments