#include "stdafx.h" #include "common.h" /////////////////////////////////////////////////////////////////// // ここから、ペアステートメント補完を行うための関数郡 /////////////////////////////////////////////////////////////////// int GetStartCommandId_FromBuffer(char *buffer){ int i; char temporary[VN_SIZE]; for(i=0;;i++){ if(!IsVariableChar(buffer[i])){ temporary[i]=0; break; } temporary[i]=buffer[i]; } if(lstrcmpi(temporary,"If")==0){ //If文の場合はブロック形式の有無を判定 int IsStr=0; for(;;i++){ if(buffer[i]=='\"') IsStr^=1; if((buffer[i]=='\''||IsCommandDelimitation(buffer,i))&&IsStr==0){ i--; break; } } while(buffer[i]==' '||buffer[i]=='\t') i--; if(memicmp(buffer+i-3,"Then",4)==0){ //ブロック形式のIf return COM_IF; } else{ //一行のみのIf return 0; } } if(lstrcmpi(temporary,"Virtual")==0|| lstrcmpi(temporary,"Override")==0|| lstrcmpi(temporary,"Static")==0){ if(temporary[0]=='s'||temporary[0]=='S') i=7; else if(temporary[0]=='v'||temporary[0]=='V') i=8; else i=9; while(buffer[i]==' '||buffer[i]=='\t') i++; int i2; for(i2=0;;i++,i2++){ if(!IsVariableChar(buffer[i])){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(lstrcmpi(temporary,"Function")==0) return COM_FUNCTION; if(lstrcmpi(temporary,"Sub")==0) return COM_SUB; return 0; } if(lstrcmpi(temporary,"Class")==0) return COM_CLASS; if(lstrcmpi(temporary,"Interface")==0) return COM_INTERFACE; if(lstrcmpi(temporary,"Do")==0) return COM_DO; if(lstrcmpi(temporary,"Enum")==0) return COM_ENUM; if(lstrcmpi(temporary,"For")==0) return COM_FOR; if(lstrcmpi(temporary,"Foreach")==0) return COM_FOR; if(lstrcmpi(temporary,"Function")==0) return COM_FUNCTION; if(lstrcmpi(temporary,"Namespace")==0) return COM_NAMESPACE; if(lstrcmpi(temporary,"Select")==0) return COM_SELECT; if(lstrcmpi(temporary,"Sub")==0) return COM_SUB; if(lstrcmpi(temporary,"Try")==0) return COM_TRY; if(lstrcmpi(temporary,"Type")==0) return COM_TYPE; if(lstrcmpi(temporary,"While")==0) return COM_WHILE; if(lstrcmpi(temporary,"With")==0) return COM_WITH; return 0; } int GetEndCommandId_FromBuffer(char *buffer){ int i,i2; char temporary[VN_SIZE]; for(i=0,i2=0;;i++,i2++){ if(!IsVariableChar(buffer[i])){ temporary[i2]=0; if(lstrcmpi(temporary,"End")==0&& (buffer[i]==' '||buffer[i]=='\t')){ while(buffer[i]==' '||buffer[i]=='\t') i++; i--; i2--; continue; } break; } temporary[i2]=buffer[i]; } if(lstrcmpi(temporary,"EndClass")==0) return COM_CLASS; if(lstrcmpi(temporary,"EndInterface")==0) return COM_INTERFACE; if(lstrcmpi(temporary,"Loop")==0) return COM_DO; if(lstrcmpi(temporary,"EndEnum")==0) return COM_ENUM; if(lstrcmpi(temporary,"Next")==0) return COM_FOR; if(lstrcmpi(temporary,"EndFunction")==0) return COM_FUNCTION; if(lstrcmpi(temporary,"EndIf")==0) return COM_IF; if(lstrcmpi(temporary,"EndNamespace")==0) return COM_NAMESPACE; if(lstrcmpi(temporary,"EndSelect")==0) return COM_SELECT; if(lstrcmpi(temporary,"EndSub")==0) return COM_SUB; if(lstrcmpi(temporary,"EndTry")==0) return COM_TRY; if(lstrcmpi(temporary,"EndType")==0) return COM_TYPE; if(lstrcmpi(temporary,"Wend")==0) return COM_WHILE; if(lstrcmpi(temporary,"EndWith")==0) return COM_WITH; return 0; } void GetNameOfEndCommand(int CmdId,char *buffer){ switch(CmdId){ case COM_CLASS: lstrcpy(buffer,"End Class"); break; case COM_INTERFACE: lstrcpy(buffer,"End Interface"); break; case COM_DO: lstrcpy(buffer,"Loop"); break; case COM_ENUM: lstrcpy(buffer,"End Enum"); break; case COM_FOR: lstrcpy(buffer,"Next"); break; case COM_FUNCTION: lstrcpy(buffer,"End Function"); break; case COM_IF: lstrcpy(buffer,"End If"); break; case COM_NAMESPACE: lstrcpy(buffer,"End Namespace"); break; case COM_SELECT: lstrcpy(buffer,"End Select"); break; case COM_SUB: lstrcpy(buffer,"End Sub"); break; case COM_TRY: lstrcpy(buffer,"End Try"); break; case COM_TYPE: lstrcpy(buffer,"End Type"); break; case COM_WHILE: lstrcpy(buffer,"Wend"); break; case COM_WITH: lstrcpy(buffer,"End With"); break; } } BOOL IsIntoStringQuotes(char *buffer,int i){ int i2; i2=i; while(i2&&buffer[i2]!='\n') i2--; if(i2==-1) i2=0; if(buffer[i2]=='\n') i2++; int IsStr=0; for(;i2=0;i--){ i2=IsCommandDelimitation(buffer,i); if(i2) break; } while(1){ //i2に一行前の先頭位置を格納 for(i--;i>=0;i--){ i2=IsCommandDelimitation(buffer,i); if(i2){ if(IsIntoStringQuotes(buffer,i)){ //文字列中の場合 continue; } if(i2==1) i2=i+1; else{ i2=i+2; LineNum++; if(LineNum>pobj_nv->BackNum_PairStatementComplement){ //設定された行数を超えた場合 return 0; } } break; } } if(i==-1) i2=i+1; //インデント文字列をindentにコピー for(i3=0;;i2++,i3++){ if(buffer[i2]!='\t'){ indent[i3]=0; break; } indent[i3]=buffer[i2]; } //空白文字を飛び越す while(buffer[i2]==' '||buffer[i2]=='\t') i2++; //終了コマンドを取得(End Class、End Sub、Next、Wendなど…) i3=GetEndCommandId_FromBuffer(buffer+i2); if(i3){ sp++; stack[sp]=i3; } //開始コマンドを取得(Class、Sub、For、Whileなど…) i3=GetStartCommandId_FromBuffer(buffer+i2); if(i3){ if(sp==-1){ CmdId=i3; break; } if(stack[sp]!=i3) return 0; sp--; } if(i<=0) break; } if(!CmdId) return 0; extern HANDLE hHeap; extern COMPLEMENT_WINDOW_INFO ComplementWndInfo; if(CmdId==COM_IF){ //Else、ElseIf、End Ifをリストに追加 /////////////////////// // 補完情報 /////////////////////// ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*2); ComplementWndInfo.MemberNum=2; ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,5); lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"Else"); ComplementWndInfo.pMemberInfo[0].dwProc=0; ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,7); lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"End If"); ComplementWndInfo.pMemberInfo[1].dwProc=0; ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND; } else if(CmdId==COM_CLASS){ ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*4); ComplementWndInfo.MemberNum=4; ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,10); lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"End Class"); ComplementWndInfo.pMemberInfo[0].dwProc=0; ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,8); lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"Private"); ComplementWndInfo.pMemberInfo[1].dwProc=0; ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[2].pName=(char *)HeapAlloc(hHeap,0,10); lstrcpy(ComplementWndInfo.pMemberInfo[2].pName,"Protected"); ComplementWndInfo.pMemberInfo[2].dwProc=0; ComplementWndInfo.pMemberInfo[2].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[3].pName=(char *)HeapAlloc(hHeap,0,7); lstrcpy(ComplementWndInfo.pMemberInfo[3].pName,"Public"); ComplementWndInfo.pMemberInfo[3].dwProc=0; ComplementWndInfo.pMemberInfo[3].dwAccess=ACCESS_PAIRCOMMAND; } else if(CmdId==COM_SELECT){ ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*4); ComplementWndInfo.MemberNum=2; ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,10); lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"End Select"); ComplementWndInfo.pMemberInfo[0].dwProc=0; ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,8); lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"Case"); ComplementWndInfo.pMemberInfo[1].dwProc=0; ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND; } else if(CmdId==COM_TRY){ ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)*4); ComplementWndInfo.MemberNum=3; ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,10); lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,"End Try"); ComplementWndInfo.pMemberInfo[0].dwProc=0; ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[1].pName=(char *)HeapAlloc(hHeap,0,10); lstrcpy(ComplementWndInfo.pMemberInfo[1].pName,"Catch"); ComplementWndInfo.pMemberInfo[1].dwProc=0; ComplementWndInfo.pMemberInfo[1].dwAccess=ACCESS_PAIRCOMMAND; ComplementWndInfo.pMemberInfo[2].pName=(char *)HeapAlloc(hHeap,0,8); lstrcpy(ComplementWndInfo.pMemberInfo[2].pName,"Finally"); ComplementWndInfo.pMemberInfo[2].dwProc=0; ComplementWndInfo.pMemberInfo[2].dwAccess=ACCESS_PAIRCOMMAND; } else{ //その他のコマンド //エンドペアステートメントの名前を取得 GetNameOfEndCommand(CmdId,epcName); /////////////////////// // 補完情報 /////////////////////// ComplementWndInfo.pMemberInfo=(MEMBERINFO *)HeapAlloc(hHeap,0,sizeof(MEMBERINFO)); ComplementWndInfo.MemberNum=1; ComplementWndInfo.pMemberInfo[0].pName=(char *)HeapAlloc(hHeap,0,lstrlen(epcName)+1); lstrcpy(ComplementWndInfo.pMemberInfo[0].pName,epcName); ComplementWndInfo.pMemberInfo[0].dwProc=0; ComplementWndInfo.pMemberInfo[0].dwAccess=ACCESS_PAIRCOMMAND; } lstrcpy(ComplementWndInfo.szIndent,indent); return 1; } BOOL IsNeedNewIndentCommand(char *name){ if(lstrcmpi(name,"Case")==0) return 1; return 0; } /////////////////////////////////////////////// // Withで構成されるオブジェクト識別子を取得 /////////////////////////////////////////////// void GetWithObjectVariable(char *buffer,int p,char *pObjectVar){ int i,i2,i3,i4,CmdId; char LineNum; char temporary[VN_SIZE]; int stack[255]; int sp; CmdId=0; LineNum=0; sp=-1; pObjectVar[0]=0; i=p; //入力中の行を除く for(i--;i>=0;i--){ i2=IsCommandDelimitation(buffer,i); if(i2) break; } while(1){ //i2に一行前の先頭位置を格納 for(i--;i>=0;i--){ i2=IsCommandDelimitation(buffer,i); if(i2){ if(i2==1) i2=i+1; else{ i2=i+2; LineNum++; if(LineNum>pobj_nv->BackNum_PairStatementComplement){ //設定された行数を超えた場合 return; } } break; } } if(i==-1) i2=i+1; //インデントを飛び越す while(buffer[i2]==' '||buffer[i2]=='\t') i2++; //終了コマンドを取得(End Class、End Sub、Next、Wendなど…) CmdId=GetEndCommandId_FromBuffer(buffer+i2); if(CmdId){ sp++; stack[sp]=CmdId; } //開始コマンドを取得(Class、Sub、For、Whileなど…) CmdId=GetStartCommandId_FromBuffer(buffer+i2); if(CmdId){ if(sp==-1){ if(CmdId==COM_WITH){ //オブジェクト識別子を付加 i2+=5; while(buffer[i2]==' '||buffer[i2]=='\t') i2++; for(i3=0;;i2++,i3++){ if(buffer[i2]=='-'&&buffer[i2+1]=='>'){ temporary[i3++]=buffer[i2++]; temporary[i3]=buffer[i2]; continue; } if(buffer[i2]=='['){ i4=GetStringInBracket(temporary+i3,buffer+i2); i2+=i4-1; i3+=i4-1; continue; } if(buffer[i2]=='('){ i4=GetStringInPare(temporary+i3,buffer+i2); i2+=i4-1; i3+=i4-1; continue; } if(!(IsVariableChar(buffer[i2])||buffer[i2]=='.')){ temporary[i3]=0; break; } temporary[i3]=buffer[i2]; } lstrcat(temporary,pObjectVar); lstrcpy(pObjectVar,temporary); } } else{ if(stack[sp]!=CmdId){ pObjectVar[0]=0; break; } sp--; } } if(i<=0) break; } }