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

Last change on this file since 478 was 475, checked in by dai_9181, 17 years ago

構成管理を変更中・・・(いったんコミット)

File size: 13.2 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.name[0]){
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,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(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(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(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(!IsExistFile(MdiInfo[WndNum].path)) return;
432
433 int i,i2,sw=0;
434 for(i=0;i<num;i++){
435 if(lstrcmpi(MdiInfo[WndNum].path,ppItem[i]->lpszFileName)==0){
436 for(i2=0;i2<ppItem[i]->num;i2++){
437 if(MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y==ppItem[i]->piLine[i2]){
438 sw=1;
439 break;
440 }
441 }
442 break;
443 }
444 }
445
446 if(sw==0){
447 //ブレークポイントを追加
448 insert(MdiInfo[WndNum].path,MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
449 }
450 else{
451 //ブレークポイントを削除
452 remove(MdiInfo[WndNum].path,MdiInfo[WndNum].pMdiTextEdit->StartCaretPos.y);
453 }
454
455 if(pobj_Debugger->IsDebugging()){
456 SaveToTempFile();
457
458 //デバッガにブレークポイント更新のメッセージを送る
459 //未完成
460 }
461
462 //エディタを再描画
463 InvalidateRect(MdiInfo[WndNum].pMdiTextEdit->hEdit,NULL,0);
464}
465void CDBBreakPoint::SaveToTempFile(void){
466 char *buffer;
467 int length=0;
468 buffer=(char *)HeapAlloc(hHeap,0,65535);
469 buffer[0]=0;
470 int i,i2;
471 for(i=0;i<num;i++){
472 sprintf(buffer+length,"\"%s\"",ppItem[i]->lpszFileName);
473 length+=lstrlen(buffer+length);
474
475 for(i2=0;i2<ppItem[i]->num;i2++){
476 sprintf(buffer+length,",%d",ppItem[i]->piLine[i2]);
477 length+=lstrlen(buffer+length);
478 }
479
480 lstrcpy(buffer+length,"\n");
481 length+=lstrlen(buffer+length);
482 }
483
484 HANDLE hFile;
485 char temporary[MAX_PATH];
486 GetTempPath(MAX_PATH,temporary);
487 if(temporary[lstrlen(temporary)-1]!='\\') lstrcat(temporary,"\\");
488 lstrcat(temporary,"ab_breakpoint.tmp");
489
490 //未完成
491 sprintf(temporary,"%sab_breakpoint.tmp",pj_editor_Dir);
492
493 hFile=CreateFile(temporary,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_TEMPORARY,NULL);
494 DWORD dwAccBytes;
495 WriteFile(hFile,buffer,lstrlen(buffer),&dwAccBytes,NULL);
496 CloseHandle(hFile);
497
498 HeapDefaultFree(buffer);
499}
500
501
502CFileBreakPoint *CDBBreakPoint::EnumLines(char *lpszFilePath){
503 int i;
504 for(i=0;i<num;i++){
505 if(lstrcmpi(lpszFilePath,ppItem[i]->lpszFileName)==0){
506 return ppItem[i];
507 }
508 }
509 return 0;
510}
511
512void CDBBreakPoint::replace(LPSTR lpszFilePath,LPSTR lpszBuffer,CHARRANGE *pDelRange,CHARRANGE *pRange,LPSTR lpszNewStr){
513 int i;
514 for(i=0;i<num;i++){
515 if(lstrcmpi(ppItem[i]->lpszFileName,lpszFilePath)==0){
516 ppItem[i]->replace(lpszBuffer,pDelRange,pRange,lpszNewStr);
517 return;
518 }
519 }
520}
Note: See TracBrowser for help on using the repository browser.