Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

360 lines
9.4 KiB

  1. //========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: VPC
  4. //
  5. //=====================================================================================//
  6. #include "vpc.h"
  7. //-----------------------------------------------------------------------------
  8. // VPC_Group_FindOrCreateProject
  9. //
  10. //-----------------------------------------------------------------------------
  11. projectIndex_t VPC_Group_FindOrCreateProject( const char *pName, bool bCreate )
  12. {
  13. for ( int i = 0; i < g_pVPC->m_Projects.Count(); i++ )
  14. {
  15. if ( !V_stricmp( pName, g_pVPC->m_Projects[i].name.String() ) )
  16. {
  17. return i;
  18. }
  19. }
  20. if ( !bCreate )
  21. return INVALID_INDEX;
  22. int index = g_pVPC->m_Projects.AddToTail();
  23. g_pVPC->m_Projects[index].name = pName;
  24. return index;
  25. }
  26. //-----------------------------------------------------------------------------
  27. // VPC_Group_CreateGroup
  28. //
  29. //-----------------------------------------------------------------------------
  30. groupIndex_t VPC_Group_CreateGroup()
  31. {
  32. groupIndex_t index = g_pVPC->m_Groups.AddToTail();
  33. return index;
  34. }
  35. //-----------------------------------------------------------------------------
  36. // VPC_Group_FindOrCreateGroupTag
  37. //
  38. //-----------------------------------------------------------------------------
  39. groupTagIndex_t VPC_Group_FindOrCreateGroupTag( const char *pName, bool bCreate )
  40. {
  41. for (int i=0; i<g_pVPC->m_GroupTags.Count(); i++)
  42. {
  43. if ( !V_stricmp( pName, g_pVPC->m_GroupTags[i].name.String() ) )
  44. return i;
  45. }
  46. if ( !bCreate )
  47. return INVALID_INDEX;
  48. groupTagIndex_t index = g_pVPC->m_GroupTags.AddToTail();
  49. g_pVPC->m_GroupTags[index].name = pName;
  50. return index;
  51. }
  52. //-----------------------------------------------------------------------------
  53. // VPC_GroupKeyword_Games
  54. //
  55. //-----------------------------------------------------------------------------
  56. void VPC_GroupKeyword_Games()
  57. {
  58. const char *pToken;
  59. pToken = g_pVPC->GetScript().GetToken( true );
  60. if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
  61. g_pVPC->VPCSyntaxError();
  62. while ( 1 )
  63. {
  64. pToken = g_pVPC->GetScript().GetToken( true );
  65. if ( !pToken || !pToken[0] )
  66. g_pVPC->VPCSyntaxError();
  67. if ( !V_stricmp( pToken, "}" ) )
  68. {
  69. // end of section
  70. break;
  71. }
  72. else
  73. {
  74. g_pVPC->FindOrCreateConditional( pToken, true, CONDITIONAL_GAME );
  75. }
  76. }
  77. }
  78. //-----------------------------------------------------------------------------
  79. // VPC_GroupKeyword_Group
  80. //
  81. //-----------------------------------------------------------------------------
  82. void VPC_GroupKeyword_Group()
  83. {
  84. const char *pToken;
  85. bool bFirstToken = true;
  86. groupIndex_t groupIndex;
  87. projectIndex_t projectIndex;
  88. groupIndex = VPC_Group_CreateGroup();
  89. while ( 1 )
  90. {
  91. if ( !bFirstToken )
  92. {
  93. pToken = g_pVPC->GetScript().PeekNextToken( false );
  94. if ( !pToken || !pToken[0] )
  95. break;
  96. }
  97. else
  98. {
  99. bFirstToken = false;
  100. }
  101. pToken = g_pVPC->GetScript().GetToken( false );
  102. if ( !pToken || !pToken[0] )
  103. g_pVPC->VPCSyntaxError();
  104. // specified tag now builds this group
  105. groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true );
  106. g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex );
  107. }
  108. pToken = g_pVPC->GetScript().GetToken( true );
  109. if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
  110. g_pVPC->VPCSyntaxError();
  111. while ( 1 )
  112. {
  113. pToken = g_pVPC->GetScript().GetToken( true );
  114. if ( !pToken || !pToken[0] )
  115. g_pVPC->VPCSyntaxError();
  116. if ( !V_stricmp( pToken, "}" ) )
  117. {
  118. // end of section
  119. break;
  120. }
  121. else
  122. {
  123. projectIndex = VPC_Group_FindOrCreateProject( pToken, false );
  124. if ( projectIndex != INVALID_INDEX )
  125. {
  126. int index = g_pVPC->m_Groups[groupIndex].projects.AddToTail();
  127. g_pVPC->m_Groups[groupIndex].projects[index] = projectIndex;
  128. }
  129. else
  130. {
  131. g_pVPC->VPCWarning( "No Project %s defined, ignoring.", pToken );
  132. continue;
  133. }
  134. }
  135. }
  136. }
  137. //-----------------------------------------------------------------------------
  138. // VPC_GroupKeyword_Project
  139. //
  140. //-----------------------------------------------------------------------------
  141. void VPC_GroupKeyword_Project()
  142. {
  143. const char *pToken;
  144. pToken = g_pVPC->GetScript().GetToken( false );
  145. if ( !pToken || !pToken[0] )
  146. g_pVPC->VPCSyntaxError();
  147. if ( VPC_Group_FindOrCreateProject( pToken, false ) != INVALID_INDEX )
  148. {
  149. // already defined
  150. g_pVPC->VPCWarning( "project %s already defined", pToken );
  151. g_pVPC->VPCSyntaxError();
  152. }
  153. projectIndex_t projectIndex = VPC_Group_FindOrCreateProject( pToken, true );
  154. // create a default group that contains just this project
  155. groupIndex_t groupIndex = VPC_Group_CreateGroup();
  156. g_pVPC->m_Groups[groupIndex].projects.AddToTail( projectIndex );
  157. // create a default tag that matches the project name
  158. groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pToken, true );
  159. g_pVPC->m_GroupTags[groupTagIndex].groups.AddToTail( groupIndex );
  160. g_pVPC->m_GroupTags[groupTagIndex].bSameAsProject = true;
  161. pToken = g_pVPC->GetScript().GetToken( true );
  162. if ( !pToken || !pToken[0] || V_stricmp( pToken, "{" ) )
  163. g_pVPC->VPCSyntaxError();
  164. while ( 1 )
  165. {
  166. pToken = g_pVPC->GetScript().GetToken( true );
  167. if ( !pToken || !pToken[0] )
  168. g_pVPC->VPCSyntaxError();
  169. if ( !V_stricmp( pToken, "}" ) )
  170. {
  171. // end of section
  172. break;
  173. }
  174. else
  175. {
  176. scriptIndex_t scriptIndex = g_pVPC->m_Projects[projectIndex].scripts.AddToTail();
  177. g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].name = pToken;
  178. pToken = g_pVPC->GetScript().PeekNextToken( false );
  179. if ( pToken && pToken[0] )
  180. {
  181. pToken = g_pVPC->GetScript().GetToken( false );
  182. g_pVPC->m_Projects[projectIndex].scripts[scriptIndex].m_condition = pToken;
  183. }
  184. }
  185. }
  186. }
  187. //-----------------------------------------------------------------------------
  188. // VPC_ParseGroupScript
  189. //
  190. //-----------------------------------------------------------------------------
  191. void VPC_ParseGroupScript( const char *pScriptName )
  192. {
  193. char szScriptName[MAX_PATH];
  194. const char *pToken;
  195. // caller's pointer is aliased
  196. strcpy( szScriptName, pScriptName );
  197. V_FixSlashes( szScriptName );
  198. g_pVPC->VPCStatus( false, "Parsing: %s", szScriptName );
  199. g_pVPC->GetScript().PushScript( szScriptName );
  200. while ( 1 )
  201. {
  202. pToken = g_pVPC->GetScript().GetToken( true );
  203. if ( !pToken || !pToken[0] )
  204. {
  205. // end of file
  206. break;
  207. }
  208. if ( !V_stricmp( pToken, "$include" ) )
  209. {
  210. pToken = g_pVPC->GetScript().GetToken( false );
  211. if ( !pToken || !pToken[0] )
  212. {
  213. // end of file
  214. g_pVPC->VPCSyntaxError();
  215. }
  216. // recurse into and run
  217. VPC_ParseGroupScript( pToken );
  218. }
  219. else if ( !V_stricmp( pToken, "$games" ) )
  220. {
  221. VPC_GroupKeyword_Games();
  222. }
  223. else if ( !V_stricmp( pToken, "$group" ) )
  224. {
  225. VPC_GroupKeyword_Group();
  226. }
  227. else if ( !V_stricmp( pToken, "$project" ) )
  228. {
  229. VPC_GroupKeyword_Project();
  230. }
  231. else
  232. {
  233. g_pVPC->VPCSyntaxError();
  234. }
  235. }
  236. g_pVPC->GetScript().PopScript();
  237. }
  238. //-----------------------------------------------------------------------------
  239. // Collect all the +XXX, remove all the -XXX
  240. // This allows removal to be the expected trumping operation.
  241. //-----------------------------------------------------------------------------
  242. void CVPC::GenerateBuildSet( CProjectDependencyGraph &dependencyGraph )
  243. {
  244. // process +XXX commands
  245. for ( int i = 0; i < m_BuildCommands.Count(); i++ )
  246. {
  247. const char *pCommand = m_BuildCommands[i].Get();
  248. if ( pCommand[0] == '-' )
  249. continue;
  250. groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
  251. if ( groupTagIndex == INVALID_INDEX )
  252. continue;
  253. groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
  254. CUtlVector<projectIndex_t> projectsToAdd;
  255. for ( int j=0; j<pGroupTag->groups.Count(); j++ )
  256. {
  257. group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
  258. for ( int k=0; k<pGroup->projects.Count(); k++ )
  259. {
  260. projectIndex_t targetProject = pGroup->projects[k];
  261. if ( pCommand[0] == '*' )
  262. {
  263. // Add this project and any projects that depend on it.
  264. if ( !dependencyGraph.HasGeneratedDependencies() )
  265. dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS );
  266. dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, false );
  267. }
  268. else if ( pCommand[0] == '@' )
  269. {
  270. // Add this project and any projects that it depends on.
  271. if ( !dependencyGraph.HasGeneratedDependencies() )
  272. dependencyGraph.BuildProjectDependencies( BUILDPROJDEPS_CHECK_ALL_PROJECTS );
  273. dependencyGraph.GetProjectDependencyTree( targetProject, projectsToAdd, true );
  274. }
  275. else
  276. {
  277. projectsToAdd.AddToTail( targetProject );
  278. }
  279. }
  280. }
  281. // Add all the projects in the list.
  282. for ( int j=0; j < projectsToAdd.Count(); j++ )
  283. {
  284. projectIndex_t targetProject = projectsToAdd[j];
  285. if ( g_pVPC->m_TargetProjects.Find( targetProject ) == -1 )
  286. {
  287. g_pVPC->m_TargetProjects.AddToTail( targetProject );
  288. }
  289. }
  290. }
  291. // process -XXX commands, explicitly remove tagge projects
  292. for ( int i=0; i<m_BuildCommands.Count(); i++ )
  293. {
  294. const char *pCommand = m_BuildCommands[i].Get();
  295. if ( pCommand[0] == '+' || pCommand[0] == '*' || pCommand[0] == '@' )
  296. continue;
  297. groupTagIndex_t groupTagIndex = VPC_Group_FindOrCreateGroupTag( pCommand+1, false );
  298. if ( groupTagIndex == INVALID_INDEX )
  299. continue;
  300. groupTag_t *pGroupTag = &g_pVPC->m_GroupTags[groupTagIndex];
  301. for ( int j=0; j<pGroupTag->groups.Count(); j++ )
  302. {
  303. group_t *pGroup = &g_pVPC->m_Groups[pGroupTag->groups[j]];
  304. for ( int k=0; k<pGroup->projects.Count(); k++ )
  305. {
  306. g_pVPC->m_TargetProjects.FindAndRemove( pGroup->projects[k] );
  307. }
  308. }
  309. }
  310. }