#include "stdafx.h" #include #include #include #include #include "BasicCompiler.h" #if defined HeapAlloc #define MEM_MAX 65536 LPVOID pCheckMem[MEM_MAX]; int now; #undef HeapAlloc #undef HeapReAlloc LPVOID CheckHeapAlloc(HANDLE hf,DWORD dwFlags,DWORD dwBytes){ LPVOID ret; ret=HeapAlloc(hf,dwFlags,dwBytes); pCheckMem[now]=ret; //この部分にnowのチェックを挿入 now++; if(now>=MEM_MAX){ MessageBox(0,"pCheckMemの最大値を超えました","Check - BasicCompiler.exe",0); } return ret; } LPVOID CheckHeapReAlloc(HANDLE hf,DWORD dwFlags,LPVOID lpMem,DWORD dwBytes){ int i; LPVOID ret; for(i=0;;i++){ if(lpMem==pCheckMem[i]) break; if(i>=MEM_MAX){ MessageBox(0,"エラー","Check - BasicCompiler.exe",0); break; } } ret=HeapReAlloc(hf,dwFlags,lpMem,dwBytes); pCheckMem[i]=ret; return ret; } void HeapDefaultFree(LPVOID lpMem){ int i; for(i=0;;i++){ if(lpMem==pCheckMem[i]) break; if(i>=MEM_MAX||lpMem==0){ MessageBox(0,"エラー","Check - BasicCompiler.exe",0); break; } } pCheckMem[i]=0; HeapFree(hHeap,0,lpMem); } void CheckHeapCheck(){ int i,i2; char temp[100]; temp[0]=0; for(i=0,i2=0;i=0x0999 /* extern int obp; if(obp>=0x988DE){ int test=0; }*/ } void GetRelationalPath(char *path,char *dir){ //相対パスを取得 int i,i2,i3,i4,i5; char temporary[MAX_PATH],temp2[MAX_PATH],temp3[MAX_PATH],temp4[MAX_PATH]; //ドライブ名をチェック _splitpath(path,temporary,0,0,0); _splitpath(dir,temp2,0,0,0); if(lstrcmpi(temporary,temp2)!=0) return; _splitpath(path,0,temporary,0,0); _splitpath(dir,0,temp2,0,0); i=1;i2=1; while(1){ i4=i; if(temporary[i-1]=='\\'&&temporary[i]){ //path側 for(i3=0;;i++,i3++){ if(temporary[i]=='\\'){ temp3[i3]=0; i++; break; } temp3[i3]=temporary[i]; } } else temp3[0]=0; i5=i2; if(temp2[i2-1]=='\\'&&temp2[i2]){ //dir側 for(i3=0;;i2++,i3++){ if(temp2[i2]=='\\'){ temp4[i3]=0; i2++; break; } temp4[i3]=temp2[i2]; } } else temp4[0]=0; if(temp3[0]=='\0'&&temp4[0]=='\0'){ lstrcpy(temp3,".\\"); break; } if(lstrcmpi(temp3,temp4)!=0){ for(i3=0;;i5++){ if(temp2[i5]=='\0') break; if(temp2[i5]=='\\') i3++; } if(i3==0) lstrcpy(temp3,".\\"); else{ temp3[0]=0; for(i2=0;i2MainDlgPos; GetWindowRect(hwnd,&rect); size.cx=rect.right-rect.left; size.cy=rect.bottom-rect.top; MoveWindow(hwnd,pos.x,pos.y,size.cx,size.cy,1); char relationalPath[MAX_PATH]; lstrcpy(relationalPath,program.GetOutputFilePath().c_str()); GetRelationalPath(relationalPath,BasicCurDir); SetDlgItemText(hwnd,IDC_EXEPATH,relationalPath); //"エラー無し" SetDlgItemText(hwnd,IDC_ERRORLIST,STRING_NOERROR); //"デバッグ情報無し" SetDlgItemText(hwnd,IDC_DEBUGLIST,STRING_NODEBUGMSG); //リストボックスの初期位置 GetWindowRect(GetDlgItem(hwnd,IDC_ERRORLIST),&rect); pos_List.x=rect.left; pos_List.y=rect.top; ScreenToClient(hwnd,&pos_List); //プログレスバーの初期位置と高さ GetWindowRect(GetDlgItem(hwnd,IDC_PROGRESS),&rect); pos_Progress.x=rect.left; pos_Progress.y=rect.top; ScreenToClient(hwnd,&pos_Progress); height_Progress=rect.bottom-rect.top; //バージョン表記 sprintf(temporary,"Version %d.%02d.%02d %s",MAJOR_VER,MINOR_VER,REVISION_VER,VER_INFO); SetDlgItemText(hwnd,IDC_STATIC_VERSION,temporary); break; case WM_COMMAND: switch(LOWORD(wParam)){ case IDOK: GetDlgItemText(hwnd,IDOK,temporary,MAX_PATH); //STRING_COMPILE = "コンパイル" if(lstrcmp(temporary,STRING_COMPILE)==0){ char tempOutputFileName[MAX_PATH]; GetDlgItemText(hwnd,IDC_EXEPATH,tempOutputFileName,MAX_PATH); program.SetOutputFilePath( Jenga::Common::Path::MakeFullPath( tempOutputFileName, BasicCurDir ) ); _beginthread( &MainThread, NULL, NULL ); } //STRING_STOP = "中断" else if(lstrcmp(temporary,STRING_STOP)==0){ if(hDebugProcess){ //デバッグ中のとき //プロセスを終了 TerminateProcess(hDebugProcess,0); hDebugProcess=0; //デバッグダイアログを終了 if(hDebugWnd){ DestroyWindow(hDebugWnd); } } else{ //コンパイル中のとき bStopCompile=1; /* メインスレッドで「閉じる」ボタンに変更することで、 コンパイルを中断中の早いタイミングでも終了することが可能 */ //"閉じる" SetDlgItemText(hwnd,IDOK,STRING_CLOSE); } } else{ SetFocus(hOwnerEditor); DestroyWindow(hwnd); } return 1; case IDCANCEL: //×ボタン用 if(hDebugProcess){ //デバッグ中のとき //プロセスを終了 TerminateProcess(hDebugProcess,0); hDebugProcess=0; //デバッグダイアログを終了 if(hDebugWnd){ DestroyWindow(hDebugWnd); } } SetFocus(hOwnerEditor); DestroyWindow(hwnd); return 1; case IDC_SHOWERROR: ShowWindow(GetDlgItem(hwnd,IDC_ERRORLIST),SW_SHOW); ShowWindow(GetDlgItem(hwnd,IDC_DEBUGLIST),SW_HIDE); return 1; case IDC_SHOWDEBUG: ShowWindow(GetDlgItem(hwnd,IDC_ERRORLIST),SW_HIDE); ShowWindow(GetDlgItem(hwnd,IDC_DEBUGLIST),SW_SHOW); return 1; } break; case WM_SHOWVARLIST: if( program.IsClipCompileView() ){ //埋め込み表示 CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_DEBUGGER),hOwnerEditor,(DLGPROC)DlgDebugger,lParam); ShowWindow(hDebugWnd,SW_SHOW); SendMessage(hOwnerEditor,WM_SETDEBUGGERVIEW,0,(LPARAM)hDebugWnd); } else{ //ポップアップ表示 CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_VARLIST),hOwnerEditor,(DLGPROC)DlgVarList,lParam); SetForegroundWindow(hDebugWnd); } return 1; case WM_SIZE: if( program.IsClipCompileView() ){ //エラーリストの位置 MoveWindow(GetDlgItem(hwnd,IDC_ERRORLIST), pos_List.x, pos_List.y, LOWORD(lParam)-pos_List.x, HIWORD(lParam)-pos_List.y, 1); //デバッグリストの位置 MoveWindow(GetDlgItem(hwnd,IDC_DEBUGLIST), pos_List.x, pos_List.y, LOWORD(lParam)-pos_List.x, HIWORD(lParam)-pos_List.y, 1); //プログレスバーの位置 MoveWindow(GetDlgItem(hwnd,IDC_PROGRESS), pos_Progress.x, pos_Progress.y, LOWORD(lParam)-pos_Progress.x, height_Progress, 1); } return 1; case WM_DESTROY: GetWindowRect(hwnd,&rect); if( !program.IsClipCompileView() ){ pobj_nv->MainDlgPos.x=rect.left; pobj_nv->MainDlgPos.y=rect.top; } PostQuitMessage(0); return 1; /////////////////////// // デバッグコマンド /////////////////////// case WM_DEBUG_STOP: Debugger_Stop(); return 1; case WM_DEBUG_PAUSE: Debugger_Pause(); return 1; case WM_CLOSE_DEBUGGER: if(hDebugWnd){ DestroyWindow(hDebugWnd); } return 1; } return 0; } void _Test() { Jenga::Common::LoggerSetting loggerSetting; bool result = loggerSetting.WriteXml( Jenga::Common::Environment::GetAppDir() + "\\logger.setting.xml" ); } int main() { int i; char temporary[1024],temp2[MAX_PATH]; hInst = GetModuleHandle( NULL ); // グローバルローケルを日本語にする locale::global(locale("japanese")); _setmode(_fileno(stdout), _O_BINARY); //_Test(); //MessageBox(0,"starting compiler/debugger","ActiveBasic",MB_OK); trace( "Start ActiveBasic Compiler!" ); //コモンコントロールを初期化 InitCommonControls(); hHeap=GetProcessHeap(); ScreenX=GetSystemMetrics(SM_CXSCREEN); ScreenY=GetSystemMetrics(SM_CYSCREEN); //不揮発性データを取得 pobj_nv=new CNonVolatile; pobj_nv->load(); if( !program.AnalysisCommandLines() ) { // コマンドラインが不正 return 0; } bool isSpecifiedSourceFilePathByCommandLine = false; if( program.GetSourceFilePath().size() > 0 ) { // ソースファイル名が与えられていたとき isSpecifiedSourceFilePathByCommandLine = true; } else { // ソースファイル名が与えられなかったとき char temp[MAX_PATH]; if(!GetFilePathDialog(0,temp,BasicFileFilter,"コンパイルするファイルを指定して下さい",1)) { return 0; } program.SetSourceFilePath( temp ); } //出力ファイル名が与えられなかったとき if( program.GetOutputFilePath().size() == 0 ) { char tempOutputFileName[MAX_PATH]; _splitpath( program.GetSourceFilePath().c_str(), tempOutputFileName,temporary,temp2,0); lstrcat(tempOutputFileName,temporary); lstrcat(tempOutputFileName,temp2); if( compiler.IsStaticLibrary() ) { if( program.IsDebugRun() || compiler.IsDebug() ) { lstrcat(tempOutputFileName,"_debug.abobj"); } else { lstrcat(tempOutputFileName,".abobj"); } } else { if( program.IsDebugRun() || compiler.IsDebug() ) { lstrcat(tempOutputFileName,"_debug.exe"); } else { lstrcat(tempOutputFileName,".exe"); } } program.SetOutputFilePath( tempOutputFileName ); } { // カレントディレクトリを取得 std::string baseDirPath = Jenga::Common::Environment::GetAppDir()+"\\"; // インクルードディレクトリが指定されなかったとき if( program.GetIncludeDir().size() == 0 ) { program.SetIncludeDir( Jenga::Common::Path::MakeFullPath( ".\\Include\\", baseDirPath ) ); } else { // インクルードディレクトリを絶対パスに変更 program.SetIncludeDir( Jenga::Common::Path::MakeFullPath( program.GetIncludeDir(), baseDirPath ) ); } // ソースファイル名を絶対パスに変換 program.SetSourceFilePath( Jenga::Common::Path::MakeFullPath( program.GetSourceFilePath(), baseDirPath ) ); // 出力ファイル名を絶対パスに変換 program.SetOutputFilePath( Jenga::Common::Path::MakeFullPath( program.GetOutputFilePath(), baseDirPath ) ); // モジュール名をセット compiler.SetModuleName( Jenga::Common::Path( program.GetOutputFilePath() ).GetFileName() ); } if( compiler.IsDll() ) { //DLLファイル名を取得 _splitpath( program.GetOutputFilePath().c_str(),NULL,NULL,szDllName,temporary); lstrcat(szDllName,temporary); } if( program.IsDebugRun() ) { //コマンドライン、DLLの実行可能アプリケーションを取得 HANDLE hFile; DWORD dwAccessBytes; hFile=CreateFile( ( Jenga::Common::Environment::GetAppDir() + "\\pgm.tmp" ).c_str(), GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile!=INVALID_HANDLE_VALUE){ ReadFile(hFile,temporary,MAX_PATH,&dwAccessBytes,NULL); CloseHandle(hFile); temporary[dwAccessBytes]=0; } else temporary[0]=0; for(i=0;;i++){ if(temporary[i]=='\r'&&temporary[i+1]=='\n'||temporary[i]=='\0'){ szDebugExeForDll[i]=0; break; } szDebugExeForDll[i]=temporary[i]; } if(temporary[i]){ lstrcpy(szDebugCmdLine,temporary+i+2); } } _splitpath( program.GetSourceFilePath().c_str(), BasicCurDir,temporary,NULL,NULL); lstrcat(BasicCurDir,temporary); if( program.IsClipCompileView() ){ //ProjectEditor埋め込み型インターフェイス hMainDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_CLIPMAIN),hOwnerEditor,(DLGPROC)DlgCompile); ShowWindow(hMainDlg,SW_SHOW); SendMessage(hOwnerEditor,WM_SETCOMPILEVIEW,0,(LPARAM)hMainDlg); //プログレスバーの色をセットする PostMessage(GetDlgItem(hMainDlg,IDC_PROGRESS),PBM_SETBARCOLOR,0,RGB(255,220,192)); PostMessage(GetDlgItem(hMainDlg,IDC_PROGRESS),PBM_SETBKCOLOR,0,RGB(255,255,255)); } else{ //通常ダイアログインターフェイス hMainDlg=CreateDialog(hInst,MAKEINTRESOURCE(IDD_MAIN),hOwnerEditor,(DLGPROC)DlgCompile); if( program.IsKickedFromEditor() ) { // エディタから起動されたとき PostMessage( hMainDlg, WM_COMMAND, IDOK, 0 ); } else if( program.IsShowDlg() ) { // コマンドラインでshow_dlgパラメータが指定された場合、ダイアログを表示する // すぐにビルドを開始する ShowWindow(hMainDlg,SW_SHOW); PostMessage( hMainDlg, WM_COMMAND, IDOK, 0 ); } else if( isSpecifiedSourceFilePathByCommandLine ) { // コマンドラインでソースコード指定があった場合はウィンドウは表示せず、そのままビルドを開始する。 MainThread(0); trace("Complete ActiveBasic Compiler!"); ExitProcess( program.GetExitCode() ); return 0; } else { ShowWindow(hMainDlg,SW_SHOW); } } SendDlgItemMessage(hMainDlg,IDC_SHOWERROR,BM_SETCHECK,BST_CHECKED,0); //エラーリストをサブクラス化 OldErrorListProc=(WNDPROC)GetWindowLongPtr(GetDlgItem(hMainDlg,IDC_ERRORLIST),GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hMainDlg,IDC_ERRORLIST),GWLP_WNDPROC,(LONG_PTR)ErrorListProc); //デバッグリストをサブクラス化 OldDebugListProc=(WNDPROC)GetWindowLongPtr(GetDlgItem(hMainDlg,IDC_DEBUGLIST),GWLP_WNDPROC); SetWindowLongPtr(GetDlgItem(hMainDlg,IDC_DEBUGLIST),GWLP_WNDPROC,(LONG_PTR)DebugListProc); if( program.IsKickedFromEditor() ) { SendMessage(hMainDlg,WM_COMMAND,IDOK,0); } MSG msg; while(GetMessage(&msg,0,0,0)){ if(IsDialogMessage(hMainDlg,&msg)) continue; TranslateMessage(&msg); DispatchMessage(&msg); } //不揮発性データを保存 pobj_nv->save(); delete pobj_nv; pobj_nv=0; #if defined HeapAlloc CheckHeapCheck(); #endif if( program.IsClipCompileView() ){ SendMessage(hOwnerEditor,WM_DESTROYCOMPILEVIEW,0,0); } trace("Complete ActiveBasic Compiler!"); ExitProcess( program.GetExitCode() ); return 0; }