|
|
//========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
//
// Purpose: VPC
//
//=====================================================================================//
#include "vpc.h"
//-----------------------------------------------------------------------------
// VPC_Group_FindOrCreateProject
//
//-----------------------------------------------------------------------------
projectIndex_t VPC_Group_FindOrCreateProject( const char *pName, bool bCreate ) { for ( int i = 0; i < g_pVPC->m_Projects.Count(); i++ ) { if ( !V_stricmp( pName, g_pVPC->m_Projects[i].name.String() ) ) { return i; } }
if ( !bCreate ) return INVALID_INDEX;
int index = g_pVPC->m_Projects.AddToTail(); g_pVPC->m_Projects[index].name = pName;
return index; }
//-----------------------------------------------------------------------------
// VPC_Group_CreateGroup
//
//-----------------------------------------------------------------------------
groupIndex_t VPC_Group_CreateGroup() { groupIndex_t index = g_pVPC->m_Groups.AddToTail(); return index; }
//-----------------------------------------------------------------------------
// VPC_Group_FindOrCreateGroupTag
//
//-----------------------------------------------------------------------------
groupTagIndex_t VPC_Group_FindOrCreateGroupTag( const char *pName, bool bCreate ) { for (int i=0; i<g_pVPC->m_GroupTags.Count(); i++) { if ( !V_stricmp( pName, g_pVPC->m_GroupTags[i].name.String() ) ) return i; }
if ( !bCreate ) return INVALID_INDEX;
groupTagIndex_t index = g_pVPC->m_GroupTags.AddToTail(); g_pVPC->m_GroupTags[index].name = pName;
return index; }
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Games
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Games() { const char *pToken;
pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) ) g_pVPC->VPCSyntaxError();
while ( 1 ) { pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] ) g_pVPC->VPCSyntaxError();
if ( !V_stricmp( pToken, "}" ) ) { // end of section
break; } else { g_pVPC->FindOrCreateConditional( pToken, true, CONDITIONAL_GAME ); } } }
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Group
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Group() { const char *pToken; bool bFirstToken = true; groupIndex_t groupIndex; projectIndex_t projectIndex;
groupIndex = VPC_Group_CreateGroup();
while ( 1 ) { if ( !bFirstToken ) { pToken = g_pVPC->GetScript().PeekNextToken( false ); if ( !pToken || !pToken[0] ) break; } else { bFirstToken = false; }
pToken = g_pVPC->GetScript().GetToken( false ); if ( !pToken || !pToken[0] ) g_pVPC->VPCSyntaxError();
// specified tag now builds this group
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true ); g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex ); }
pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) ) g_pVPC->VPCSyntaxError();
while ( 1 ) { pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] ) g_pVPC->VPCSyntaxError();
if ( !V_stricmp( pToken, "}" ) ) { // end of section
break; } else { projectIndex = VPC_Group_FindOrCreateProject( pToken, false ); if ( projectIndex != INVALID_INDEX ) { int index = g_pVPC->m_Groups[groupIndex].projects.AddToTail(); g_pVPC->m_Groups[groupIndex].projects[index] = projectIndex; } else { g_pVPC->VPCWarning( "No Project %s defined, ignoring.", pToken ); continue; } } } }
//-----------------------------------------------------------------------------
// VPC_GroupKeyword_Project
//
//-----------------------------------------------------------------------------
void VPC_GroupKeyword_Project() { const char *pToken;
pToken = g_pVPC->GetScript().GetToken( false ); if ( !pToken || !pToken[0] ) g_pVPC->VPCSyntaxError();
if ( VPC_Group_FindOrCreateProject( pToken, false ) != INVALID_INDEX ) { // already defined
g_pVPC->VPCWarning( "project %s already defined", pToken ); g_pVPC->VPCSyntaxError(); }
projectIndex_t projectIndex = VPC_Group_FindOrCreateProject( pToken, true );
// create a default group that contains just this project
groupIndex_t groupIndex = VPC_Group_CreateGroup(); g_pVPC->m_Groups[groupIndex].projects.AddToTail( projectIndex );
// create a default tag that matches the project name
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true ); g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex ); g_pVPC->m_GroupTags[groupTagIndex].bSameAsProject = true;
pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) ) g_pVPC->VPCSyntaxError();
while ( 1 ) { pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] ) g_pVPC->VPCSyntaxError();
if ( !V_stricmp( pToken, "}" ) ) { // end of section
break; } else { scriptIndex_t scriptIndex = g_pVPC->m_Projects[projectIndex].scripts.AddToTail(); g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].name = pToken;
pToken = g_pVPC->GetScript().PeekNextToken( false ); if ( pToken && pToken[0] ) { pToken = g_pVPC->GetScript().GetToken( false ); g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].m_condition = pToken; } } } }
//-----------------------------------------------------------------------------
// VPC_ParseGroupScript
//
//-----------------------------------------------------------------------------
void VPC_ParseGroupScript( const char *pScriptName ) { char szScriptName[MAX_PATH]; const char *pToken;
// caller's pointer is aliased
strcpy( szScriptName, pScriptName ); V_FixSlashes( szScriptName );
g_pVPC->VPCStatus( false, "Parsing: %s", szScriptName ); g_pVPC->GetScript().PushScript( szScriptName );
while ( 1 ) { pToken = g_pVPC->GetScript().GetToken( true ); if ( !pToken || !pToken[0] ) { // end of file
break; }
if ( !V_stricmp( pToken, "$include" ) ) { pToken = g_pVPC->GetScript().GetToken( false ); if ( !pToken || !pToken[0] ) { // end of file
g_pVPC->VPCSyntaxError(); }
// recurse into and run
VPC_ParseGroupScript( pToken ); } else if ( !V_stricmp( pToken, "$games" ) ) { VPC_GroupKeyword_Games(); } else if ( !V_stricmp( pToken, "$group" ) ) { VPC_GroupKeyword_Group(); } else if ( !V_stricmp( pToken, "$project" ) ) { VPC_GroupKeyword_Project(); } else { g_pVPC->VPCSyntaxError(); } }
g_pVPC->GetScript().PopScript(); }
//-----------------------------------------------------------------------------
// Collect all the +XXX, remove all the -XXX
// This allows removal to be the expected trumping operation.
//-----------------------------------------------------------------------------
void CVPC::GenerateBuildSet( CProjectDependencyGraph &dependencyGraph ) { // process +XXX commands
for ( int i = 0; i < m_BuildCommands.Count(); i++ ) { const char *pCommand = m_BuildCommands[i].Get(); if ( pCommand[0] == '-' ) continue;
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false ); if ( groupTagIndex == INVALID_INDEX ) continue; groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
CUtlVector<projectIndex_t> projectsToAdd;
for ( int j=0; j<pGroupTag->groups.Count(); j++ ) { group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]]; for ( int k=0; k<pGroup->projects.Count(); k++ ) { projectIndex_t targetProject = pGroup->projects[k]; if ( pCommand[0] == '*' ) { // Add this project and any projects that depend on it.
if ( !dependencyGraph.HasGeneratedDependencies() ) dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS );
dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, false ); } else if ( pCommand[0] == '@' ) { // Add this project and any projects that it depends on.
if ( !dependencyGraph.HasGeneratedDependencies() ) dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS );
dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, true ); } else { projectsToAdd.AddToTail( targetProject ); } } }
// Add all the projects in the list.
for ( int j=0; j < projectsToAdd.Count(); j++ ) { projectIndex_t targetProject = projectsToAdd[j];
if ( g_pVPC->m_TargetProjects.Find( targetProject ) == -1 ) { g_pVPC->m_TargetProjects.AddToTail( targetProject ); } } }
// process -XXX commands, explicitly remove tagge projects
for ( int i=0; i<m_BuildCommands.Count(); i++ ) { const char *pCommand = m_BuildCommands[i].Get(); if ( pCommand[0] == '+' || pCommand[0] == '*' || pCommand[0] == '@' ) continue;
groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false ); if ( groupTagIndex == INVALID_INDEX ) continue; groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
for ( int j=0; j<pGroupTag->groups.Count(); j++ ) { group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]]; for ( int k=0; k<pGroup->projects.Count(); k++ ) { g_pVPC->m_TargetProjects.FindAndRemove( pGroup->projects[k] ); } } } }
|