#include "stdafx.h" void EnumInfo::Collect( const char *buffer,int nowLine) { this->members.clear(); int i=nowLine,i2; if(!(buffer[i]==1&&buffer[i+1]==ESC_ENUM)) return; i+=2; //列挙体の名前を取得 char temporary[VN_SIZE]; for(i2=0;;i++,i2++){ if(IsCommandDelimitation(buffer[i])){ temporary[i2]=0; break; } if(!IsVariableChar(buffer[i])){ compiler.errorMessenger.Output(1,NULL,i); break; } temporary[i2]=buffer[i]; } if(buffer[i]=='\0'){ compiler.errorMessenger.Output(22,"Enum",nowLine); return; } int currentValue = 0; bool isUseCurrentValue = true; std::string currentValueStr; std::string lastMemberName; char temp2[VN_SIZE]; while(1){ i++; if(buffer[i]==1&&buffer[i+1]==ESC_ENDENUM) break; for(i2=0;;i2++,i++){ if(IsCommandDelimitation(buffer[i])){ temporary[i2]=0; break; } if(buffer[i]=='='){ temporary[i2]=0; break; } temporary[i2]=buffer[i]; } if(temporary[0]=='\0'){ if(buffer[i]=='\0'){ compiler.errorMessenger.Output(22,"Enum",nowLine); break; } continue; } if( buffer[i] != '=' ) { if( isUseCurrentValue ) { currentValue++; sprintf( temp2, "%d", currentValue ); currentValueStr = temp2; } else { currentValueStr = lastMemberName + "+1"; } } else { i++; GetCommandToken( temp2, buffer, i ); _int64 i64data; if( StaticCalculation( false, temp2, 0, &i64data, Type() ) ) { currentValue = static_cast(i64data); sprintf( temp2, "%d", currentValue ); currentValueStr = temp2; } else { // 取得できなかった(なんらかの識別子を含む可能性あり) isUseCurrentValue = false; currentValueStr = temp2; } } //メンバを追加 this->members.push_back( EnumMember( temporary, currentValueStr, i ) ); lastMemberName = temporary; } } void EnumInfoCollection::InitEnum(void) { this->clear(); const char *source = compiler.GetObjectModule().GetCurrentSource().GetBuffer(); // 名前空間管理 NamespaceScopes &namespaceScopes = compiler.GetNamespaceSupporter().GetLivingNamespaceScopes(); namespaceScopes.clear(); int i2; char temporary[VN_SIZE]; for(int i=0;;i++){ if(source[i]=='\0') break; if( source[i] == 1 && source[i+1] == ESC_NAMESPACE ){ for(i+=2,i2=0;;i2++,i++){ if( IsCommandDelimitation( source[i] ) ){ temporary[i2]=0; break; } temporary[i2]=source[i]; } namespaceScopes.push_back( temporary ); continue; } else if( source[i] == 1 && source[i+1] == ESC_ENDNAMESPACE ){ if( namespaceScopes.size() <= 0 ){ compiler.errorMessenger.Output(12, "End Namespace", i ); } else{ namespaceScopes.pop_back(); } i += 2; continue; } if(source[i]==1&&source[i+1]==ESC_ENUM){ if(i>=2){ if(source[i-2]==1&&source[i-1]==ESC_CONST) continue; } i2 = i + 2; GetCommandToken( temporary, source, i2 ); // 追加 this->push_back( EnumInfo( namespaceScopes, temporary ) ); // 収集 this->back().Collect( source, i ); } } } char *EnumInfoCollection::GenerateSourceCode(void){ char *buffer; int MaxSize,length; MaxSize=65535; buffer=(char *)HeapAlloc(hHeap,0,MaxSize+65535); length=0; buffer[0]=0; const EnumInfoCollection &thisEnumInfoCollection = *this; BOOST_FOREACH( const EnumInfo &enumInfo, thisEnumInfoCollection ) { BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){ sprintf(buffer+length,"Namespace %s\n",namespaceStr.c_str()); length+=lstrlen(buffer+length); } sprintf(buffer+length,"Class Enum %s\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tInherits EnumBase<%s>\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tSub %s(value As Long,lpszName As LPSTR)\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"\t\tEnumBase(value,lpszName)\n"); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"\tEnd Sub\n"); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"Public\n"); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tSub %s()\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); if( enumInfo.GetMembers().size()){ sprintf(buffer+length,"\t\tEnumBase(%s)\n", enumInfo.GetMembers().begin()->GetName().c_str() ); length+=lstrlen(buffer+length); } lstrcpy(buffer+length,"\tEnd Sub\n"); length+=lstrlen(buffer+length); sprintf(buffer+length,"\tSub ~%s()\n",enumInfo.GetName().c_str()); length+=lstrlen(buffer+length); lstrcpy(buffer+length,"\tEnd Sub\n"); length+=lstrlen(buffer+length); BOOST_FOREACH( const EnumMember &member, enumInfo.GetMembers() ) { sprintf(buffer+length,"\tStatic %s As %s((%s) As Long,\"%s\")\n", member.GetName().c_str(), enumInfo.GetName().c_str(), member.GetValueStr().c_str(), member.GetName().c_str()); length+=lstrlen(buffer+length); } lstrcpy(buffer+length,"End Class\n"); length+=lstrlen(buffer+length); BOOST_FOREACH( const std::string &namespaceStr, enumInfo.GetNamespaceScopes() ){ lstrcpy( buffer+length, "End Namespace\n" ); length+=lstrlen(buffer+length); } //バッファ領域が足りなくなった場合はバッファを増量する if(length>MaxSize){ MaxSize+=65535; buffer=(char *)HeapReAlloc(hHeap,0,buffer,MaxSize+65535); } } #ifdef _DEBUG // ログを生成 Jenga::Common::Logger logger( Jenga::Common::Environment::GetAppDir() + "\\enum_generated.log", false ); logger << buffer << std::endl; #endif return buffer; }