示例#1
0
void OnNetMsg( NetSocket& rSocket,NetMsgHead* pMsg ,int32 nSize )
{

	ClientPlayer* gPlayer = ClientPlayerMgr::Instance()->GetClientPlayer(rSocket);

	// 解密处理
	static char msgBuffer[65536];
	memcpy(&msgBuffer[0], pMsg,nSize);

	Encrypt::XorCode(nSize,gPlayer->GetEncryptKey(),msgBuffer,nSize);
	pMsg = ( NetMsgHead*)&msgBuffer[0];

	NetMsgHandlerMapIter iter = gMsgHeandlerMap.find( pMsg->nType );
	if ( iter == gMsgHeandlerMap.end() )
	{
		FLOG_INFO("Not find Pro:%d", pMsg->nType);
		ASSERT(0);
	}
	else
	{
		ClientPlayer* pClientPlayer = ClientPlayerMgr::Instance()->GetClientPlayer(rSocket);
		(iter->second.pFun)(pClientPlayer,pMsg ,nSize);
		FLOG_INFO("OnNetMsg %d", pMsg->nType);
	}
}
示例#2
0
// StoreVariableString
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableString( const AString & name,
									 const BFFIterator & valueStart, const BFFIterator & valueEnd,
									 const BFFIterator & operatorIter,
									 BFFStackFrame * frame )
{
	// unescape and subsitute embedded variables
	AStackString< 2048 > value;
	if ( PerformVariableSubstitutions( valueStart, valueEnd, value ) == false )
	{
		return false;
	}

	// are we concatenating?
	const BFFVariable * varToConcat = nullptr;
	if ( *operatorIter == BFF_VARIABLE_CONCATENATION )
	{
		// find existing
		varToConcat = BFFStackFrame::GetVar( name, frame );
		if ( varToConcat == nullptr )
		{
			Error::Error_1026_VariableNotFoundForConcatenation( operatorIter, name );
			return false;
		}

		// make sure types are compatible
		if ( varToConcat->IsString() )
		{
			// OK - can concat String to String
			AStackString< 1024 > finalValue( varToConcat->GetString() );
			finalValue += value;

			BFFStackFrame::SetVarString( name, finalValue, frame );
			FLOG_INFO( "Appended '%s' to <String> variable '%s' with result '%s'", value.Get(), name.Get(), finalValue.Get() );
			return true;
		}
		else if ( varToConcat->IsArrayOfStrings() )
		{
			// OK - can concat String to ArrayOfStrings
			Array< AString > finalValues( varToConcat->GetArrayOfStrings().GetSize() + 1, false );
			finalValues = varToConcat->GetArrayOfStrings();
			finalValues.Append( value );

			BFFStackFrame::SetVarArrayOfStrings( name, finalValues, frame );
			FLOG_INFO( "Appended '%s' to <ArrayOfStrings> variable '%s' with result of %i items", value.Get(), name.Get(), finalValues.GetSize() );
			return true;
		}
		else
		{
			Error::Error_1027_CannotConcatenate( operatorIter, name, varToConcat->GetType(), BFFVariable::VAR_STRING );
			return false;
		}
	}

	// handle regular assignment of string
	BFFStackFrame::SetVarString( name, value, frame );
	FLOG_INFO( "Registered <string> variable '%s' with value '%s'", name.Get(), value.Get() );
	return true;
}
示例#3
0
void TQuery<target>::log() {
	for (GLsizei id = 0; id < mHowMany; id++) {
		if (glIsQuery(mHandles[id])) {
			FLOG_INFO("Query %d exists", mHandles[id]);
		} else {
			FLOG_INFO("Query %d does not exist", mHandles[id]);
		}
	}
}
示例#4
0
inline void Mesh::initBuffers() {
	if (mIBO) {
		FLOG_INFO("RELOAD IBO");
		mIBO->reload();
	}
	if (mVBO) {
		FLOG_INFO("RELOAD VBO");
		mVBO->reload();
	}
}
示例#5
0
// StoreVariableStruct
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableStruct( const AString & name,
									 const BFFIterator & valueStart, const BFFIterator & valueEnd,
									 const BFFIterator & operatorIter,
									 BFFStackFrame * frame )
{
	// are we concatenating?
	if ( *operatorIter == BFF_VARIABLE_CONCATENATION )
	{
		// concatenation of structs not supported
		Error::Error_1027_CannotModify( operatorIter, name, BFFVariable::VAR_STRUCT, BFFVariable::VAR_ANY );
		return false;
	}

	// create stack frame to capture variables
	BFFStackFrame stackFrame;

	// parse all the variables in the scope
	BFFParser subParser;
	BFFIterator subIter( valueStart );
	subIter.SetMax( valueEnd.GetCurrent() ); // limit to closing token
	if ( subParser.Parse( subIter ) == false )
	{
		return false; // error will be emitted by Parse
	}

	// get variables defined in the scope
	const Array< const BFFVariable * > & structMembers = stackFrame.GetLocalVariables();

	// Register this variable
	BFFStackFrame::SetVarStruct( name, structMembers, frame ? frame : stackFrame.GetParent() );
	FLOG_INFO( "Registered <struct> variable '%s' with %u members", name.Get(), structMembers.GetSize() );

	return true;
}
示例#6
0
// ParseDefineDirective
//------------------------------------------------------------------------------
bool BFFParser::ParseDefineDirective( BFFIterator & iter )
{
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}

	// parse out token
	const BFFIterator tokenStart( iter );
	iter.SkipVariableName();
	if ( tokenStart.GetCurrent() == iter.GetCurrent() )
	{
		Error::Error_1007_ExpectedVariable( iter, nullptr );
		return false;
	}
	const BFFIterator tokenEnd( iter );

	AStackString<> token( tokenStart.GetCurrent(), tokenEnd.GetCurrent() );

	if ( BFFMacros::Get().Define( token ) == false )
	{
		Error::Error_1038_OverwritingTokenInDefine( tokenStart );
		return false;
	}

	FLOG_INFO( "Define macro <%s>", token.Get() );

	return true;
}
示例#7
0
void VertexBufferFloat::log() const {
	auto d = [] (core::VertexFloat & f) {
		return static_cast<double>(f.mData);
	};
	for (auto it : mDataVertices) {
		FLOG_INFO("Vertex written: %f", d(it));
	}
}
示例#8
0
// StoreVariableInt
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableInt( const AString & name, int value, BFFStackFrame * frame )
{
	BFFStackFrame::SetVarInt( name, value, frame );

	FLOG_INFO( "Registered <int> variable '%s' with value '%i'", name.Get(), value );

	return true;
}
示例#9
0
// StoreVariableBool
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableBool( const AString & name, bool value, BFFStackFrame * frame )
{
	// Register this variable
	BFFStackFrame::SetVarBool( name, value, frame );

	FLOG_INFO( "Registered <bool> variable '%s' with value '%s'", name.Get(), value ? "true" : "false" );

	return true;
}
示例#10
0
// StoreVariableInt
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableInt( const char * varNameStart, const char * varNameEnd, int value )
{
	AStackString< MAX_VARIABLE_NAME_LENGTH > name( varNameStart, varNameEnd );
	BFFStackFrame::SetVarInt( name, value );

	FLOG_INFO( "Registered <int> variable '%s' with value '%i'", name.Get(), value );

	return true;
}
示例#11
0
// ParseImportDirective
//------------------------------------------------------------------------------
bool BFFParser::ParseImportDirective( const BFFIterator & directiveStart, BFFIterator & iter )
{
	iter.SkipWhiteSpace();

	// make sure we haven't hit the end of the file
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( directiveStart );
		return false;
	}

	// make sure this is a variable name
	if ( iter.IsAtValidVariableNameCharacter() == false )
	{
		Error::Error_1013_UnexpectedCharInVariableName( iter, nullptr );
		return false;
	}

	// find the end of the variable name
	const BFFIterator varNameStart( iter );
	iter.SkipVariableName();
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}
	const BFFIterator varNameEnd( iter );

	// sanity check it is a sensible length
	size_t varNameLen = varNameStart.GetDistTo( varNameEnd );
	if ( varNameLen > MAX_VARIABLE_NAME_LENGTH )
	{
		Error::Error_1014_VariableNameIsTooLong( iter, (uint32_t)varNameLen, (uint32_t)MAX_VARIABLE_NAME_LENGTH );
		return false;
	}
	AStackString<> varName( varNameStart.GetCurrent(), varNameEnd.GetCurrent() );

	// look for varName in system environment
	AStackString<> varValue;
	uint32_t varHash = 0;
	if ( FBuild::Get().ImportEnvironmentVar( varName.Get(), varValue, varHash ) == false )
	{
		Error::Error_1009_UnknownVariable( varNameStart, nullptr );
		return false;
	}

	// add the dot to variable name
	varName = ".";
	varName.Append( varNameStart.GetCurrent(), varNameLen );

	// import variable in current scope
	BFFStackFrame::SetVarString( varName, varValue, nullptr );
	FLOG_INFO( "Imported <string> variable '%s' with value '%s' from system environment", varName.Get(), varValue.Get() );

	return true;
}
示例#12
0
// StoreVariableBool
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableBool( const char * varNameStart, const char * varNameEnd, bool value )
{
	// Register this variable
	AStackString< MAX_VARIABLE_NAME_LENGTH > name( varNameStart, varNameEnd );
	BFFStackFrame::SetVarBool( name, value );

	FLOG_INFO( "Registered <bool> variable '%s' with value '%s'", name.Get(), value ? "true" : "false" );

	return true;
}
示例#13
0
// Commit
//------------------------------------------------------------------------------
/*virtual*/ bool FunctionSettings::Commit( NodeGraph & /*nodeGraph*/, const BFFIterator & funcStartIter ) const
{
    // using a cache plugin?
    AStackString<> cachePluginDLL;
    if ( !GetString( funcStartIter, cachePluginDLL, ".CachePluginDLL" ) )
    {
        return false;
    }
    FBuild::Get().SetCachePluginDLL( cachePluginDLL );
    if ( !cachePluginDLL.IsEmpty() )
    {
        FLOG_INFO( "CachePluginDLL: '%s'", cachePluginDLL.Get() );
    }

    // try to get the cache path from the config
    const BFFVariable * cachePathVar;
    if ( !GetString( funcStartIter, cachePathVar, ".CachePath" ) )
    {
        return false;
    }
    if ( cachePathVar )
    {
        s_CachePath = cachePathVar->GetString();

        // override environment default only if not empty
        if ( s_CachePath.IsEmpty() == false )
        {
            FBuild::Get().SetCachePath( s_CachePath );
        }
    }

    // "Workers"
    Array< AString > workerList;
    if ( !GetStrings( funcStartIter, workerList, ".Workers" ) )
    {
        return false;
    }
    if ( !workerList.IsEmpty() )
    {
        FBuild::Get().SetWorkerList( workerList );
    }

    // "Environment"
    Array< AString > environment;
    if ( !GetStrings( funcStartIter, environment, ".Environment" ) )
    {
        return false;
    }
    if ( !environment.IsEmpty() )
    {
        ProcessEnvironment( environment );
    }

    return true;
}
示例#14
0
void ForServerMsgHandler::ReqLogin(BaseSession* pSession, const NetMsgHead* pMsg,int32 nSize)
{
	//---------------------------------服务组代码begin-------------------------------
	ServerSession* pServerSession = static_cast<ServerSession*>(pSession);
	if(pServerSession->Status() != ESERVER_STATUS_CONNETED)
		return;

	const SSReqLoginWs* pPacket = static_cast<const SSReqLoginWs*>(pMsg);

	int32 nServerID = pPacket->nServerID;
	int32 nServerType = pPacket->nServerType;

	// 状态
	pServerSession->SetServerID(nServerID);
	pServerSession->SetRemoteServerType((EServerType)nServerType);
	pServerSession->SetStatus(ECLIENT_STATUS_LOGINED);

	// 记录新登入进来的server
	bool bResult = ServerInfoMgr::Instance()->OnServerLogin(pServerSession,pPacket->arrServerAddr,pPacket->nServerPort,nServerID,nServerType);
	if(!bResult)
	{
		FLOG_INFO("OnServerLogin fail serverid:%d",nServerID);
	}

	// 记录serverID与对应的session
	bResult = ServerSessionMgr::Instance()->InitSession(nServerID,pServerSession);
	if(!bResult)
	{
		FLOG_INFO("InitSession fail serverid:%d",nServerID);
	}

	// 返回登录成功
	pServerSession->LoginResult(bResult);

	// fep与dp的服务器信息需要广播给ls与ss
	if(bResult)
	{
		ServerInfoMgr::Instance()->BoardcastDpAndFepServerInfo2LsAndSs(pPacket->nServerID);
	}
	//---------------------------------服务组代码end-------------------------------

}
示例#15
0
// GetOtherLibrary
//------------------------------------------------------------------------------
bool LinkerNode::GetOtherLibrary( NodeGraph & nodeGraph,
                                  const BFFIterator & iter,
                                  const Function * function,
                                  Dependencies & libs,
                                  const AString & path,
                                  const AString & lib,
                                  bool & found ) const
{
    found = false;

    AStackString<> potentialNodeName( path );
    if ( !potentialNodeName.IsEmpty() )
    {
        PathUtils::EnsureTrailingSlash( potentialNodeName );
    }
    potentialNodeName += lib;
    AStackString<> potentialNodeNameClean;
    NodeGraph::CleanPath( potentialNodeName, potentialNodeNameClean );

    // see if a node already exists
    Node * node = nodeGraph.FindNode( potentialNodeNameClean );
    if ( node )
    {
        // aliases not supported - must point to something that provides a file
        if ( node->IsAFile() == false )
        {
            Error::Error_1103_NotAFile( iter, function, ".LinkerOptions", potentialNodeNameClean, node->GetType() );
            return false;
        }

        // found existing node
        libs.Append( Dependency( node ) );
        found = true;
        return true; // no error
    }

    // see if the file exists on disk at this location
    if ( FileIO::FileExists( potentialNodeNameClean.Get() ) )
    {
        node = nodeGraph.CreateFileNode( potentialNodeNameClean );
        libs.Append( Dependency( node ) );
        found = true;
        FLOG_INFO( "Additional library '%s' assumed to be '%s'\n", lib.Get(), potentialNodeNameClean.Get() );
        return true; // no error
    }

    return true; // no error
}
示例#16
0
void ServerStart()
{
	int32 nRunTimes = 0;
	while(gIsRun)
	{
		SSleep(1);
		gNetClientForWs->Update(0.0);
		ServerConnectMgr::Instance()->Update(0.0); // NetClient.update
		nRunTimes++;
		if(nRunTimes > RUN_PRINT_TIMES)
		{
			int32 nServerNum = ServerSessionMgr::Instance()->CountConnected();
			int32 nClientNum = ClientSessionMgr::Instance()->ConnectedSessions();
			FLOG_INFO("Server Info: Server Connected Num:%d ,Client Connected Num:%d", nServerNum, nClientNum);
			nRunTimes = 0;
		}
	}
}
示例#17
0
SizedBufferRef HandleIpFragment(IpHeaderStruct* ipHeader)
{
	const time_t now = time(NULL);
	const int timeoutSec = 60;
	static time_t lastCheck = 0;
	static FragmentMap fragmentMap;

	// Delete previous fragments older than timeoutSec 
	if (now-lastCheck >= timeoutSec) {
		std::list <FragmentMap::iterator> toBeDeleted; 
		for (FragmentMap::iterator it=fragmentMap.begin(); it!=fragmentMap.end(); ++it) {
			if (now - it->second->lastUpdate() >= timeoutSec) 
				toBeDeleted.push_back(it);
		}
		if (toBeDeleted.size()) {
			for (std::list <FragmentMap::iterator>::iterator it=toBeDeleted.begin(); it!=toBeDeleted.end();++it) {
				fragmentMap.erase(*it);
			} 
			FLOG_WARN(s_log,"%d fragmented packets older than %u seconds has been removed from the map", toBeDeleted.size(), timeoutSec);
		}
		lastCheck = now;
	}

	FLOG_DEBUG(s_log,"Recieved fragment with packet id:%u, offset:%u, payload length:%u", ipHeader->packetId(), ipHeader->offset(), ipHeader->payloadLen());
	FragmentMap::iterator it = fragmentMap.find(ipHeader->packetId());
	if (it == fragmentMap.end()) { 
		it = fragmentMap.insert(std::make_pair(ipHeader->packetId(), FragmentationAlgorithmRef(new FRAGMENTATION_ALGORITHM()))).first;
	}
	FragmentationAlgorithmRef algorithm = it->second;
	algorithm->addFragment(ipHeader);

	if (algorithm->drop()) {
		fragmentMap.erase(it);
		FLOG_WARN(s_log,"Dropping fragmented packet data with id:%u", ipHeader->packetId());
	} 

	if (algorithm->isComplete()) {
		fragmentMap.erase(it);
		IpHeaderStruct *header = reinterpret_cast<IpHeaderStruct*>(algorithm->packetData()->get());
		FLOG_INFO(s_log, "Reassembled fragmented packet with id:%u, total payload length:%u", header->packetId(), header->payloadLen());
		return algorithm->packetData(); 
	}
	return SizedBufferRef(); // By default return empty ref
}
示例#18
0
void ServerStart()
{
    int32 nRunTimes = 0;
    while(true)
    {
        SSleep(1);
        gNetClientForWs->Update(0);
        gNetServerForServer->Update(0);
        gNetServerForClient->Update(0);
        nRunTimes++;
        if(nRunTimes > RUN_PRINT_TIMES)
        {
            int32 nServerNum = ServerSessionMgr::Instance()->CountConnected();
            int32 nClientNum = gNetServerForClient->ConnectedSockets();
            FLOG_INFO("Server Info: Server Connected Num:%d ,Client Connected Num:%d", nServerNum, nClientNum);// 标识主线程还在做事中
            nRunTimes = 0;
        }
    }
}
示例#19
0
文件: TapeMsg.cpp 项目: havoc83/oreka
void TapeMsg::HandleResponse(MessageRef responseRef) {
	CStdString logMsg;

	TapeResponse* tr = dynamic_cast<TapeResponse*>(responseRef.get());
	if (!tr) {
		LOG4CXX_WARN(LOG.messaging,"Ignoring wrong response type");
		return;
	}

	if(tr->m_deleteTape && this->m_stage.Equals("ready") )
	{
		CStdString tapeFilename = this->m_fileName;

		CStdString absoluteFilename = CONFIG.m_audioOutputPath + "/" + tapeFilename;
		if (ACE_OS::unlink((PCSTR)absoluteFilename) == 0)
		{
			FLOG_INFO(LOG.messaging,"deleted tape: %s", tapeFilename);
		}
		else
		{
			FLOG_DEBUG(LOG.messaging,"could not delete tape: %s ", tapeFilename);
		}

	}
	else if(tr->m_deleteTape && this->m_stage.Equals("start") && CONFIG.m_pauseRecordingOnRejectedStart == true)
	{
		CStdString orkUid = this->m_recId;
		CStdString empty;
		CapturePluginProxy::Singleton()->PauseCapture(empty, orkUid, empty);
	}
	else 
	{
		// Tape is wanted
		if(CONFIG.m_lookBackRecording == false && CONFIG.m_allowAutomaticRecording && this->m_stage.Equals("start"))
		{
			CStdString orkuid = "", nativecallid = "", side = "";
			CapturePluginProxy::Singleton()->StartCapture(this->m_localParty, orkuid, nativecallid, side);
			CapturePluginProxy::Singleton()->StartCapture(this->m_remoteParty, orkuid, nativecallid, side);
		}
	}

}
示例#20
0
void Init()
{
	bool bResult = NetServerOpt::Instance()->LoadServerConfig("ls_cfg.xml",ESERVER_TYPE_LS);
	if(!bResult)
	{
		FLOG_INFO("Load cfg fail");
		return;
	}

	// 连接WS服务
	ServerInfoOpt& rRemoteInfo = NetServerOpt::Instance()->GetRemoteServerInfo();
	gNetClientForWs = new NetClient();
	gNetClientForWs->SetAddress(rRemoteInfo.strHost.c_str(), rRemoteInfo.nPort);
	gNetClientForWs->SetHandler(boost::bind(&ForWorldMsgHandler::OnNetMsgEnter, ForWorldMsgHandler::Instance(), _1),
		boost::bind(&ForWorldMsgHandler::OnNetMsg, ForWorldMsgHandler::Instance(), _1, _2, _3),
		boost::bind(&ForWorldMsgHandler::OnNetMsgExit, ForWorldMsgHandler::Instance(), _1));

	gNetClientForWs->Start();

}
示例#21
0
void Init()
{

    bool bResult = NetServerOpt::Instance()->LoadServerConfig("fep_cfg.xml",ESERVER_TYPE_FEP);
    if(!bResult)
    {
        FLOG_INFO("Load cfg fail");
        return;
    }

    // 连接WS服务
    ServerInfoOpt& rRemoteInfo = NetServerOpt::Instance()->GetRemoteServerInfo();
    gNetClientForWs = new NetClient();
    gNetClientForWs->SetAddress(rRemoteInfo.strHost.c_str(),rRemoteInfo.nPort);
    gNetClientForWs->SetHandler(boost::bind(&ForWorldMsgHandler::OnNetMsgEnter,ForWorldMsgHandler::Instance(),_1),
                                boost::bind(&ForWorldMsgHandler::OnNetMsg,ForWorldMsgHandler::Instance(),_1,_2,_3),
                                boost::bind(&ForWorldMsgHandler::OnNetMsgExit,ForWorldMsgHandler::Instance(),_1));
    gNetClientForWs->Start();

    // 初始化ForServer服务
    ServerInfoOpt& rLocalInfo = NetServerOpt::Instance()->GetLocalServerInfo();
    gNetServerForServer = new NetServer(32);
    gNetServerForServer->SetTimeout(60);
    gNetServerForServer->SetAddress(rLocalInfo.strHost.c_str(), rLocalInfo.nPort);
    gNetServerForServer->SetHandler(boost::bind(&ForServerMsgHandler::OnNetMsgEnter, ForServerMsgHandler::Instance(), _1),
                                    boost::bind(&ForServerMsgHandler::OnNetMsg, ForServerMsgHandler::Instance(), _1, _2,_3),
                                    boost::bind(&ForServerMsgHandler::OnNetMsgExit, ForServerMsgHandler::Instance(), _1));
    gNetServerForServer->Start();

    // 初始化ForClient服务
    ServerInfoOpt& rClientInfo = NetServerOpt::Instance()->GetClientServerInfo();
    gNetServerForClient = new NetServer(MAX_FEP_SOCKET_CONNECT);
    gNetServerForClient->SetAddress(rClientInfo.strHost.c_str(),rClientInfo.nPort);
    gNetServerForClient->SetHandler(boost::bind(&ForClientMsgHandler::OnNetMsgEnter,ForClientMsgHandler::Instance(),_1),
                                    boost::bind(&ForClientMsgHandler::OnNetMsg,ForClientMsgHandler::Instance(),_1,_2,_3),
                                    boost::bind(&ForClientMsgHandler::OnNetMsgExit,ForClientMsgHandler::Instance(),_1));

    // 启动Socket服务
    gNetServerForClient->Start();

}
示例#22
0
void ForServerMsgHandler::RepLogined(BaseSession* pBaseSession, const NetMsgHead* pMsg,int32 nSize)
{
	//---------------------------------服务组代码begin-------------------------------
	if(pBaseSession->Status() != ESERVER_STATUS_CONNETED)
	{
		FLOG_INFO("pBaseSession->Status() != EWORLD_STATUS_CONNECTED");
		return;
	}
	const SSRepLogined* pPacket = static_cast<const SSRepLogined*>(pMsg);
	if(pPacket->nResult == SSRepLogined::SUCCESS)
	{
		pBaseSession->SetStatus(ESERVER_STATUS_LOGINED);
	}
	else
	{
		//登录失败,可以再进行第二次及第三次登录试试看
		return;
	}
	//---------------------------------服务组代码end-------------------------------

}
示例#23
0
// ParseUndefDirective
//------------------------------------------------------------------------------
bool BFFParser::ParseUndefDirective( BFFIterator & iter )
{
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}

	// parse out token
	const BFFIterator tokenStart( iter );
	iter.SkipVariableName();
	if ( tokenStart.GetCurrent() == iter.GetCurrent() )
	{
		Error::Error_1007_ExpectedVariable( iter, nullptr );
		return false;
	}
	const BFFIterator tokenEnd( iter );

	AStackString<> token( tokenStart.GetCurrent(), tokenEnd.GetCurrent() );

	if ( BFFMacros::Get().Undefine( token ) == false )
	{
		if ( token.BeginsWith( "__" ) )
		{
			Error::Error_1040_UndefOfBuiltInTokenNotAllowed( tokenStart );			
		}
		else
		{
			Error::Error_1039_UnknownTokenInUndef( tokenStart );
		}
		return false;
	}

	FLOG_INFO( "Undefine macro <%s>", token.Get() );

	return true;
}
示例#24
0
// ParseFunction
//------------------------------------------------------------------------------
bool BFFParser::ParseFunction( BFFIterator & iter )
{
	ASSERT( iter.IsAtValidFunctionNameCharacter() );

	// for variables to be used by this function
	BFFStackFrame stackFrame;

	BFFIterator functionNameStart( iter );
	iter.SkipFunctionName();
	if ( iter.IsAtEnd() )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}

	// check length
	if ( functionNameStart.GetDistTo( iter ) > MAX_FUNCTION_NAME_LENGTH )
	{
		// if it's too long, then it can't be a valid function
		Error::Error_1015_UnknownFunction( functionNameStart );
		return false;
	}

	// store function name
	AStackString<MAX_FUNCTION_NAME_LENGTH> functionName( functionNameStart.GetCurrent(), iter.GetCurrent() );
	const Function * func = Function::Find( functionName );
	if ( func == nullptr )
	{
		Error::Error_1015_UnknownFunction( functionNameStart );
		return false;
	}
	iter.SkipWhiteSpace();

	if ( func->IsUnique() && func->GetSeen() )
	{
		Error::Error_1020_FunctionCanOnlyBeInvokedOnce( functionNameStart, func );
		return false;
	}
	func->SetSeen();

	FLOG_INFO( "Function call '%s'", functionName.Get() );

	// header, or body?
	bool hasHeader = false;
	BFFIterator functionArgsStartToken( iter );
	BFFIterator functionArgsStopToken( iter );
	if ( *iter == BFF_FUNCTION_ARGS_OPEN )
	{
		// can this function accept a header?
		if ( func->AcceptsHeader() == false )
		{
			Error::Error_1021_UnexpectedHeaderForFunction( iter, func );
			return false;
		}

		// args
		if ( iter.ParseToMatchingBrace( BFF_FUNCTION_ARGS_OPEN, BFF_FUNCTION_ARGS_CLOSE ) == false )
		{
			Error::Error_1022_MissingFunctionHeaderCloseToken( functionArgsStartToken, func );
			return false;
		}
		functionArgsStopToken = iter;
		hasHeader = true;
		iter++; // skip over closing token	
		iter.SkipWhiteSpaceAndComments();
	}

	if ( func->NeedsHeader() && ( hasHeader == false ) )
	{
		Error::Error_1023_FunctionRequiresAHeader( iter, func );
		return false;
	}

	// some functions have no body
	bool hasBody = false;

	BFFIterator functionBodyStartToken( iter );
	BFFIterator functionBodyStopToken( iter );
	if ( func->NeedsBody() )
	{
		// find body
		if ( *iter != BFF_SCOPE_OPEN )
		{
			Error::Error_1024_FunctionRequiresABody( functionNameStart, func );
			return false;
		}

		if ( iter.ParseToMatchingBrace( BFF_SCOPE_OPEN, BFF_SCOPE_CLOSE ) == false )
		{
			Error::Error_1025_MissingScopeCloseToken( functionBodyStartToken, func );
			return false;
		}

		functionBodyStopToken = iter;
		iter++;
		hasBody = true;
	}

	return func->ParseFunction( functionNameStart,
								hasBody ? &functionBodyStartToken : nullptr, 
								hasBody ? &functionBodyStopToken : nullptr,
								hasHeader ? &functionArgsStartToken : nullptr,
								hasHeader ? &functionArgsStopToken : nullptr );}
示例#25
0
// DoBuild
//------------------------------------------------------------------------------
/*static*/ Node::BuildResult JobQueue::DoBuild( Job * job )
{
	Timer timer; // track how long the item takes

	Node * node = job->GetNode();

	// make sure the output path exists for files
	// (but don't bother for input files)
	if ( node->IsAFile() && ( node->GetType() != Node::FILE_NODE ) && ( node->GetType() != Node::COMPILER_NODE ) )
	{
		if ( Node::EnsurePathExistsForFile( node->GetName() ) == false )
		{
			// error already output by EnsurePathExistsForFile
			return Node::NODE_RESULT_FAILED;
		}
	}

	Node::BuildResult result = node->DoBuild( job );

	uint32_t timeTakenMS = uint32_t( timer.GetElapsedMS() );

	if ( result == Node::NODE_RESULT_OK )
	{
		// record new build time only if built (i.e. if cached or failed, the time
		// does not represent how long it takes to create this resource)
		node->SetLastBuildTime( timeTakenMS );
		node->SetStatFlag( Node::STATS_BUILT );
		FLOG_INFO( "-Build: %u ms\t%s", timeTakenMS, node->GetName().Get() );
	}

	if ( result == Node::NODE_RESULT_NEED_SECOND_BUILD_PASS )
	{
		// nothing to check
	}
	else if ( node->IsAFile() )
	{
		if ( result == Node::NODE_RESULT_FAILED )
		{
			if ( node->GetControlFlags() & Node::FLAG_NO_DELETE_ON_FAIL )
			{
				// node failed, but builder wants result left on disc
			}
			else
			{
				// build of file failed - if there is a file....
				if ( FileIO::FileExists( node->GetName().Get() ) )
				{
					// ... it is invalid, so try to delete it
					if ( FileIO::FileDelete( node->GetName().Get() ) == false )
					{
						// failed to delete it - this might cause future build problems!
						FLOG_ERROR( "Post failure deletion failed for '%s'", node->GetName().Get() );
					}
				}
			}
		}
		else
		{
			// build completed ok, or retrieved from cache...
			ASSERT( ( result == Node::NODE_RESULT_OK ) || ( result == Node::NODE_RESULT_OK_CACHE ) );

			// (don't check existence of input files)
			if ( node->GetType() != Node::FILE_NODE )
			{
				// ... ensure file exists (to detect builder logic problems)
				if ( !FileIO::FileExists( node->GetName().Get() ) )
				{
					FLOG_ERROR( "File missing despite success for '%s'", node->GetName().Get() );
					result = Node::NODE_RESULT_FAILED;
				}
			}
		}
	}

	// log processing time
	node->AddProcessingTime( timeTakenMS );

	return result;
}
示例#26
0
// DoBuild
//------------------------------------------------------------------------------
/*virtual*/ Node::BuildResult DirectoryListNode::DoBuild( Job * UNUSED( job ) )
{
	// NOTE: The DirectoryListNode makes no assumptions about whether no files
	// is an error or not.  That's up to the dependent nodes to decide.

	Array< FileIO::FileInfo > files( 4096, true );
	FileIO::GetFilesEx( m_Path, &m_Patterns, m_Recursive, &files );

	m_Files.SetCapacity( files.GetSize() );

	// filter exclusions
	const FileIO::FileInfo * const end = files.End();
	for ( const FileIO::FileInfo * it = files.Begin(); it != end; it++ )
	{
		bool excluded = false;
        
		// filter excluded paths
		const AString * const eEnd = m_ExcludePaths.End();
		for ( const AString * eIt=m_ExcludePaths.Begin(); eIt != eEnd; ++eIt )
		{
			if ( PathUtils::PathBeginsWith( it->m_Name, *eIt ) )
			{
				excluded = true;
				break;
			}
		}

        // filter excluded files
		if ( !excluded )
		{
	        const AString * fit = m_FilesToExclude.Begin();
	        const AString * const fend = m_FilesToExclude.End();
	        for ( ; fit != fend; ++fit )
	        {
				if ( PathUtils::PathEndsWithFile( it->m_Name, *fit ) )
	            {
	                excluded = true;
	                break;
	            }
	        }
		}

		if ( !excluded )
		{
			m_Files.Append( *it );
		}
	}

	if ( FLog::ShowInfo() )
	{
		const size_t numFiles = m_Files.GetSize();
		FLOG_INFO( "Dir: '%s' (found %u files)\n", 
							m_Name.Get(), 
							(uint32_t)numFiles);
		for ( size_t i=0; i<numFiles; ++i )
		{
			FLOG_INFO( " - %s\n", m_Files[ i ].m_Name.Get() );
		}
	}

	return NODE_RESULT_OK;
}
示例#27
0
void OnNetMsgExit( NetSocket& socket )
{
	FLOG_INFO("=========Had Exist===============","");
	bExist = true;
}
示例#28
0
// StoreVariableArray
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableArray( const AString & name,
									const BFFIterator & valueStart, const BFFIterator & valueEnd,
									const BFFIterator & operatorIter,
									BFFStackFrame * frame )
{
	Array< AString > values( 32, true );
	Array< const BFFVariable * > structValues( 32, true );

	// are we concatenating?
	if ( ( *operatorIter == BFF_VARIABLE_CONCATENATION ) ||
		 ( *operatorIter == BFF_VARIABLE_SUBTRACTION ) )
	{
		// find existing
		const BFFVariable * var = BFFStackFrame::GetVar( name, frame );
		if ( var == nullptr )
		{
			Error::Error_1026_VariableNotFoundForModification( operatorIter, name );
			return false;
		}

		// make sure existing is an array
		if ( var->IsArrayOfStrings() )
		{
			// get values to start with
			values = var->GetArrayOfStrings();
		}
		else if ( var->IsArrayOfStructs() )
		{
			// get values to start with
			structValues = var->GetArrayOfStructs();
		}
		else
		{
			// TODO:B Improve this error to handle ArrayOfStructs case
			Error::Error_1027_CannotModify( operatorIter, name, var->GetType(), BFFVariable::VAR_ARRAY_OF_STRINGS );
			return false;
		}
	}

	// Parse array of variables
	BFFIterator iter( valueStart );
	for (;;)
	{
		iter.SkipWhiteSpaceAndComments();

		// end?
		if ( iter.GetCurrent() == valueEnd.GetCurrent() )
		{
			break;
		}

		const char c = *iter;
		if ( ( c == '"' ) || ( c == '\'' ) )
		{
			// a quoted string

			// detect mistmatches
			if ( structValues.IsEmpty() == false )
			{
				// Mixed types in vector
				Error::Error_1034_OperationNotSupported( iter, 
														 BFFVariable::VAR_ARRAY_OF_STRUCTS,
														 BFFVariable::VAR_STRING,
														 operatorIter );
				return false;
			}

			// subtraction not supported on arrays
			if ( *operatorIter == BFF_VARIABLE_SUBTRACTION )
			{
				Error::Error_1034_OperationNotSupported( iter, BFFVariable::VAR_ARRAY_OF_STRINGS, BFFVariable::VAR_STRING, operatorIter );
				return false;
			}

			// a string
			BFFIterator elementValueStart( iter );
			iter.SkipString( c );
			ASSERT( iter.GetCurrent() <= valueEnd.GetCurrent() ); // should not be in this function if string is not terminated
			elementValueStart++; // move to start of actual content
			AStackString< 2048 > elementValue;

			// unescape and subsitute embedded variables
			if ( PerformVariableSubstitutions( elementValueStart, iter, elementValue ) == false )
			{
				return false;
			}

			values.Append( elementValue );

			iter++; // pass closing quote
		}
		else if ( c == BFF_DECLARE_VAR_INTERNAL ||
				  c == BFF_DECLARE_VAR_PARENT )
		{
			const BFFIterator elementStartValue = iter;

			// a variable
			AStackString< MAX_VARIABLE_NAME_LENGTH > varName;
			bool parentScope = false; // ignored, the behavior is the same
			if ( ParseVariableName( iter, varName, parentScope ) == false )
			{
				return false;
			}

			// Determine stack frame to use for Src var
			BFFStackFrame * srcFrame = BFFStackFrame::GetCurrent();			
			if ( c == BFF_DECLARE_VAR_PARENT )
			{
				srcFrame = BFFStackFrame::GetCurrent()->GetParent();
			}

			// get the variable
			const BFFVariable * var = srcFrame->GetVariableRecurse( varName );
			if ( var == nullptr )
			{
				Error::Error_1026_VariableNotFoundForModification( operatorIter, varName );
				return false;
			}

			// subtraction not supported on arrays
			if ( *operatorIter == BFF_VARIABLE_SUBTRACTION )
			{
				const BFFVariable::VarType dstType = structValues.IsEmpty() ? BFFVariable::VAR_ARRAY_OF_STRINGS : BFFVariable::VAR_ARRAY_OF_STRUCTS;
				const BFFVariable::VarType srcType = var->GetType();
				Error::Error_1034_OperationNotSupported( elementStartValue, dstType, srcType, operatorIter );
				return false;
    		}

			if ( var->IsString() || var->IsArrayOfStrings() )
			{
				// dest is consistent?
				if ( structValues.IsEmpty() == false )
				{
					// inconsistency
					Error::Error_1034_OperationNotSupported( elementStartValue, 
															 BFFVariable::VAR_ARRAY_OF_STRUCTS,
															 var->GetType(),
															 operatorIter );
					return false;
				}

				if ( var->IsString() )
				{
					values.Append( var->GetString() );
				}
				else
				{
					values.Append( var->GetArrayOfStrings() );
				}
			}
			else if ( var->IsStruct() || var->IsArrayOfStructs() )
			{
				// dest is consistent?
				if ( values.IsEmpty() == false )
				{
					// inconsistency
					Error::Error_1034_OperationNotSupported( elementStartValue, 
															 BFFVariable::VAR_ARRAY_OF_STRINGS,
															 var->GetType(),
															 operatorIter );
					return false;
				}

				if ( var->IsStruct() )
				{
					structValues.Append( var );
				}
				else
				{
					structValues.Append( var->GetArrayOfStructs() );
				}
			}
			else
			{
				Error::Error_1050_PropertyMustBeOfType( iter, nullptr, name.Get(), 
														var->GetType(),
														BFFVariable::VAR_STRING,
														BFFVariable::VAR_STRUCT );
				return false;
			}
		}
		else
		{
			Error::Error_1001_MissingStringStartToken( iter, nullptr );
			return false;
		}

		iter.SkipWhiteSpaceAndComments();
		if ( *iter == ',' ) // comma seperators are optional
		{ 
			iter++; 
		}

		// continue looking for more vars...
	}

	// should only have one populated array
	ASSERT( values.IsEmpty() || structValues.IsEmpty() );

	// Register this variable
	if ( structValues.IsEmpty() == false )
	{
		// structs
		BFFStackFrame::SetVarArrayOfStructs( name, structValues, frame );
		FLOG_INFO( "Registered <ArrayOfStructs> variable '%s' with %u elements", name.Get(), structValues.GetSize() );
	}
	else
	{
		// strings (or unknown, so default to strings)
		BFFStackFrame::SetVarArrayOfStrings( name, values, frame );
		FLOG_INFO( "Registered <ArrayOfStrings> variable '%s' with %u elements", name.Get(), values.GetSize() );
	}

	return true;
}
示例#29
0
// StoreVariableToVariable
//------------------------------------------------------------------------------
bool BFFParser::StoreVariableToVariable( const AString & dstName, BFFIterator & iter, const BFFIterator & operatorIter, BFFStackFrame * dstFrame )
{
	AStackString< MAX_VARIABLE_NAME_LENGTH > srcName;

	bool srcParentScope = false;
	const BFFIterator varNameSrcStart( iter ); // Take note of start of var
	if ( ParseVariableName( iter, srcName, srcParentScope ) == false )
	{
		return false;
	}

	// find src var
	const BFFVariable * varSrc = nullptr;
	BFFStackFrame * const srcFrame = ( srcParentScope )
		? BFFStackFrame::GetParentDeclaration( srcName, nullptr, varSrc )
		: nullptr;

	if ( !srcParentScope )
	{
		varSrc = BFFStackFrame::GetVar( srcName, nullptr );
	}

	if ( ( srcParentScope && nullptr == srcFrame ) || ( nullptr == varSrc ) )
    {
    	Error::Error_1009_UnknownVariable( varNameSrcStart, nullptr );
    	return false;
    }

	// find dst var
	const BFFVariable * varDst = BFFStackFrame::GetVar( dstName, dstFrame );

	const bool concat = ( *operatorIter == BFF_VARIABLE_CONCATENATION );

	// concatenation?
	if ( concat )
	{
		// can only concatenate to existing vars
		if ( varDst == nullptr )
		{
			Error::Error_1026_VariableNotFoundForModification( operatorIter, dstName );
			return false;
		}
	}

	// if dst exists, types must match
	BFFVariable::VarType srcType = varSrc->GetType(); 
	BFFVariable::VarType dstType = BFFVariable::VAR_ANY; 
	if ( varDst )
	{
		dstType = varDst->GetType();
	}
	else 
	{
		ASSERT( concat == false );
		dstType = srcType;
	}

	// handle supported types

	if ( srcType != dstType )
	{
		// Mismatched - is there a supported conversion?

		// String to ArrayOfStrings
		if ( ( dstType == BFFVariable::VAR_ARRAY_OF_STRINGS ) && 
			 ( srcType == BFFVariable::VAR_STRING ) )
		{
			uint32_t num = (uint32_t)( 1 + ( concat ? varDst->GetArrayOfStrings().GetSize() : 0 ) );
			Array< AString > values( num, false );
			if ( concat )
			{
				values.Append( varDst->GetArrayOfStrings() );
			}
			values.Append( varSrc->GetString() );

			BFFStackFrame::SetVarArrayOfStrings( dstName, values, dstFrame );
			FLOG_INFO( "Registered <ArrayOfStrings> variable '%s' with %u elements", dstName.Get(), num );
			return true;
		}

		// Struct to ArrayOfStructs
		if ( ( dstType == BFFVariable::VAR_ARRAY_OF_STRUCTS ) && 
			 ( srcType == BFFVariable::VAR_STRUCT ) )
		{
			uint32_t num = (uint32_t)( 1 + ( concat ? varDst->GetArrayOfStructs().GetSize() : 0 ) );
			Array< const BFFVariable * > values( num, false );
			if ( concat )
			{
				values.Append( varDst->GetArrayOfStructs() );
			}
			values.Append( varSrc );

			BFFStackFrame::SetVarArrayOfStructs( dstName, values, dstFrame );
			FLOG_INFO( "Registered <ArrayOfStructs> variable '%s' with %u elements", dstName.Get(), num );
			return true;
		}

	}
	else
	{
		// Matching Src and Dst

		if ( srcType == BFFVariable::VAR_STRING )
		{
			AStackString< 2048 > finalValue;
			if ( concat )
			{
				finalValue = varDst->GetString();
			}
			finalValue += varSrc->GetString();

			BFFStackFrame::SetVarString( dstName, finalValue, dstFrame );
			FLOG_INFO( "Registered <string> variable '%s' with value '%s'", dstName.Get(), finalValue.Get() );
			return true;
		}
	
		if ( srcType == BFFVariable::VAR_ARRAY_OF_STRINGS )
		{
			if ( concat )
			{
				const unsigned int num = (unsigned int)( varSrc->GetArrayOfStrings().GetSize() + varDst->GetArrayOfStrings().GetSize() );
				Array< AString > values( num, false );
				values.Append( varDst->GetArrayOfStrings() );
				values.Append( varSrc->GetArrayOfStrings() );
				BFFStackFrame::SetVarArrayOfStrings( dstName, values, dstFrame );
				FLOG_INFO( "Registered <ArrayOfStrings> variable '%s' with %u elements", dstName.Get(), num );
			}
			else
			{
				BFFStackFrame::SetVarArrayOfStrings( dstName, varSrc->GetArrayOfStrings(), dstFrame );
				FLOG_INFO( "Registered <ArrayOfStrings> variable '%s' with %u elements", dstName.Get(), (unsigned int)varSrc->GetArrayOfStrings().GetSize() );
			}
			return true;
		}

		if ( srcType == BFFVariable::VAR_ARRAY_OF_STRUCTS )
		{
			if ( concat )
			{
				const unsigned int num = (unsigned int)( varSrc->GetArrayOfStructs().GetSize() + varDst->GetArrayOfStructs().GetSize() );
				Array< const BFFVariable * > values( num, false );
				values.Append( varDst->GetArrayOfStructs() );
				values.Append( varSrc->GetArrayOfStructs() );
				BFFStackFrame::SetVarArrayOfStructs( dstName, values, dstFrame );
				FLOG_INFO( "Registered <ArrayOfStructs> variable '%s' with %u elements", dstName.Get(), num );
			}
			else
			{
				BFFStackFrame::SetVarArrayOfStructs( dstName, varSrc->GetArrayOfStructs(), dstFrame );
				FLOG_INFO( "Registered <ArrayOfStructs> variable '%s' with %u elements", dstName.Get(), (unsigned int)varSrc->GetArrayOfStructs().GetSize() );
			}
			return true;
		}

		if ( srcType == BFFVariable::VAR_INT )
		{
			int newVal( varSrc->GetInt() );
			if ( concat )
			{
				newVal += varDst->GetInt();
			}
			return StoreVariableInt( dstName, newVal, dstFrame );
		}

		if ( srcType == BFFVariable::VAR_BOOL )
		{
			// only assignment is supported
			if ( concat == false )
			{
				return StoreVariableBool( dstName, varSrc->GetBool(), dstFrame );
			}
		}

		if ( srcType == BFFVariable::VAR_STRUCT )
		{
			const Array< const BFFVariable * > & srcMembers = varSrc->GetStructMembers();
			if ( concat )
			{
				BFFVariable *const newVar = BFFStackFrame::ConcatVars( dstName, varSrc, varDst, dstFrame );
				FLOG_INFO( "Registered <struct> variable '%s' with %u members", dstName.Get(), newVar->GetStructMembers().GetSize() );
			}
			else
			{
				// Register this variable
				BFFStackFrame::SetVarStruct( dstName, srcMembers, dstFrame );
				FLOG_INFO( "Registered <struct> variable '%s' with %u members", dstName.Get(), srcMembers.GetSize() );
			}
			return true;
		}
	}

	Error::Error_1034_OperationNotSupported( varNameSrcStart, 
											 varDst ? varDst->GetType() : varSrc->GetType(),
											 varSrc->GetType(),
											 operatorIter );
	return false;
}
示例#30
0
// ParseIncludeDirective
//------------------------------------------------------------------------------
bool BFFParser::ParseIncludeDirective( BFFIterator & iter )
{
	// Sanity check include depth to detect cyclic includes
	if ( s_Depth >= 128 )
	{
		Error::Error_1035_ExcessiveDepthComplexity( iter );
		return false;
	}

	// we expect a " quoted string
	if ( *iter != '"' )
	{
		Error::Error_1031_UnexpectedCharFollowingDirectiveName( iter, AStackString<>( "include" ), '"' ); 
		return false;
	}

	BFFIterator stringStart( iter );
	stringStart++; // first actual character

	// find end of string
	if ( iter.ParseToNext( '"' ) == false )
	{
		Error::Error_1012_UnexpectedEndOfFile( iter );
		return false;
	}

	// unescape and substitute variables
	AStackString<> include;
	if ( PerformVariableSubstitutions( stringStart, iter, include ) == false )
	{
		return false;
	}

	iter++; // skip closing quote before returning

	FLOG_INFO( "Including: %s\n", include.Get() );

	// open include

	// 1) Try current directory
	AStackString<> includeToUse;
	if (PathUtils::IsFullPath(include) == false)
	{
		const char * lastSlash = iter.GetFileName().FindLast( NATIVE_SLASH );
		lastSlash = lastSlash ? lastSlash : iter.GetFileName().FindLast( OTHER_SLASH );
		lastSlash = lastSlash ? ( lastSlash + 1 ): iter.GetFileName().Get(); // file only, truncate to empty
		includeToUse.Assign( iter.GetFileName().Get(), lastSlash );
	}
	includeToUse += include;
	AStackString<> includeToUseClean;
	NodeGraph::CleanPath( includeToUse, includeToUseClean );
	FileStream f;
	if ( f.Open( includeToUseClean.Get(), FileStream::READ_ONLY ) == false )
	{
		Error::Error_1032_UnableToOpenInclude( stringStart, includeToUseClean );
		return false;
	}

	// check if include uses "once" pragma
	if ( FBuild::Get().GetDependencyGraph().IsOneUseFile( includeToUseClean ) )
	{
		// already seen, and uses #once : don't include again
		return true;
	}

	uint64_t includeTimeStamp = FileIO::GetFileLastWriteTime( includeToUseClean );

	// read content of include
	const uint32_t fileSize = (uint32_t)f.GetFileSize();
	AutoPtr< char > mem( (char *)ALLOC( fileSize + 1 ) );
	if ( f.Read( mem.Get(), fileSize ) != fileSize )
	{
		Error::Error_1033_ErrorReadingInclude( stringStart, include, Env::GetLastErr() );
		return false;
	}
	mem.Get()[ fileSize ] = '\000'; // sentinel
	BFFParser parser;
	const bool pushStackFrame = false; // include is treated as if injected at this point
	return parser.Parse( mem.Get(), fileSize, includeToUseClean.Get(), includeTimeStamp, pushStackFrame ); 
}