source: dev/ProjectEditor/Debugger.cpp@ 22

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

バックアップ用ディレクトリが消去されていたときは、自動生成する。
プロ版の概念を除去。機能制限を解除。

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