source: dev/trunk/abdev/ProjectEditor/Debugger.cpp@ 262

Last change on this file since 262 was 58, checked in by dai_9181, 18 years ago

TheTextのコンパイルを通るようにした。

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