#include "../BasicCompiler_Common/common.h" #ifdef _AMD64_ #include "../BasicCompiler64/opcode.h" #else #include "../BasicCompiler32/opcode.h" #endif ////////////////////////////////////// // #requireの管理 ////////////////////////////////////// class CRequireFiles{ char **ppFilePath; int count; public: CRequireFiles(){ ppFilePath = (char **)malloc( 1 ); count = 0; } ~CRequireFiles(){ for( int i = 0; i < count; i++ ){ free( ppFilePath[i] ); } free( ppFilePath ); } bool IsIncluded( const char *FilePath ){ for( int i = 0; i < count; i++ ){ if( lstrcmpi( ppFilePath[i], FilePath ) == 0 ){ return true; } } return false; } void Add( const char *FilePath ){ //既に読み込まれているとき if( IsIncluded( FilePath ) ) return; //追加 ppFilePath = (char **)realloc(ppFilePath, ( count + 1 ) * sizeof(char *) ); ppFilePath[count] = (char *)malloc( lstrlen(FilePath) + 1 ); lstrcpy( ppFilePath[count], FilePath ); count++; } }; CRequireFiles *pRequireFiles; ////////////////////////////////////// // #define間するクラス ////////////////////////////////////// class CDefine{ int num; char **ppNames; public: CDefine(); ~CDefine(); BOOL add(char *name); BOOL undef(char *name); BOOL check(char *name); }; CDefine::CDefine(){ extern HANDLE hHeap; ppNames=(char **)HeapAlloc(hHeap,0,1); num=0; extern BOOL bDebugCompile; if(bDebugCompile) add("_DEBUG"); #ifdef _AMD64_ add("_WIN64"); #endif char temporary[255]; sprintf(temporary,"_AB_VER%d",MAJOR_VER); add(temporary); } CDefine::~CDefine(){ int i; for(i=0;icheck(temporary)) sw=1; if(bndef){ //#ifndefのとき(反対にする) if(sw) sw=0; else sw=1; } //#ifdefの行を消去 SlideString(buffer+i,-i); i=0; BOOL bElse=0; if(sw){ //TRUEのとき //#else、#endifを探索 for(;;i++){ if(buffer[i]=='\0') break; if(i==0||buffer[i-1]=='\n'){ if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){ i=Search_endif(buffer,i+6); if(buffer[i]=='\0') break; continue; } else if(_memicmp(buffer+i,"#else",5)==0){ i2=5; bElse=1; break; } else if(_memicmp(buffer+i,"#endif",6)==0){ i2=6; bElse=0; break; } } } //行を消去 SlideString(buffer+i+i2,-i2); if(bElse){ //#elseがある場合はその区間を消去 for(i2=i,i3=0;;i2++){ if(buffer[i2]=='\0') break; if(buffer[i2]=='\n') i3++; if(i2==0||buffer[i2-1]=='\n'){ if(_memicmp(buffer+i2,"#ifdef",6)==0||_memicmp(buffer+i2,"#ifndef",7)==0){ i2=Search_endif(buffer,i2+6); if(buffer[i2]=='\0') break; continue; } if(_memicmp(buffer+i2,"#endif",6)==0){ i2+=6; break; } } } //ソースコード区間を消去し、改行コードを挿入 SlideString(buffer+i2,i-i2+i3); memset(buffer+i,'\n',i3); } } else{ //FALSEのとき //#else、#endifを探索 for(i2=i,i3=0;;i2++){ if(buffer[i2]=='\0') break; if(buffer[i2]=='\n') i3++; if(i2==0||buffer[i2-1]=='\n'){ if(_memicmp(buffer+i2,"#ifdef",6)==0||_memicmp(buffer+i2,"#ifndef",7)==0){ i2=Search_endif(buffer,i2+6); if(buffer[i2]=='\0') break; continue; } else if(_memicmp(buffer+i2,"#else",5)==0){ i2+=5; bElse=1; break; } else if(_memicmp(buffer+i2,"#endif",6)==0){ i2+=6; bElse=0; break; } } } //ソースコード区間を消去し、改行コードを挿入 SlideString(buffer+i2,i-i2+i3); memset(buffer+i,'\n',i3); if(bElse){ //#endifを探索 for(;;i++){ if(buffer[i]=='\0') break; if(i==0||buffer[i-1]=='\n'){ if(_memicmp(buffer+i,"#ifdef",6)==0||_memicmp(buffer+i,"#ifndef",7)==0){ i=Search_endif(buffer,i+6); if(buffer[i]=='\0') break; continue; } else if(_memicmp(buffer+i,"#endif",6)==0){ i2=6; bElse=0; break; } } } //行を消去 SlideString(buffer+i+i2,-i2); } } } void DirectiveIfdef(char *buffer){ int i,i2,i3,sw; char temporary[VN_SIZE]; for(i=0;;i++){ if(buffer[i]=='\0') break; if(i==0||buffer[i-1]=='\n'){ sw=0; if(_memicmp(buffer+i,"#define",7)==0){ i2=i+7; while(buffer[i2]==' '||buffer[i2]=='\t') i2++; for(i3=0;;i2++,i3++){ if(buffer[i2]=='\n'||buffer[i2]=='\0'){ temporary[i3]=0; break; } temporary[i3]=buffer[i2]; } pobj_define->add(temporary); i2-=i; //ディレクティブを消去 SlideString(buffer+i+i2,-i2); } if(_memicmp(buffer+i,"#undef",6)==0){ i2=i+7; while(buffer[i2]==' '||buffer[i2]=='\t') i2++; for(i3=0;;i2++,i3++){ if(buffer[i2]=='\n'||buffer[i2]=='\0'){ temporary[i3]=0; break; } temporary[i3]=buffer[i2]; } pobj_define->undef(temporary); i2-=i; //ディレクティブを消去 SlideString(buffer+i+i2,-i2); } else if(_memicmp(buffer+i,"#ifdef",6)==0){ preprocessor_ifdef(buffer+i,0); continue; } else if(_memicmp(buffer+i,"#ifndef",7)==0){ preprocessor_ifdef(buffer+i,1); continue; } else continue; } } } char *IncludeFiles(char *base){ extern HANDLE hHeap; extern char szIncludeDir[MAX_PATH]; extern char BasicCurDir[MAX_PATH]; extern INCLUDEFILEINFO IncludeFileInfo; int i,i2,i3,sw1,FileSize,LineNum,FileLayer[255],layer,LastFileByte[255]; char *buffer,temporary[MAX_PATH],temp2[MAX_PATH+255],*LayerDir[255]; IncludeFileInfo.ppFileNames=(char **)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(char *)); extern char SourceFileName[MAX_PATH]; IncludeFileInfo.ppFileNames[0]=(char *)HeapAlloc(hHeap,0,lstrlen(SourceFileName)+1); lstrcpy(IncludeFileInfo.ppFileNames[0],SourceFileName); IncludeFileInfo.FilesNum=1; buffer=base+2; layer=0; FileLayer[layer]=0; LastFileByte[layer]=lstrlen(buffer); LineNum=0; //参照ディレクトリ LayerDir[0]=(char *)HeapAlloc(hHeap,0,lstrlen(BasicCurDir)+1); lstrcpy(LayerDir[0],BasicCurDir); for(i=0;;i++){ if(buffer[i]=='\0'){ IncludeFileInfo.LineOfFile[LineNum]=-1; break; } if(buffer[i]=='\n'){ IncludeFileInfo.LineOfFile[LineNum]=FileLayer[layer]; LineNum++; } if(i>LastFileByte[layer]){ HeapDefaultFree(LayerDir[layer]); layer--; } if(buffer[i-1]=='\n'&&buffer[i]=='#'){ bool isRequire = false; if(memcmp( buffer + i + 1, "include", 7 ) == 0 || memcmp( buffer + i + 1, "require", 7 ) == 0){ //#requireの場合 if( buffer[i + 1] == 'r' ) isRequire = true; i2=i+8; while(buffer[i2]==' '||buffer[i2]=='\t') i2++; if(buffer[i2]=='\"') sw1=0; else if(buffer[i2]=='<') sw1=1; i2++; for(i3=0;;i2++,i3++){ if((buffer[i2]=='\"'&&sw1==0)||(buffer[i2]=='>'&&sw1==1)||buffer[i2]=='\n'||buffer[i2]=='\0'){ temporary[i3]=0; break; } temporary[i3]=buffer[i2]; } while(buffer[i2]!='\n'&&buffer[i2]!='\0') i2++; if(sw1){ sprintf(temp2,"%s%s",szIncludeDir,temporary); lstrcpy(temporary,temp2); } else GetFullPath(temporary,LayerDir[layer]); } else if(memcmp(buffer+i+1,"prompt",6)==0){ i2=i+7; sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir); } else if(memcmp(buffer+i+1,"N88BASIC",8)==0){ i2=i+9; sprintf(temporary,"%sbasic\\prompt.sbp",szIncludeDir); } else if(memcmp(buffer+i+1,"console",7)==0){ //サブシステム タイプをCUIに変更 extern unsigned short TypeOfSubSystem; TypeOfSubSystem=IMAGE_SUBSYSTEM_WINDOWS_CUI; i2=i+8; sprintf(temporary,"%sbasic\\dos_console.sbp",szIncludeDir); } else continue; if(i){ //ディレクティブが消えるため、一行減ってしまうのを防ぐ(basic.sbpを除く) SlideString(buffer+i2,1); buffer[i2]='\n'; for(i3=0;i3<=layer;i3++) LastFileByte[i3]++; } IncludeFileInfo.ppFileNames=(char **)HeapReAlloc(hHeap,0,IncludeFileInfo.ppFileNames,(IncludeFileInfo.FilesNum+1)*sizeof(char *)); IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1); lstrcpy(IncludeFileInfo.ppFileNames[IncludeFileInfo.FilesNum],temporary); layer++; FileLayer[layer]=IncludeFileInfo.FilesNum; IncludeFileInfo.FilesNum++; //#requireの場合では、既に読み込まれているファイルは読み込まないようにする bool isFake = false; if( isRequire ){ if( pRequireFiles->IsIncluded( temporary ) ){ //既に読み込まれているとき isFake = true; } } char *temp3; if( isFake ){ //既に読み込まれているときは空データを生成 temp3 = (char *)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1);; FileSize = 0; } else{ //取り込まれたファイルを収集する pRequireFiles->Add( temporary ); //インクルードファイルを読み込む DWORD AccBytes; HANDLE hFile=CreateFile(temporary,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile==INVALID_HANDLE_VALUE){ sprintf(temp2,"インクルードファイル \"%s\" をオープンできません",temporary); extern char *basbuf; basbuf=base+2; SetError(-1,temp2,i); break; } FileSize=GetFileSize(hFile,NULL); //読み込み temp3=(char *)HeapAlloc(hHeap,0,FileSize+1); ReadFile(hFile,temp3,FileSize,&AccBytes,NULL); temp3[AccBytes]=0; CloseHandle(hFile); //CRLFをLFに変換 ChangeReturnCode(temp3); //コメント削除 DeleteComment(temp3); //#ifdefディレクティブ DirectiveIfdef(temp3); FileSize=lstrlen(temp3); } i3=lstrlen(buffer)+FileSize; base=(char *)HeapReAlloc(hHeap,HEAP_ZERO_MEMORY,base,i3*2); buffer=base+2; SlideString(buffer+i2,FileSize+(i-i2)); memcpy(buffer+i,temp3,FileSize); //クローズ HeapDefaultFree(temp3); //新しい参照ディレクトリをセット char temp4[MAX_PATH]; _splitpath(temporary,temp2,temp4,0,0); lstrcat(temp2,temp4); LayerDir[layer]=(char *)HeapAlloc(hHeap,0,lstrlen(temp2)+1); lstrcpy(LayerDir[layer],temp2); //ファイル範囲をスライド LastFileByte[layer]=i+FileSize-1; for(i3=0;i3\n"); buffer+=lstrlen(buffer); //読み込み ReadFile(hFile,buffer,dwFileSize,&dwAccBytes,0); buffer[dwAccBytes]=0; //CRLFをLFに変換 ChangeReturnCode(buffer); //コメント削除 DeleteComment(buffer); //#ifdefディレクティブ DirectiveIfdef(buffer); //最終行には文字を含ませないようにする lstrcat(buffer,"\n"); //ファイルクローズ CloseHandle(hFile); //インクルードファイルを読み込む pRequireFiles = new CRequireFiles(); base=IncludeFiles(base); delete pRequireFiles; //#define情報を破棄 delete pobj_define; pobj_define=0; return base; }