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.

352 lines
8.5 KiB

  1. //========= Copyright � 1996-2006, Valve Corporation, All rights reserved. ============//
  2. //
  3. //
  4. //=====================================================================================//
  5. #include "vpc.h"
  6. CGeneratorDefinition::CGeneratorDefinition()
  7. {
  8. Clear();
  9. }
  10. void CGeneratorDefinition::Clear()
  11. {
  12. m_pPropertyNames = NULL;
  13. m_ScriptName.Clear();
  14. m_NameString.Clear();
  15. m_VersionString.Clear();
  16. m_Tools.Purge();
  17. m_ScriptCRC = 0;
  18. }
  19. void CGeneratorDefinition::IterateAttributesKey( ToolProperty_t *pProperty, KeyValues *pAttributesKV )
  20. {
  21. const char *pAttributeName = pAttributesKV->GetName();
  22. const char *pValue = pAttributesKV->GetString( "" );
  23. //Msg( "Attribute name: %s\n", pAttributeName );
  24. if ( !V_stricmp( pAttributeName, "type" ) )
  25. {
  26. if ( !V_stricmp( pValue, "bool" ) || !V_stricmp( pValue, "boolean" ) )
  27. {
  28. pProperty->m_nType = PT_BOOLEAN;
  29. }
  30. else if ( !V_stricmp( pValue, "string" ) )
  31. {
  32. pProperty->m_nType = PT_STRING;
  33. }
  34. else if ( !V_stricmp( pValue, "list" ) )
  35. {
  36. pProperty->m_nType = PT_LIST;
  37. }
  38. else if ( !V_stricmp( pValue, "int" ) || !V_stricmp( pValue, "integer" ) )
  39. {
  40. pProperty->m_nType = PT_INTEGER;
  41. }
  42. else if ( !V_stricmp( pValue, "ignore" ) || !V_stricmp( pValue, "none" ) )
  43. {
  44. pProperty->m_nType = PT_IGNORE;
  45. }
  46. else if ( !V_stricmp( pValue, "deprecated" ) || !V_stricmp( pValue, "donotuse" ) )
  47. {
  48. pProperty->m_nType = PT_DEPRECATED;
  49. }
  50. else
  51. {
  52. // unknown
  53. g_pVPC->VPCError( "Unknown type '%s' in '%s'", pValue, pProperty->m_ParseString.Get() );
  54. }
  55. }
  56. else if ( !V_stricmp( pAttributeName, "alias" ) )
  57. {
  58. pProperty->m_AliasString = pValue;
  59. }
  60. else if ( !V_stricmp( pAttributeName, "legacy" ) )
  61. {
  62. pProperty->m_LegacyString = pValue;
  63. }
  64. else if ( !V_stricmp( pAttributeName, "InvertOutput" ) )
  65. {
  66. pProperty->m_bInvertOutput = pAttributesKV->GetBool();
  67. }
  68. else if ( !V_stricmp( pAttributeName, "output" ) )
  69. {
  70. pProperty->m_OutputString = pValue;
  71. }
  72. else if ( !V_stricmp( pAttributeName, "fixslashes" ) )
  73. {
  74. pProperty->m_bFixSlashes = pAttributesKV->GetBool();
  75. }
  76. else if ( !V_stricmp( pAttributeName, "PreferSemicolonNoComma" ) )
  77. {
  78. pProperty->m_bPreferSemicolonNoComma = pAttributesKV->GetBool();
  79. }
  80. else if ( !V_stricmp( pAttributeName, "PreferSemicolonNoSpace" ) )
  81. {
  82. pProperty->m_bPreferSemicolonNoSpace = pAttributesKV->GetBool();
  83. }
  84. else if ( !V_stricmp( pAttributeName, "AppendSlash" ) )
  85. {
  86. pProperty->m_bAppendSlash = pAttributesKV->GetBool();
  87. }
  88. else if ( !V_stricmp( pAttributeName, "GlobalProperty" ) )
  89. {
  90. pProperty->m_bEmitAsGlobalProperty = pAttributesKV->GetBool();
  91. }
  92. else if ( !V_stricmp( pAttributeName, "ordinals" ) )
  93. {
  94. if ( pProperty->m_nType == PT_UNKNOWN )
  95. {
  96. pProperty->m_nType = PT_LIST;
  97. }
  98. for ( KeyValues *pKV = pAttributesKV->GetFirstSubKey(); pKV; pKV = pKV->GetNextKey() )
  99. {
  100. const char *pOrdinalName = pKV->GetName();
  101. const char *pOrdinalValue = pKV->GetString();
  102. if ( !pOrdinalValue[0] )
  103. {
  104. g_pVPC->VPCError( "Unknown ordinal value for name '%s' in '%s'", pOrdinalName, pProperty->m_ParseString.Get() );
  105. }
  106. int iIndex = pProperty->m_Ordinals.AddToTail();
  107. pProperty->m_Ordinals[iIndex].m_ParseString = pOrdinalName;
  108. pProperty->m_Ordinals[iIndex].m_ValueString = pOrdinalValue;
  109. }
  110. }
  111. else
  112. {
  113. g_pVPC->VPCError( "Unknown attribute '%s' in '%s'", pAttributeName, pProperty->m_ParseString.Get() );
  114. }
  115. }
  116. void CGeneratorDefinition::IteratePropertyKey( GeneratorTool_t *pTool, KeyValues *pPropertyKV )
  117. {
  118. //Msg( "Property Key name: %s\n", pPropertyKV->GetName() );
  119. int iIndex = pTool->m_Properties.AddToTail();
  120. ToolProperty_t *pProperty = &pTool->m_Properties[iIndex];
  121. pProperty->m_ParseString = pPropertyKV->GetName();
  122. KeyValues *pKV = pPropertyKV->GetFirstSubKey();
  123. if ( !pKV )
  124. return;
  125. for ( ;pKV; pKV = pKV->GetNextKey() )
  126. {
  127. IterateAttributesKey( pProperty, pKV );
  128. }
  129. }
  130. void CGeneratorDefinition::IterateToolKey( KeyValues *pToolKV )
  131. {
  132. //Msg( "Tool Key name: %s\n", pToolKV->GetName() );
  133. // find or create
  134. GeneratorTool_t *pTool = NULL;
  135. for ( int i = 0; i < m_Tools.Count(); i++ )
  136. {
  137. if ( !V_stricmp( pToolKV->GetName(), m_Tools[i].m_ParseString ) )
  138. {
  139. pTool = &m_Tools[i];
  140. break;
  141. }
  142. }
  143. if ( !pTool )
  144. {
  145. int iIndex = m_Tools.AddToTail();
  146. pTool = &m_Tools[iIndex];
  147. }
  148. pTool->m_ParseString = pToolKV->GetName();
  149. KeyValues *pKV = pToolKV->GetFirstSubKey();
  150. if ( !pKV )
  151. return;
  152. for ( ;pKV; pKV = pKV->GetNextKey() )
  153. {
  154. IteratePropertyKey( pTool, pKV );
  155. }
  156. }
  157. void CGeneratorDefinition::AssignIdentifiers()
  158. {
  159. CUtlVector< bool > usedPropertyNames;
  160. int nTotalPropertyNames = 0;
  161. while ( m_pPropertyNames[nTotalPropertyNames].m_nPropertyId >= 0 )
  162. {
  163. nTotalPropertyNames++;
  164. }
  165. usedPropertyNames.SetCount( nTotalPropertyNames );
  166. // assign property identifiers
  167. for ( int i = 0; i < m_Tools.Count(); i++ )
  168. {
  169. GeneratorTool_t *pTool = &m_Tools[i];
  170. // assign the tool keyword
  171. configKeyword_e keyword = g_pVPC->NameToKeyword( pTool->m_ParseString.Get() );
  172. if ( keyword == KEYWORD_UNKNOWN )
  173. {
  174. g_pVPC->VPCError( "Unknown Tool Keyword '%s' in '%s'", pTool->m_ParseString.Get(), m_ScriptName.Get() );
  175. }
  176. pTool->m_nKeyword = keyword;
  177. const char *pPrefix = m_NameString.Get();
  178. const char *pToolName = pTool->m_ParseString.Get();
  179. if ( pToolName[0] == '$' )
  180. {
  181. pToolName++;
  182. }
  183. for ( int j = 0; j < pTool->m_Properties.Count(); j++ )
  184. {
  185. ToolProperty_t *pProperty = &pTool->m_Properties[j];
  186. if ( pProperty->m_nType == PT_IGNORE || pProperty->m_nType == PT_DEPRECATED )
  187. {
  188. continue;
  189. }
  190. const char *pPropertyName = pProperty->m_AliasString.Get();
  191. if ( !pPropertyName[0] )
  192. {
  193. pPropertyName = pProperty->m_ParseString.Get();
  194. }
  195. if ( pPropertyName[0] == '$' )
  196. {
  197. pPropertyName++;
  198. }
  199. CUtlString prefixString = CFmtStr( "%s_%s", pPrefix, pToolName );
  200. bool bFound = false;
  201. for ( int k = 0; k < nTotalPropertyNames && !bFound; k++ )
  202. {
  203. if ( !V_stricmp( prefixString.Get(), m_pPropertyNames[k].m_pPrefixName ) )
  204. {
  205. if ( !V_stricmp( pPropertyName, m_pPropertyNames[k].m_pPropertyName ) )
  206. {
  207. pProperty->m_nPropertyId = m_pPropertyNames[k].m_nPropertyId;
  208. bFound = true;
  209. usedPropertyNames[k] = true;
  210. }
  211. }
  212. }
  213. if ( !bFound )
  214. {
  215. g_pVPC->VPCError( "Could not find PROPERTYNAME( %s, %s ) for %s", prefixString.Get(), pPropertyName, m_ScriptName.Get() );
  216. }
  217. }
  218. }
  219. if ( g_pVPC->IsVerbose() )
  220. {
  221. for ( int i = 0; i < usedPropertyNames.Count(); i++ )
  222. {
  223. if ( !usedPropertyNames[i] )
  224. {
  225. g_pVPC->VPCWarning( "Unused PROPERTYNAME( %s, %s ) in %s", m_pPropertyNames[i].m_pPrefixName, m_pPropertyNames[i].m_pPropertyName, m_ScriptName.Get() );
  226. }
  227. }
  228. }
  229. }
  230. void CGeneratorDefinition::LoadDefinition( const char *pDefnitionName, PropertyName_t *pPropertyNames )
  231. {
  232. Clear();
  233. m_pPropertyNames = pPropertyNames;
  234. g_pVPC->GetScript().PushScript( CFmtStr( "vpc_scripts\\definitions\\%s", pDefnitionName ) );
  235. // project definitions are KV format
  236. KeyValues *pScriptKV = new KeyValues( g_pVPC->GetScript().GetName() );
  237. pScriptKV->LoadFromBuffer( g_pVPC->GetScript().GetName(), g_pVPC->GetScript().GetData() );
  238. m_ScriptName = g_pVPC->GetScript().GetName();
  239. m_ScriptCRC = CRC32_ProcessSingleBuffer( g_pVPC->GetScript().GetData(), strlen( g_pVPC->GetScript().GetData() ) );
  240. m_NameString = pScriptKV->GetName();
  241. KeyValues *pKV = pScriptKV->GetFirstSubKey();
  242. for ( ;pKV; pKV = pKV->GetNextKey() )
  243. {
  244. const char *pKeyName = pKV->GetName();
  245. if ( !V_stricmp( pKeyName, "version" ) )
  246. {
  247. m_VersionString = pKV->GetString();
  248. }
  249. else
  250. {
  251. IterateToolKey( pKV );
  252. }
  253. }
  254. g_pVPC->GetScript().PopScript();
  255. pScriptKV->deleteThis();
  256. g_pVPC->VPCStatus( false, "Definition: '%s' Version: %s", m_NameString.Get(), m_VersionString.Get() );
  257. AssignIdentifiers();
  258. }
  259. const char *CGeneratorDefinition::GetScriptName( CRC32_t *pCRC )
  260. {
  261. if ( pCRC )
  262. {
  263. *pCRC = m_ScriptCRC;
  264. }
  265. return m_ScriptName.Get();
  266. }
  267. ToolProperty_t *CGeneratorDefinition::GetProperty( configKeyword_e keyword, const char *pPropertyName )
  268. {
  269. for ( int i = 0; i < m_Tools.Count(); i++ )
  270. {
  271. GeneratorTool_t *pTool = &m_Tools[i];
  272. if ( pTool->m_nKeyword != keyword )
  273. continue;
  274. for ( int j = 0; j < pTool->m_Properties.Count(); j++ )
  275. {
  276. ToolProperty_t *pToolProperty = &pTool->m_Properties[j];
  277. if ( !V_stricmp( pToolProperty->m_ParseString.Get(), pPropertyName ) )
  278. {
  279. // found
  280. return pToolProperty;
  281. }
  282. if ( !pToolProperty->m_LegacyString.IsEmpty() && !V_stricmp( pToolProperty->m_LegacyString.Get(), pPropertyName ) )
  283. {
  284. // found
  285. return pToolProperty;
  286. }
  287. }
  288. }
  289. // not found
  290. return NULL;
  291. }