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.

337 lines
9.0 KiB

  1. //====== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "vpc.h"
  7. #include "baseprojectdatacollector.h"
  8. #include "tier1/utlstack.h"
  9. #include "p4lib/ip4.h"
  10. // ------------------------------------------------------------------------------------------------ //
  11. // CSpecificConfig implementation.
  12. // ------------------------------------------------------------------------------------------------ //
  13. CSpecificConfig::CSpecificConfig( CSpecificConfig *pParentConfig )
  14. : m_pParentConfig( pParentConfig )
  15. {
  16. m_pKV = new KeyValues( "" );
  17. m_bFileExcluded = false;
  18. m_bIsSchema = false;
  19. }
  20. CSpecificConfig::~CSpecificConfig()
  21. {
  22. m_pKV->deleteThis();
  23. }
  24. const char* CSpecificConfig::GetConfigName()
  25. {
  26. return m_pKV->GetName();
  27. }
  28. const char* CSpecificConfig::GetOption( const char *pOptionName )
  29. {
  30. const char *pRet = m_pKV->GetString( pOptionName, NULL );
  31. if ( pRet )
  32. return pRet;
  33. if ( m_pParentConfig )
  34. return m_pParentConfig->m_pKV->GetString( pOptionName, NULL );
  35. return NULL;
  36. }
  37. // ------------------------------------------------------------------------------------------------ //
  38. // CFileConfig implementation.
  39. // ------------------------------------------------------------------------------------------------ //
  40. CFileConfig::~CFileConfig()
  41. {
  42. Term();
  43. }
  44. void CFileConfig::Term()
  45. {
  46. m_Configurations.PurgeAndDeleteElements();
  47. }
  48. const char* CFileConfig::GetName()
  49. {
  50. return m_Filename.String();
  51. }
  52. CSpecificConfig* CFileConfig::GetConfig( const char *pConfigName )
  53. {
  54. int i = m_Configurations.Find( pConfigName );
  55. if ( i == m_Configurations.InvalidIndex() )
  56. return NULL;
  57. else
  58. return m_Configurations[i];
  59. }
  60. CSpecificConfig* CFileConfig::GetOrCreateConfig( const char *pConfigName, CSpecificConfig *pParentConfig )
  61. {
  62. int i = m_Configurations.Find( pConfigName );
  63. if ( i == m_Configurations.InvalidIndex() )
  64. {
  65. CSpecificConfig *pConfig = new CSpecificConfig( pParentConfig );
  66. i = m_Configurations.Insert( pConfigName, pConfig );
  67. }
  68. return m_Configurations[i];
  69. }
  70. bool CFileConfig::IsExcludedFrom( const char *pConfigName )
  71. {
  72. CSpecificConfig *pSpecificConfig = GetConfig( pConfigName );
  73. if ( pSpecificConfig )
  74. return pSpecificConfig->m_bFileExcluded;
  75. else
  76. return false;
  77. }
  78. // ------------------------------------------------------------------------------------------------ //
  79. // CBaseProjectDataCollector implementation.
  80. // ------------------------------------------------------------------------------------------------ //
  81. CBaseProjectDataCollector::CBaseProjectDataCollector( CRelevantPropertyNames *pNames ) : m_Files( k_eDictCompareTypeFilenames )
  82. {
  83. m_RelevantPropertyNames.m_nNames = 0;
  84. m_RelevantPropertyNames.m_pNames = NULL;
  85. if ( pNames )
  86. {
  87. m_RelevantPropertyNames = *pNames;
  88. }
  89. }
  90. CBaseProjectDataCollector::~CBaseProjectDataCollector()
  91. {
  92. Term();
  93. }
  94. void CBaseProjectDataCollector::StartProject()
  95. {
  96. m_ProjectName = "UNNAMED";
  97. m_CurFileConfig.Push( &m_BaseConfigData );
  98. m_CurSpecificConfig.Push( NULL );
  99. }
  100. void CBaseProjectDataCollector::EndProject()
  101. {
  102. }
  103. void CBaseProjectDataCollector::Term()
  104. {
  105. m_BaseConfigData.Term();
  106. m_Files.PurgeAndDeleteElements();
  107. m_CurFileConfig.Purge();
  108. m_CurSpecificConfig.Purge();
  109. }
  110. CUtlString CBaseProjectDataCollector::GetProjectName()
  111. {
  112. return m_ProjectName;
  113. }
  114. void CBaseProjectDataCollector::SetProjectName( const char *pProjectName )
  115. {
  116. char tmpBuf[MAX_PATH];
  117. V_strncpy( tmpBuf, pProjectName, sizeof( tmpBuf ) );
  118. Q_strlower( tmpBuf );
  119. m_ProjectName = tmpBuf;
  120. }
  121. // Get a list of all configurations.
  122. void CBaseProjectDataCollector::GetAllConfigurationNames( CUtlVector< CUtlString > &configurationNames )
  123. {
  124. configurationNames.Purge();
  125. for ( int i=m_BaseConfigData.m_Configurations.First(); i != m_BaseConfigData.m_Configurations.InvalidIndex(); i=m_BaseConfigData.m_Configurations.Next(i) )
  126. {
  127. configurationNames.AddToTail( m_BaseConfigData.m_Configurations.GetElementName(i) );
  128. }
  129. }
  130. void CBaseProjectDataCollector::StartConfigurationBlock( const char *pConfigName, bool bFileSpecific )
  131. {
  132. CFileConfig *pFileConfig = m_CurFileConfig.Top();
  133. // Find or add a new config block.
  134. char sLowerCaseConfigName[MAX_PATH];
  135. V_strncpy( sLowerCaseConfigName, pConfigName, sizeof( sLowerCaseConfigName ) );
  136. V_strlower( sLowerCaseConfigName );
  137. int index = pFileConfig->m_Configurations.Find( sLowerCaseConfigName );
  138. if ( index == -1 )
  139. {
  140. CSpecificConfig *pParent = ( pFileConfig==&m_BaseConfigData ? NULL : m_BaseConfigData.GetOrCreateConfig( sLowerCaseConfigName, NULL ) );
  141. CSpecificConfig *pConfig = new CSpecificConfig( pParent );
  142. pConfig->m_bFileExcluded = false;
  143. pConfig->m_pKV->SetName( sLowerCaseConfigName );
  144. index = pFileConfig->m_Configurations.Insert( sLowerCaseConfigName, pConfig );
  145. }
  146. // Remember what the current config is.
  147. m_CurSpecificConfig.Push( pFileConfig->m_Configurations[index] );
  148. }
  149. void CBaseProjectDataCollector::EndConfigurationBlock()
  150. {
  151. m_CurSpecificConfig.Pop();
  152. }
  153. bool CBaseProjectDataCollector::StartPropertySection( configKeyword_e keyword, bool *pbShouldSkip )
  154. {
  155. return true;
  156. }
  157. void CBaseProjectDataCollector::HandleProperty( const char *pProperty, const char *pCustomScriptData )
  158. {
  159. int i;
  160. for ( i=0; i < m_RelevantPropertyNames.m_nNames; i++ )
  161. {
  162. if ( V_stricmp( m_RelevantPropertyNames.m_pNames[i], pProperty ) == 0 )
  163. break;
  164. }
  165. if ( i == m_RelevantPropertyNames.m_nNames )
  166. {
  167. // not found
  168. return;
  169. }
  170. if ( pCustomScriptData )
  171. {
  172. g_pVPC->GetScript().PushScript( "HandleProperty( custom script data )", pCustomScriptData );
  173. }
  174. const char *pNextToken = g_pVPC->GetScript().PeekNextToken( false );
  175. if ( pNextToken && pNextToken[0] != 0 )
  176. {
  177. // Pass in the previous value so the $base substitution works.
  178. CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
  179. const char *pBaseString = pConfig->m_pKV->GetString( pProperty );
  180. char buff[MAX_SYSTOKENCHARS];
  181. if ( g_pVPC->GetScript().ParsePropertyValue( pBaseString, buff, sizeof( buff ) ) )
  182. {
  183. pConfig->m_pKV->SetString( pProperty, buff );
  184. }
  185. }
  186. if ( pCustomScriptData )
  187. {
  188. // Restore prior script state
  189. g_pVPC->GetScript().PopScript();
  190. }
  191. }
  192. void CBaseProjectDataCollector::EndPropertySection( configKeyword_e keyword )
  193. {
  194. }
  195. void CBaseProjectDataCollector::StartFolder( const char *pFolderName )
  196. {
  197. }
  198. void CBaseProjectDataCollector::EndFolder()
  199. {
  200. }
  201. bool CBaseProjectDataCollector::StartFile( const char *pFilename, bool bWarnIfAlreadyExists )
  202. {
  203. CFileConfig *pFileConfig = new CFileConfig;
  204. pFileConfig->m_Filename = pFilename;
  205. m_Files.Insert( pFilename, pFileConfig );
  206. m_CurFileConfig.Push( pFileConfig );
  207. m_CurSpecificConfig.Push( NULL );
  208. char szFullPath[MAX_PATH];
  209. V_GetCurrentDirectory( szFullPath, sizeof( szFullPath ) );
  210. V_AppendSlash( szFullPath, sizeof( szFullPath ) );
  211. V_strncat( szFullPath, pFilename, sizeof( szFullPath ) );
  212. V_RemoveDotSlashes( szFullPath );
  213. #if 0
  214. // Add file to Perforce if it isn't there already
  215. if ( Sys_Exists( szFullPath ) )
  216. {
  217. if ( m_bP4AutoAdd && p4 && !p4->IsFileInPerforce( szFullPath ) )
  218. {
  219. p4->OpenFileForAdd( szFullPath );
  220. VPCStatus( "%s automatically opened for add in default changelist.", szFullPath );
  221. }
  222. }
  223. else
  224. {
  225. // g_pVPC->Warning( "%s not found on disk at location specified in project script.", szFullPath );
  226. }
  227. #endif
  228. return true;
  229. }
  230. void CBaseProjectDataCollector::EndFile()
  231. {
  232. m_CurFileConfig.Pop();
  233. m_CurSpecificConfig.Pop();
  234. }
  235. // This is actually just per-file configuration data.
  236. void CBaseProjectDataCollector::FileExcludedFromBuild( bool bExcluded )
  237. {
  238. CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
  239. pConfig->m_bFileExcluded = bExcluded;
  240. }
  241. void CBaseProjectDataCollector::FileIsSchema( bool bIsSchema )
  242. {
  243. CSpecificConfig *pConfig = m_CurSpecificConfig.Top();
  244. pConfig->m_bIsSchema = bIsSchema;
  245. }
  246. bool CBaseProjectDataCollector::RemoveFile( const char *pFilename )
  247. {
  248. bool bRet = false;
  249. int i = m_Files.Find( pFilename );
  250. if ( i != m_Files.InvalidIndex() )
  251. {
  252. delete m_Files[i];
  253. m_Files.RemoveAt( i );
  254. bRet = true;
  255. }
  256. return bRet;
  257. }
  258. void CBaseProjectDataCollector::DoStandardVisualStudioReplacements( const char *pStartString, const char *pFullInputFilename, char *pOut, int outLen )
  259. {
  260. // Decompose the input filename.
  261. char sInputDir[MAX_PATH], sFileBase[MAX_PATH];
  262. if ( !V_ExtractFilePath( pFullInputFilename, sInputDir, sizeof( sInputDir ) ) )
  263. g_pVPC->VPCError( "V_ExtractFilePath failed on %s.", pFullInputFilename );
  264. V_FileBase( pFullInputFilename, sFileBase, sizeof( sFileBase ) );
  265. // Handle $(InputPath), $(InputDir), $(InputName)
  266. char *strings[2] =
  267. {
  268. (char*)stackalloc( outLen ),
  269. (char*)stackalloc( outLen )
  270. };
  271. V_StrSubst( pStartString, "$(InputPath)", pFullInputFilename, strings[0], outLen );
  272. V_StrSubst( strings[0], "$(InputDir)", sInputDir, strings[1], outLen );
  273. V_StrSubst( strings[1], "$(InputName)", sFileBase, strings[0], outLen );
  274. V_StrSubst( strings[0], "$(IntDir)", "$(OBJ_DIR)", strings[1], outLen );
  275. V_StrSubst( strings[1], "$(InputFileName)", pFullInputFilename + Q_strlen(sInputDir), strings[0], outLen );
  276. V_strncpy( pOut, strings[0], outLen );
  277. V_FixSlashes( pOut, '/' );
  278. }