171 lines
5.0 KiB
C
171 lines
5.0 KiB
C
|
// Copyright (C) 2007 Id Software, Inc.
|
||
|
//
|
||
|
|
||
|
|
||
|
#ifndef __DECL_PARSE_HELPER__
|
||
|
#define __DECL_PARSE_HELPER__
|
||
|
|
||
|
/*
|
||
|
==============
|
||
|
sdDeclParseHelper
|
||
|
|
||
|
A helper class to ensure that binary data generation is handled uniformly across decl types
|
||
|
Should be added to the Parse() member of an idDecl-derived class
|
||
|
|
||
|
To ensure that tokens are generated consistently it should be created after the LEXFL_ parsing flags are set on the input idParser
|
||
|
|
||
|
The destructor handles setting dependencies and storing any binary generated data
|
||
|
==============
|
||
|
*/
|
||
|
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
sdDeclParseHelper
|
||
|
============
|
||
|
*/
|
||
|
class sdDeclParseHelper {
|
||
|
public:
|
||
|
sdDeclParseHelper( idDecl* decl_, const char* text, int textLength, idParser& src_ );
|
||
|
~sdDeclParseHelper();
|
||
|
|
||
|
void GetBinaryBuffer( const byte*& buffer, int& length ) const;
|
||
|
const idFile_Memory* GetOutputFile() const { return binaryOutput; }
|
||
|
void Finish( void );
|
||
|
|
||
|
private:
|
||
|
idParser& src; // parser that we're reading from/settings up
|
||
|
idFile_Memory* binaryOutput; // tokenized parser output to be stored on the decl
|
||
|
|
||
|
idDecl* decl; // source/target decl
|
||
|
idDeclTypeInterface* type; // type of the decl, used for decl type-specific behavior
|
||
|
|
||
|
byte* declBuffer; // binary buffer retrieved from the decl
|
||
|
int declBufferLength; // binary buffer length retrieved from the decl
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
sdDeclParseHelper::sdDeclParseHelper
|
||
|
============
|
||
|
*/
|
||
|
ID_INLINE sdDeclParseHelper::sdDeclParseHelper( idDecl* decl_, const char* text, int textLength, idParser& src_ ) :
|
||
|
binaryOutput( NULL ),
|
||
|
decl( decl_ ),
|
||
|
src( src_ ),
|
||
|
declBuffer( NULL ),
|
||
|
declBufferLength( 0 ) {
|
||
|
|
||
|
type = declManager->GetDeclType( decl->GetType() );
|
||
|
|
||
|
idTokenCache* cache = NULL;
|
||
|
if( !type->UsePrivateTokens() ) {
|
||
|
cache = &declManager->GetGlobalTokenCache();
|
||
|
}
|
||
|
|
||
|
if( decl->HasBinaryBuffer() && decl->GetState() != DS_DEFAULTED ) {
|
||
|
decl->GetBinarySource( declBuffer, declBufferLength );
|
||
|
src.LoadMemoryBinary( declBuffer, declBufferLength, va( "%s: %s", decl->GetFileName(), decl->GetName() ), cache );
|
||
|
} else {
|
||
|
// store expanded text (except for templates) so that it's written in its entirety to the binary decl file
|
||
|
if( cvarSystem->GetCVarBool( "com_writeBinaryDecls" ) && !type->WriteBinary() && !type->AlwaysGenerateBinary() && decl->GetState() != DS_DEFAULTED ) {
|
||
|
src.LoadMemory( text, textLength, va( "%s: %s", decl->GetFileName(), decl->GetName() ), decl->GetLineNum() );
|
||
|
if( decl->GetFileLevelIncludeDependencies() != NULL ) {
|
||
|
src.AddIncludes( *( decl->GetFileLevelIncludeDependencies() ) );
|
||
|
}
|
||
|
|
||
|
sdStringBuilder_Heap builder;
|
||
|
|
||
|
idToken token;
|
||
|
while( src.ReadToken( &token )) {
|
||
|
if( token.type == TT_STRING ) {
|
||
|
builder += "\"";
|
||
|
}
|
||
|
builder += token;
|
||
|
if( token.type == TT_STRING ) {
|
||
|
builder += "\"";
|
||
|
}
|
||
|
builder += " ";
|
||
|
}
|
||
|
decl->SetText( builder.c_str() );
|
||
|
src.FreeSource( true );
|
||
|
}
|
||
|
src.LoadMemory( text, textLength, va( "%s: %s", decl->GetFileName(), decl->GetName() ), decl->GetLineNum() );
|
||
|
}
|
||
|
|
||
|
// no need to setup file dependencies in binary mode
|
||
|
if( decl->GetFileLevelIncludeDependencies() != NULL && !decl->HasBinaryBuffer() ) {
|
||
|
src.AddIncludes( *( decl->GetFileLevelIncludeDependencies() ) );
|
||
|
}
|
||
|
|
||
|
if( type->WriteBinary() ) {
|
||
|
if( ( cvarSystem->GetCVarBool( "com_writeBinaryDecls" ) || type->AlwaysGenerateBinary() ) &&
|
||
|
( !decl->HasBinaryBuffer() || ( type->AlwaysGenerateBinary() && decl->GetState() == DS_DEFAULTED ) ) ) {
|
||
|
binaryOutput = fileSystem->OpenMemoryFile( decl->GetName() );
|
||
|
binaryOutput->SetGranularity( 256 );
|
||
|
|
||
|
src.WriteBinary( binaryOutput, cache );
|
||
|
src.ResetBinaryParsing();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
sdDeclParseHelper::~sdDeclParseHelper
|
||
|
============
|
||
|
*/
|
||
|
ID_INLINE sdDeclParseHelper::~sdDeclParseHelper() {
|
||
|
Finish();
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
sdDeclParseHelper::GetBinaryBuffer
|
||
|
============
|
||
|
*/
|
||
|
ID_INLINE void sdDeclParseHelper::GetBinaryBuffer( const byte*& buffer, int& length ) const {
|
||
|
if( declBuffer == NULL || declBufferLength == 0 ) {
|
||
|
if( binaryOutput != NULL ) {
|
||
|
buffer = reinterpret_cast< const byte* >( binaryOutput->GetDataPtr() );
|
||
|
length = binaryOutput->Length();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
buffer = declBuffer;
|
||
|
length = declBufferLength;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
============
|
||
|
sdDeclParseHelper::Finish
|
||
|
============
|
||
|
*/
|
||
|
ID_INLINE void sdDeclParseHelper::Finish( void ) {
|
||
|
// no dependencies in binary mode, except for types that always generate
|
||
|
if( decl != NULL && ( binaryOutput == NULL || type->AlwaysGenerateBinary() ) ) {
|
||
|
declManager->AddDependencies( decl, src );
|
||
|
}
|
||
|
|
||
|
if( decl != NULL && binaryOutput != NULL && decl->GetState() != DS_DEFAULTED ) {
|
||
|
decl->SetBinarySource( reinterpret_cast< const byte* >( binaryOutput->GetDataPtr() ), binaryOutput->Length() );
|
||
|
}
|
||
|
|
||
|
if( decl != NULL && declBuffer != NULL ) {
|
||
|
decl->FreeSourceBuffer( declBuffer );
|
||
|
declBuffer = NULL;
|
||
|
}
|
||
|
|
||
|
if( binaryOutput != NULL ) {
|
||
|
fileSystem->CloseFile( binaryOutput );
|
||
|
binaryOutput = NULL;
|
||
|
}
|
||
|
|
||
|
decl = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif // !__DECL_PARSE_HELPER__
|