source: dev/trunk/ab5.0/abdev/abdev/Debugger.cpp@ 625

Last change on this file since 625 was 625, checked in by dai_9181, 16 years ago

・WindowInfoクラスをリファクタリング
・MdiInfoを単純配列からvectorに変更した。

File size: 13.3 KB
Line 
1#include "stdafx.h"
2
3#include "common.h"
4
5CDebugger *pobj_Debugger;
6
7#define WM_DEBUG_CONTINUE WM_USER+200
8#define WM_STEP_IN WM_USER+201
9#define WM_STEP_OVER WM_USER+202
10#define WM_STEP_CURSOR WM_USER+203
11#define WM_DEBUG_STOP WM_USER+204
12#define WM_DEBUG_PAUSE WM_USER+205
13
14CDebugger::CDebugger(){
15 hwnd=0;
16 bDebugging=0;
17}
18CDebugger::~CDebugger(){
19}
20
21BOOL CDebugger::IsDebugging(void){
22 return bDebugging;
23}
24BOOL CDebugger::IsDebuggerView(void){
25 if(hwnd) return 1;
26 return 0;
27}
28
29void CDebugger::resize(int x,int y,int cx,int cy){
30 MoveWindow(hwnd,x,y,cx,cy,1);
31}
32
33void CDebugger::ResetCommandEnabled(void){
34 if(bDebugging==0){
35 BOOL bEnableDocument=0, bBreakPoint=0;
36
37 HWND hChild;
38 hChild=GetWindow(hClient,GW_CHILD);
39
40 if( projectInfo.IsOpened() ){
41 //有効(プロジェクトを開いているとき)
42 bEnableDocument=1;
43 }
44 else{
45 if(IsWindow(hChild)){
46 if(MdiInfo[GetWndNum(hChild)].DocType==WNDTYPE_BASIC){
47 //有効(Basicプログラムファイルを開いているとき)
48 bEnableDocument=1;
49 }
50 }
51 }
52
53 if(IsWindow(hChild)){
54 if(MdiInfo[GetWndNum(hChild)].DocType==WNDTYPE_BASIC){
55 //ブレークポイント有効(Basicプログラムファイルを開いているとき)
56 bBreakPoint=1;
57 }
58 }
59
60 int MenuMsg;
61 if(bEnableDocument) MenuMsg=MF_BYCOMMAND|MF_ENABLED;
62 else MenuMsg=MF_BYCOMMAND|MF_GRAYED;
63
64 //リリースコンパイル
65 pobj_MainMenu->EnableItem(IDM_RELEASECOMPILE,MenuMsg);
66 pobj_ReleaseToolbar->EnableItem(IDM_RELEASECOMPILE,bEnableDocument);
67
68 //リリース実行
69 pobj_MainMenu->EnableItem(IDM_RELEASERUN,MenuMsg);
70 pobj_ReleaseToolbar->EnableItem(IDM_RELEASERUN,bEnableDocument);
71
72 //デバッグコンパイル
73 pobj_MainMenu->EnableItem(IDM_DEBUGCOMPILE,MenuMsg);
74 pobj_DebuggerToolbar->EnableItem(IDM_DEBUGCOMPILE,bEnableDocument);
75
76 //デバッグ実行
77 pobj_MainMenu->EnableItem(IDM_DEBUG,MenuMsg);
78 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,bEnableDocument);
79
80 if(bEnableDocument==0){
81 //ステップ実行
82 pobj_MainMenu->EnableItem(IDM_STEP_IN,MenuMsg);
83 pobj_MainMenu->EnableItem(IDM_STEP_OVER,MenuMsg);
84 pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MenuMsg);
85 pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,bEnableDocument);
86 pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,bEnableDocument);
87 pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,bEnableDocument);
88
89 //デバッグの一時停止
90 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MenuMsg);
91 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,bEnableDocument);
92
93 //デバッグの中断
94 pobj_MainMenu->EnableItem(IDM_DEBUG_STOP,MenuMsg);
95 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_STOP,bEnableDocument);
96 }
97
98 if(bBreakPoint) MenuMsg=MF_BYCOMMAND|MF_ENABLED;
99 else MenuMsg=MF_BYCOMMAND|MF_GRAYED;
100
101 //ブレークポイント
102 pobj_MainMenu->EnableItem(IDM_BREAKPOINT,MenuMsg);
103 pobj_DebuggerToolbar->EnableItem(IDM_BREAKPOINT,bBreakPoint);
104
105
106
107
108 //プラットフォームセレクト
109 extern HWND hSelectCompilerCombo;
110 EnableWindow(hSelectCompilerCombo,bEnableDocument);
111 }
112}
113
114void CDebugger::SaftyCheck(void){
115 extern HWND hCompileView;
116 if(!IsWindow(hCompileView)){
117 SendMessage(hOwner,WM_DESTROYDEBUGGERVIEW,0,0);
118 SendMessage(hOwner,WM_DESTROYDEBUGGERBASE,0,0);
119 SendMessage(hOwner,WM_DESTROYCOMPILEVIEW,0,0);
120 }
121}
122
123
124
125/////////////////////////////////////////
126// デバッグ開始
127/////////////////////////////////////////
128void CDebugger::begin(void){
129 bDebugging=1;
130
131 if(pobj_MainMenu){
132 //リリースコンパイルを無効化
133 pobj_MainMenu->EnableItem(IDM_RELEASECOMPILE,MF_BYCOMMAND|MF_GRAYED);
134 pobj_DebuggerToolbar->EnableItem(IDM_RELEASECOMPILE,0);
135
136 //デバッグコンパイルを無効化
137 pobj_MainMenu->EnableItem(IDM_DEBUGCOMPILE,MF_BYCOMMAND|MF_GRAYED);
138 pobj_DebuggerToolbar->EnableItem(IDM_DEBUGCOMPILE,0);
139
140 //デバッグ実行を無効化
141 pobj_MainMenu->EnableItem(IDM_DEBUG,MF_BYCOMMAND|MF_GRAYED);
142 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,0);
143
144 //ステップ実行を無効化
145 pobj_MainMenu->EnableItem(IDM_STEP_IN,MF_BYCOMMAND|MF_GRAYED);
146 pobj_MainMenu->EnableItem(IDM_STEP_OVER,MF_BYCOMMAND|MF_GRAYED);
147 pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MF_BYCOMMAND|MF_GRAYED);
148 pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,0);
149 pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,0);
150 pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,0);
151
152 //デバッグの一時停止を有効化
153 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MF_BYCOMMAND|MF_ENABLED);
154 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,1);
155
156 //デバッグの中断を有効化
157 pobj_MainMenu->EnableItem(IDM_DEBUG_STOP,MF_BYCOMMAND|MF_ENABLED);
158 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_STOP,1);
159 }
160}
161
162
163/////////////////////////////////////////
164// デバッグ終了
165/////////////////////////////////////////
166void CDebugger::end(void){
167 bDebugging=0;
168
169 if(pobj_MainMenu){
170 //リリースコンパイルを有効化
171 pobj_MainMenu->EnableItem(IDM_RELEASECOMPILE,MF_BYCOMMAND|MF_ENABLED);
172 pobj_DebuggerToolbar->EnableItem(IDM_RELEASECOMPILE,1);
173
174 //デバッグコンパイルを有効化
175 pobj_MainMenu->EnableItem(IDM_DEBUGCOMPILE,MF_BYCOMMAND|MF_ENABLED);
176 pobj_DebuggerToolbar->EnableItem(IDM_DEBUGCOMPILE,1);
177
178 //デバッグ実行を有効化
179 pobj_MainMenu->EnableItem(IDM_DEBUG,MF_BYCOMMAND|MF_ENABLED);
180 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,1);
181
182 //ステップ実行を無効化
183 pobj_MainMenu->EnableItem(IDM_STEP_IN,MF_BYCOMMAND|MF_GRAYED);
184 pobj_MainMenu->EnableItem(IDM_STEP_OVER,MF_BYCOMMAND|MF_GRAYED);
185 pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MF_BYCOMMAND|MF_GRAYED);
186 pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,0);
187 pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,0);
188 pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,0);
189
190 //デバッグの一時停止を無効化
191 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MF_BYCOMMAND|MF_GRAYED);
192 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,0);
193
194 //デバッグの中断を無効化
195 pobj_MainMenu->EnableItem(IDM_DEBUG_STOP,MF_BYCOMMAND|MF_GRAYED);
196 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_STOP,0);
197 }
198}
199
200
201/////////////////////////////////////////
202// 一時停止(ウォッチウィンドウが立ち上がる)
203/////////////////////////////////////////
204void CDebugger::watch_start(HWND hDebuggerView){
205 hwnd=hDebuggerView;
206
207 if(pobj_MainMenu){
208 //継続を有効化
209 pobj_MainMenu->EnableItem(IDM_DEBUG,MF_BYCOMMAND|MF_ENABLED);
210 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG,1);
211
212 //ステップ実行を有効化
213 pobj_MainMenu->EnableItem(IDM_STEP_IN,MF_BYCOMMAND|MF_ENABLED);
214 pobj_MainMenu->EnableItem(IDM_STEP_OVER,MF_BYCOMMAND|MF_ENABLED);
215 pobj_MainMenu->EnableItem(IDM_STEP_CURSOR,MF_BYCOMMAND|MF_ENABLED);
216 pobj_DebuggerToolbar->EnableItem(IDM_STEP_IN,1);
217 pobj_DebuggerToolbar->EnableItem(IDM_STEP_OVER,1);
218 pobj_DebuggerToolbar->EnableItem(IDM_STEP_CURSOR,1);
219
220 //デバッグの一時停止を無効化
221 pobj_MainMenu->EnableItem(IDM_DEBUG_PAUSE,MF_BYCOMMAND|MF_GRAYED);
222 pobj_DebuggerToolbar->EnableItem(IDM_DEBUG_PAUSE,0);
223 }
224}
225
226
227/////////////////////////////////////////
228// デバッグを再開
229/////////////////////////////////////////
230void CDebugger::watch_quit(void){
231 hwnd=0;
232
233 begin();
234}
235
236
237void CDebugger::DebugContinue(void){
238 if(hwnd) SendMessage(hwnd,WM_DEBUG_CONTINUE,0,0);
239}
240void CDebugger::StepIn(void){
241 if(hwnd) SendMessage(hwnd,WM_STEP_IN,0,0);
242}
243void CDebugger::StepOver(void){
244 if(hwnd) SendMessage(hwnd,WM_STEP_OVER,0,0);
245}
246void CDebugger::StepToCursor(void){
247 if(hwnd){
248 int WndNum;
249 WndNum=GetNowWndNum();
250 if(WndNum==-1) return;
251
252 char temporary[MAX_PATH];
253 sprintf(temporary,"\"%s\",%d",MdiInfo[WndNum].path.c_str(),MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
254
255 char temp2[MAX_PATH];
256 GetTempPath(MAX_PATH,temp2);
257 if(temp2[lstrlen(temp2)-1]!='\\') lstrcat(temp2,"\\");
258 lstrcat(temp2,"ab_breakpoint.tmp");
259
260 WriteBuffer(temp2,temporary,lstrlen(temporary));
261
262 SendMessage(hwnd,WM_STEP_CURSOR,0,0);
263 }
264}
265void CDebugger::DebugStop(void){
266 extern HWND hCompileView;
267 SendMessage(hCompileView,WM_DEBUG_STOP,0,0);
268}
269void CDebugger::DebugPause(void){
270 extern HWND hCompileView;
271 SendMessage(hCompileView,WM_DEBUG_PAUSE,0,0);
272}
273
274
275
276
277
278
279//////////////////////////
280// ブレークポイント
281//////////////////////////
282
283CFileBreakPoint::CFileBreakPoint(const char *lpszFileName,int iLineNum){
284 this->lpszFileName=(char *)HeapAlloc(hHeap,0,lstrlen(lpszFileName)+1);
285 lstrcpy(this->lpszFileName,lpszFileName);
286
287 piLine=(int *)HeapAlloc(hHeap,0,sizeof(int));
288 piLine[0]=iLineNum;
289 num=1;
290}
291CFileBreakPoint::~CFileBreakPoint(){
292 HeapDefaultFree(lpszFileName);
293 HeapDefaultFree(piLine);
294}
295void CFileBreakPoint::add(int iLineNum){
296 piLine=(int *)HeapReAlloc(hHeap,0,piLine,(num+1)*sizeof(int));
297
298 int i;
299 for(i=0;i<num;i++){
300 if(piLine[i]>iLineNum){
301 for(int i2=num;i2>i;i2--){
302 piLine[i2]=piLine[i2-1];
303 }
304 break;
305 }
306 }
307
308 piLine[i]=iLineNum;
309 num++;
310}
311void CFileBreakPoint::remove(int iLineNum){
312 int i;
313 for(i=0;i<num;i++){
314 if(iLineNum==piLine[i]) break;
315 }
316 if(i==num) return;
317
318 num--;
319 for(;i<num;i++){
320 piLine[i]=piLine[i+1];
321 }
322}
323BOOL CFileBreakPoint::check(int iLineNum){
324 int i;
325 for(i=0;i<num;i++){
326 if(iLineNum==piLine[i]) return 1;
327 }
328 return 0;
329}
330
331void CFileBreakPoint::replace(LPSTR lpszBuffer,CHARRANGE *pDelRange,CHARRANGE *pRange,LPSTR lpszNewStr){
332 int i;
333
334 //削除される行範囲を取得
335 int DelStartLine=0;
336 for(i=0;i<pDelRange->cpMin;i++){
337 if(IsReturnCode(lpszBuffer+i)){
338 DelStartLine++;
339 }
340 }
341
342 int DelEndLine=DelStartLine;
343 for(;i<pDelRange->cpMax;i++){
344 if(IsReturnCode(lpszBuffer+i)){
345 DelEndLine++;
346 }
347 }
348
349 //ブレークポイントを消去
350 for(i=0;i<num;i++){
351 if(DelStartLine<piLine[i]&&piLine[i]<DelEndLine){
352 remove(piLine[i]);
353 }
354 }
355
356
357 //新しく挿入される文字列の行数を計算する
358 int NewLineNum=0;
359 for(i=0;lpszNewStr[i];i++){
360 if(IsReturnCode(lpszNewStr+i)){
361 NewLineNum++;
362 }
363 }
364
365
366 //オフセットを計算
367 int offset=DelStartLine-DelEndLine+NewLineNum;
368
369
370 //挿入行以降の行にて、オフセットを反映される
371 for(i=0;i<num;i++){
372 if(DelStartLine<=piLine[i]){
373 piLine[i]+=offset;
374 }
375 }
376}
377
378
379
380CDBBreakPoint::CDBBreakPoint(){
381 ppItem=(CFileBreakPoint **)HeapAlloc(hHeap,0,1);
382 num=0;
383}
384CDBBreakPoint::~CDBBreakPoint(){
385 int i;
386 for(i=0;i<num;i++){
387 delete ppItem[i];
388 }
389 HeapDefaultFree(ppItem);
390}
391void CDBBreakPoint::insert( const char *lpszFileName,int iLineNum){
392 int i;
393 for(i=0;i<num;i++){
394 if(lstrcmpi(ppItem[i]->lpszFileName,lpszFileName)==0){
395 ppItem[i]->add(iLineNum);
396 return;
397 }
398 }
399
400 if(i==num){
401 ppItem=(CFileBreakPoint **)HeapReAlloc(hHeap,0,ppItem,(num+1)*sizeof(CFileBreakPoint *));
402 ppItem[num]=new CFileBreakPoint(lpszFileName,iLineNum);
403 num++;
404 }
405}
406void CDBBreakPoint::remove( const char *lpszFileName,int iLineNum){
407 int i;
408 for(i=0;i<num;i++){
409 if(lstrcmpi(lpszFileName,ppItem[i]->lpszFileName)==0){
410 ppItem[i]->remove(iLineNum);
411 break;
412 }
413 }
414 if(i==num) return;
415
416 if(ppItem[i]->num==0){
417 delete ppItem[i];
418
419 num--;
420 for(;i<num;i++){
421 ppItem[i]=ppItem[i+1];
422 }
423 }
424}
425
426void CDBBreakPoint::Event_BreakPoint(void){
427 int WndNum;
428 WndNum=GetNowWndNum();
429 if(WndNum==-1) return;
430
431 if( !Jenga::Common::Path( MdiInfo[WndNum].path ).IsExistFile() )
432 {
433 return;
434 }
435
436 int i,i2,sw=0;
437 for(i=0;i<num;i++){
438 if(lstrcmpi(MdiInfo[WndNum].path.c_str(),ppItem[i]->lpszFileName)==0){
439 for(i2=0;i2<ppItem[i]->num;i2++){
440 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==ppItem[i]->piLine[i2]){
441 sw=1;
442 break;
443 }
444 }
445 break;
446 }
447 }
448
449 if(sw==0){
450 //ブレークポイントを追加
451 insert(MdiInfo[WndNum].path.c_str(),MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
452 }
453 else{
454 //ブレークポイントを削除
455 remove(MdiInfo[WndNum].path.c_str(),MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
456 }
457
458 if(pobj_Debugger->IsDebugging()){
459 SaveToTempFile();
460
461 //デバッガにブレークポイント更新のメッセージを送る
462 //未完成
463 }
464
465 //エディタを再描画
466 InvalidateRect(MdiInfo[WndNum].pMdiTextEdit->hEdit,NULL,0);
467}
468void CDBBreakPoint::SaveToTempFile(void){
469 char *buffer;
470 int length=0;
471 buffer=(char *)HeapAlloc(hHeap,0,65535);
472 buffer[0]=0;
473 int i,i2;
474 for(i=0;i<num;i++){
475 sprintf(buffer+length,"\"%s\"",ppItem[i]->lpszFileName);
476 length+=lstrlen(buffer+length);
477
478 for(i2=0;i2<ppItem[i]->num;i2++){
479 sprintf(buffer+length,",%d",ppItem[i]->piLine[i2]);
480 length+=lstrlen(buffer+length);
481 }
482
483 lstrcpy(buffer+length,"\n");
484 length+=lstrlen(buffer+length);
485 }
486
487 HANDLE hFile;
488 char temporary[MAX_PATH];
489 GetTempPath(MAX_PATH,temporary);
490 if(temporary[lstrlen(temporary)-1]!='\\') lstrcat(temporary,"\\");
491 lstrcat(temporary,"ab_breakpoint.tmp");
492
493 //未完成
494 sprintf(temporary,"%sab_breakpoint.tmp",pj_editor_Dir);
495
496 hFile=CreateFile(temporary,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_TEMPORARY,NULL);
497 DWORD dwAccBytes;
498 WriteFile(hFile,buffer,lstrlen(buffer),&dwAccBytes,NULL);
499 CloseHandle(hFile);
500
501 HeapDefaultFree(buffer);
502}
503
504
505CFileBreakPoint *CDBBreakPoint::EnumLines(const char *lpszFilePath){
506 int i;
507 for(i=0;i<num;i++){
508 if(lstrcmpi(lpszFilePath,ppItem[i]->lpszFileName)==0){
509 return ppItem[i];
510 }
511 }
512 return 0;
513}
514
515void CDBBreakPoint::replace(const char *lpszFilePath,LPSTR lpszBuffer,CHARRANGE *pDelRange,CHARRANGE *pRange,LPSTR lpszNewStr){
516 int i;
517 for(i=0;i<num;i++){
518 if(lstrcmpi(ppItem[i]->lpszFileName,lpszFilePath)==0){
519 ppItem[i]->replace(lpszBuffer,pDelRange,pRange,lpszNewStr);
520 return;
521 }
522 }
523}
Note: See TracBrowser for help on using the repository browser.