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

Last change on this file since 681 was 651, checked in by dai_9181, 15 years ago

・BreakPoint周りをリファクタリング
・FileTree周りをリファクタリング

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
283BreakPointsPerFile::BreakPointsPerFile(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}
291BreakPointsPerFile::~BreakPointsPerFile(){
292    HeapDefaultFree(lpszFileName);
293    HeapDefaultFree(piLine);
294}
295void BreakPointsPerFile::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 BreakPointsPerFile::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 BreakPointsPerFile::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 BreakPointsPerFile::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=(BreakPointsPerFile **)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=(BreakPointsPerFile **)HeapReAlloc(hHeap,0,ppItem,(num+1)*sizeof(BreakPointsPerFile *));
402        ppItem[num]=new BreakPointsPerFile(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
505BreakPointsPerFile *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.