#include "stdafx.h" #include #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); lstrcpy(temporary,OutputFileName); GetRelationalPath(temporary,BasicCurDir); SetDlgItemText(hwnd,IDC_EXEPATH,temporary); //"エラー無し" 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){ GetDlgItemText(hwnd,IDC_EXEPATH,OutputFileName,MAX_PATH); GetFullPath(OutputFileName,BasicCurDir); CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MainThread,0,0,&dw); } //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(bClipCompileView){ //埋め込み表示 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(bClipCompileView){ //エラーリストの位置 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(!bClipCompileView){ 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; } bool AnalysisCommandLines( bool &isFromEditor ) { // 値を初期化 isFromEditor = false; // コマンドラインを解析 const Jenga::Common::CmdLines cmdLines( PathGetArgs( GetCommandLine() ) ); int cmdLineIndex = 0; if( cmdLines.size() == 0 ) { // 何も指定されていないとき return true; } if( cmdLines[cmdLineIndex].IsNamelessCommand() ) { // 先頭に無名コマンドがきた場合、ソースファイル名として認識する lstrcpy( SourceFileName, cmdLines[cmdLineIndex].GetParameter().c_str() ); cmdLineIndex ++; if( cmdLines.size() == 1 ) { // ソースファイル名のみの指定だったとき return true; } // 出力ファイル名を取得 if( cmdLines[cmdLineIndex].IsNamelessCommand() ) { // 二番目にも無名コマンドがきた場合、ソースファイル名として認識する lstrcpy( OutputFileName, cmdLines[cmdLineIndex].GetParameter().c_str() ); cmdLineIndex ++; } } for( ; cmdLineIndex < static_cast(cmdLines.size()); cmdLineIndex++ ) { const Jenga::Common::CmdLine &cmdLine = cmdLines[cmdLineIndex]; if( cmdLine.GetCommand() == "wnd" ) { // 親エディタのウィンドウ ハンドル isFromEditor = true; sscanf( cmdLine.GetParameter().c_str(), "%08x", &hOwnerEditor ); } else if( cmdLine.GetCommand() == "debug" ) { // デバッグ ビルド compiler.SetDebugMark( true ); } else if( cmdLine.GetCommand() == "run" ) { // デバッグ実行 bDebugRun = 1; } else if( cmdLine.GetCommand() == "attach" ) { // アタッチ bDebugRun=1; bAttach=1; sscanf( cmdLine.GetParameter().c_str(), "%08x", &dwAttachProcessId ); } else if( cmdLine.GetCommand() == "dll" ) { // DLLとしてビルド compiler.SetTargetModuleType( Compiler::Dll ); } else if( cmdLine.GetCommand() == "static_library" ) { // 静的リンクライブラリとしてビルド compiler.SetTargetModuleType( Compiler::StaticLibrary ); } else if( cmdLine.GetCommand() == "unicode" ) { // Unicode compiler.SetUnicodeMark( true ); typeOfPtrChar = MAKE_PTR_TYPE(DEF_WORD,1); typeOfPtrUChar = MAKE_PTR_TYPE(DEF_WORD,1); } else if( cmdLine.GetCommand() == "clip_compile_view" ) { //埋め込み型コンパイラビュー bClipCompileView = 1; } else if( cmdLine.GetCommand() == "include_dir" ) { //インクルード ディレクトリ lstrcpy( szIncludeDir, cmdLine.GetParameter().c_str() ); } else { // 不正なコマンド std::string keyword = cmdLine.GetCommand(); if( keyword.size() == 0 ) { keyword = cmdLine.GetParameter(); } std::cout << keyword << " コマンドとして認識できません。" << std::endl; return false; } } return true; } 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 ); //_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(); bool isFromEditor; if( !AnalysisCommandLines( isFromEditor ) ) { // コマンドラインが不正 return 0; } //ソースファイル名が与えられなかったとき if(SourceFileName[0]=='\0'){ if(!GetFilePathDialog(0,SourceFileName,BasicFileFilter,"コンパイルするファイルを指定して下さい",1)) return 0; } //出力ファイル名が与えられなかったとき if(OutputFileName[0]=='\0'){ _splitpath(SourceFileName,OutputFileName,temporary,temp2,0); lstrcat(OutputFileName,temporary); lstrcat(OutputFileName,temp2); if( compiler.IsStaticLibrary() ) { if( bDebugRun || compiler.IsDebug() ) { lstrcat(OutputFileName,"_debug.abobj"); } else { lstrcat(OutputFileName,".abobj"); } } else { if( bDebugRun || compiler.IsDebug() ) { lstrcat(OutputFileName,"_debug.exe"); } else { lstrcat(OutputFileName,".exe"); } } } { // カレントディレクトリを取得 std::string baseDirPath = Jenga::Common::Environment::GetAppDir()+"\\"; // インクルードディレクトリが指定されなかったとき if(szIncludeDir[0]=='\0'){ lstrcpy(szIncludeDir,".\\Include\\"); // インクルードディレクトリを絶対パスに変更 GetFullPath(szIncludeDir,baseDirPath.c_str()); } else { // インクルードディレクトリを絶対パスに変更 GetFullPath(szIncludeDir,baseDirPath.c_str()); } // ソースファイル名を絶対パスに変換 GetFullPath(SourceFileName,baseDirPath.c_str()); // 出力ファイル名を絶対パスに変換 GetFullPath(OutputFileName,baseDirPath.c_str()); // モジュール名をセット compiler.SetModuleName( Jenga::Common::Path( OutputFileName ).GetFileName() ); } if( compiler.IsDll() ){ //DLLファイル名を取得 _splitpath(OutputFileName,NULL,NULL,szDllName,temporary); lstrcat(szDllName,temporary); } if(bDebugRun){ //コマンドライン、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(SourceFileName,BasicCurDir,temporary,NULL,NULL); lstrcat(BasicCurDir,temporary); if(bClipCompileView){ //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); #ifdef _DEBUG // VC++によるデバッグの場合は画面を出さない // ※別スレッドのウィンドウ ループとの不整合性がデッドロックを生む場合がある(特にステップ実行時など) PostMessage( hMainDlg, WM_COMMAND, IDOK, 0 ); #else ShowWindow(hMainDlg,SW_SHOW); #endif } 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( isFromEditor ) { 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(bClipCompileView){ SendMessage(hOwnerEditor,WM_DESTROYCOMPILEVIEW,0,0); } trace("Complete ActiveBasic Compiler!"); ExitProcess( 0 ); return 0; }