]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/PcdTools/org/tianocore/pcd/action/PlatformPcdPreprocessAction.java
1, Make exception string friendly, readable.
[mirror_edk2.git] / Tools / Source / PcdTools / org / tianocore / pcd / action / PlatformPcdPreprocessAction.java
CommitLineData
bc262841 1/** @file\r
2 PlatformPcdPreprocessAction class.\r
3\r
4 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's\r
5 pcd build information from fpd file.\r
6 This class will be extended by building tools and wizard tools.\r
7\r
8Copyright (c) 2006, Intel Corporation\r
9All rights reserved. This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18package org.tianocore.pcd.action;\r
19\r
20import java.util.ArrayList;\r
21import java.util.List;\r
22import java.util.UUID;\r
23import java.util.regex.Matcher;\r
24import java.util.regex.Pattern;\r
25\r
26import org.tianocore.DynamicPcdBuildDefinitionsDocument.DynamicPcdBuildDefinitions;\r
27import org.tianocore.PcdBuildDefinitionDocument.PcdBuildDefinition;\r
bc262841 28import org.tianocore.pcd.entity.*;\r
29import org.tianocore.pcd.entity.Token;\r
8b7bd455 30import org.tianocore.pcd.entity.MemoryDatabaseManager;\r
31import org.tianocore.pcd.exception.PlatformPcdPreprocessException;\r
bc262841 32\r
33/**\r
34 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's\r
35 pcd build information from fpd file.\r
36 This class will be extended by building tools and wizard tools.\r
37\r
38**/\r
39public abstract class PlatformPcdPreprocessAction {\r
40 ///\r
41 /// PCD memory database\r
42 ///\r
43 private MemoryDatabaseManager pcdDbManager;\r
44\r
45 /**\r
46 Set parameter pcdDbManager\r
47\r
48 @param pcdDbManager\r
49 **/\r
50 public void setPcdDbManager(MemoryDatabaseManager pcdDbManager) {\r
51 this.pcdDbManager = pcdDbManager;\r
52 }\r
53\r
54 /**\r
55 Get parameter pcdDbManager\r
8b7bd455 56\r
bc262841 57 @return MemoryDatabaseManager\r
58 **/\r
59 public MemoryDatabaseManager getPcdDbManager() {\r
60 return pcdDbManager;\r
61 }\r
62 /**\r
63 Abstract function: retrieve module information from FPD file.\r
64\r
65 In building environement, this function will be implementated by FpdParserTask.\r
66\r
8b7bd455 67 @return List<ModuleInfo> the component array.\r
68 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.\r
69\r
bc262841 70 **/\r
71 public abstract List<ModulePcdInfoFromFpd> getComponentsFromFpd()\r
8b7bd455 72 throws PlatformPcdPreprocessException;\r
bc262841 73\r
74 /**\r
75 Abstract function to get GUID string from SPD file.\r
76\r
77 In building evnironment, this function will be implementated by GlobaData.\r
78\r
79 @param guidCName the CName of GUID\r
80\r
8b7bd455 81 @return String[] Guid information from SPD file.\r
82 @throws PlatformPcdPreprocessException\r
83 Fail to get Guid information from SPD file.\r
bc262841 84 **/\r
85 public abstract String[] getGuidInfoFromSpd(String guidCName)\r
8b7bd455 86 throws PlatformPcdPreprocessException;\r
bc262841 87\r
88 /**\r
89 Abstract function: Verification the PCD data.\r
90\r
91 In different environment, such as building environment and wizard environment,\r
92 it has different implementation according to optimization.\r
93\r
8b7bd455 94 @param cName The token name\r
95 @param moduleName The module who use this PCD token\r
96 @param datum The PCD's datum\r
97 @param datumType The PCD's datum type\r
98 @param maxDatumSize The max size for PCD's Datum.\r
99\r
100 @return String exception strings.\r
bc262841 101\r
bc262841 102 **/\r
103 public abstract String verifyDatum(String cName,\r
104 String moduleName,\r
105 String datum,\r
106 Token.DATUM_TYPE datumType,\r
107 int maxDatumSize);\r
108\r
109 /**\r
110 Abstract function: Get dynamic information for a token\r
111\r
112 @param token\r
113 @param moduleName\r
114\r
115 @return DynamicPcdBuildDefinitions.PcdBuildData\r
116 **/\r
117 public abstract DynamicPcdBuildDefinitions.PcdBuildData\r
118 getDynamicInfoFromFpd(Token token,\r
119 String moduleName)\r
8b7bd455 120 throws PlatformPcdPreprocessException;\r
bc262841 121\r
122 /**\r
123 Abstract function: Get all dynamic PCD information from FPD file.\r
124\r
8b7bd455 125 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.\r
126 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.\r
127\r
bc262841 128 **/\r
129 public abstract List<DynamicPcdBuildDefinitions.PcdBuildData>\r
130 getAllDynamicPcdInfoFromFpd()\r
8b7bd455 131 throws PlatformPcdPreprocessException;\r
bc262841 132\r
133 /**\r
134 Collect all PCD information from FPD file into PCD memory database.\r
135\r
136 **/\r
137 public void initPcdMemoryDbWithPlatformInfo()\r
8b7bd455 138 throws PlatformPcdPreprocessException {\r
bc262841 139 int index = 0;\r
140 int pcdIndex = 0;\r
141 List<PcdBuildDefinition.PcdData> pcdBuildDataArray = new ArrayList<PcdBuildDefinition.PcdData>();\r
142 PcdBuildDefinition.PcdData pcdBuildData = null;\r
143 Token token = null;\r
144 List<ModulePcdInfoFromFpd> modules = null;\r
145 String primaryKey = null;\r
146 String exceptionString = null;\r
147 UsageInstance usageInstance = null;\r
148 Token.PCD_TYPE pcdType = Token.PCD_TYPE.UNKNOWN;\r
149 Token.DATUM_TYPE datumType = Token.DATUM_TYPE.UNKNOWN;\r
150 long tokenNumber = 0;\r
151 String moduleName = null;\r
152 String datum = null;\r
153 int maxDatumSize = 0;\r
154 String[] tokenSpaceStrRet = null;\r
155\r
156 //\r
157 // ----------------------------------------------\r
158 // 1), Get all <ModuleSA> from FPD file.\r
159 // ----------------------------------------------\r
160 //\r
161 modules = getComponentsFromFpd();\r
162\r
163 if (modules == null) {\r
8b7bd455 164 throw new PlatformPcdPreprocessException(\r
165 "No modules in FPD file, Please check whether there are elements in <FrameworkModules> in FPD file!");\r
bc262841 166 }\r
167\r
168 //\r
169 // -------------------------------------------------------------------\r
170 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.\r
171 // -------------------------------------------------------------------\r
172 //\r
f28c0830 173 for (index = 0; index < modules.size(); index++) {\r
bc262841 174 //\r
175 // It is legal for a module does not contains ANY pcd build definitions.\r
176 //\r
177 if (modules.get(index).pcdBuildDefinition == null) {\r
178 continue;\r
179 }\r
180\r
181 pcdBuildDataArray = modules.get(index).pcdBuildDefinition.getPcdDataList();\r
182\r
183 moduleName = modules.get(index).usageId.moduleName;\r
184\r
185 //\r
186 // ----------------------------------------------------------------------\r
187 // 2.1), Loop all Pcd entry for a module and add it into memory database.\r
188 // ----------------------------------------------------------------------\r
189 //\r
f28c0830 190 for (pcdIndex = 0; pcdIndex < pcdBuildDataArray.size(); pcdIndex++) {\r
bc262841 191 pcdBuildData = pcdBuildDataArray.get(pcdIndex);\r
192\r
193 tokenSpaceStrRet = getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
194\r
195 if (tokenSpaceStrRet == null) {\r
8b7bd455 196 throw new PlatformPcdPreprocessException(\r
197 "Fail to get Token space guid for token" + pcdBuildData.getCName() +\r
198 " from all SPD files. You must have an <GuidDeclaration> for this token space Guid");\r
bc262841 199 }\r
200\r
201 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
f28c0830 202 pcdType = Token.getPcdTypeFromString(pcdBuildData.getItemType().toString());\r
bc262841 203 datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
204 tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
205 if (pcdBuildData.getValue() != null) {\r
206 datum = pcdBuildData.getValue().toString();\r
207 } else {\r
208 datum = null;\r
209 }\r
210 maxDatumSize = pcdBuildData.getMaxDatumSize();\r
211\r
212 if ((pcdType == Token.PCD_TYPE.FEATURE_FLAG) &&\r
213 (datumType != Token.DATUM_TYPE.BOOLEAN)){\r
8b7bd455 214 exceptionString = String.format("In FPD file, for PCD %s in module %s, the PCD type is FEATRUE_FLAG but "+\r
bc262841 215 "datum type of this PCD entry is not BOOLEAN!",\r
216 pcdBuildData.getCName(),\r
217 moduleName);\r
8b7bd455 218 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 219 }\r
220\r
221 //\r
222 // -------------------------------------------------------------------------------------------\r
223 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule\r
224 // -------------------------------------------------------------------------------------------\r
225 //\r
226 if (!Token.isDynamic(pcdType)) {\r
227 //\r
228 // Value is required.\r
229 //\r
230 if (datum == null) {\r
8b7bd455 231 exceptionString = String.format("In FPD file, there is no value for PCD entry %s in module %s!",\r
bc262841 232 pcdBuildData.getCName(),\r
233 moduleName);\r
8b7bd455 234 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 235 }\r
236\r
237 //\r
238 // Check whether the datum size is matched datum type.\r
239 //\r
240 if ((exceptionString = verifyDatum(pcdBuildData.getCName(),\r
241 moduleName,\r
242 datum,\r
243 datumType,\r
244 maxDatumSize)) != null) {\r
8b7bd455 245 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 246 }\r
247 }\r
248\r
249 //\r
250 // ---------------------------------------------------------------------------------\r
251 // 2.1.2), Create token or update token information for current anaylized PCD data.\r
252 // ---------------------------------------------------------------------------------\r
253 //\r
254 if (pcdDbManager.isTokenInDatabase(primaryKey)) {\r
255 //\r
256 // If the token is already exist in database, do some necessary checking\r
257 // and add a usage instance into this token in database\r
258 //\r
259 token = pcdDbManager.getTokenByKey(primaryKey);\r
260\r
261 //\r
262 // checking for DatumType, DatumType should be unique for one PCD used in different\r
263 // modules.\r
264 //\r
265 if (token.datumType != datumType) {\r
8b7bd455 266 exceptionString = String.format("In FPD file, the datum type of PCD entry %s is %s, which is different with %s defined in before!",\r
bc262841 267 pcdBuildData.getCName(),\r
268 pcdBuildData.getDatumType().toString(),\r
269 Token.getStringOfdatumType(token.datumType));\r
8b7bd455 270 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 271 }\r
272\r
273 //\r
274 // Check token number is valid\r
275 //\r
276 if (tokenNumber != token.tokenNumber) {\r
8b7bd455 277 exceptionString = String.format("In FPD file, the token number of PCD entry %s in module %s is different with same PCD entry in other modules!",\r
bc262841 278 pcdBuildData.getCName(),\r
279 moduleName);\r
8b7bd455 280 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 281 }\r
282\r
283 //\r
284 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.\r
285 //\r
286 if (token.isDynamicPCD != Token.isDynamic(pcdType)) {\r
8b7bd455 287 exceptionString = String.format("In FPD file, for PCD entry %s in module %s, you define dynamic or non-dynamic PCD type which"+\r
288 " is different with others module's",\r
bc262841 289 token.cName,\r
290 moduleName);\r
8b7bd455 291 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 292 }\r
293\r
294 if (token.isDynamicPCD) {\r
295 //\r
296 // Check datum is equal the datum in dynamic information.\r
297 // For dynamic PCD, you can do not write <Value> in sperated every <PcdBuildDefinition> in different <ModuleSA>,\r
298 // But if you write, the <Value> must be same as the value in <DynamicPcdBuildDefinitions>.\r
299 //\r
300 if (!token.isSkuEnable() &&\r
301 (token.getDefaultSku().type == DynamicTokenValue.VALUE_TYPE.DEFAULT_TYPE) &&\r
302 (datum != null)) {\r
303 if (!datum.equalsIgnoreCase(token.getDefaultSku().value)) {\r
8b7bd455 304 exceptionString = String.format("In FPD file, for dynamic PCD %s in module %s, the datum in <ModuleSA> is "+\r
bc262841 305 "not equal to the datum in <DynamicPcdBuildDefinitions>, it is "+\r
306 "illega! You could no set <Value> in <ModuleSA> for a dynamic PCD!",\r
307 token.cName,\r
308 moduleName);\r
8b7bd455 309 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 310 }\r
311 }\r
312\r
313 if ((maxDatumSize != 0) &&\r
314 (maxDatumSize != token.datumSize)){\r
8b7bd455 315 exceptionString = String.format("In FPD file, for dynamic PCD %s in module %s, the max datum size is %d which "+\r
bc262841 316 "is different with <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",\r
317 token.cName,\r
318 moduleName,\r
319 maxDatumSize,\r
320 token.datumSize);\r
8b7bd455 321 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 322 }\r
323 }\r
324\r
325 } else {\r
326 //\r
327 // If the token is not in database, create a new token instance and add\r
328 // a usage instance into this token in database.\r
329 //\r
330 tokenSpaceStrRet = this.getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
331\r
332 if (tokenSpaceStrRet == null) {\r
8b7bd455 333 throw new PlatformPcdPreprocessException(\r
334 "Fail to get Token space guid for token" + token.cName +\r
335 " from all SPD files. You must have an <GuidDeclaration> for this token space Guid");\r
336\r
bc262841 337 }\r
338\r
339 token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
340\r
341 token.datumType = datumType;\r
342 token.tokenNumber = tokenNumber;\r
343 token.isDynamicPCD = Token.isDynamic(pcdType);\r
344 token.datumSize = maxDatumSize;\r
345\r
346 if (token.isDynamicPCD) {\r
347 //\r
348 // For Dynamic and Dynamic Ex type, need find the dynamic information\r
349 // in <DynamicPcdBuildDefinition> section in FPD file.\r
350 //\r
351 updateDynamicInformation(moduleName,\r
352 token,\r
353 datum,\r
354 maxDatumSize);\r
355 }\r
356\r
357 pcdDbManager.addTokenToDatabase(primaryKey, token);\r
358 }\r
359\r
360 //\r
361 // -----------------------------------------------------------------------------------\r
362 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.\r
363 // -----------------------------------------------------------------------------------\r
364 //\r
365 token.updateSupportPcdType(pcdType);\r
366\r
367 //\r
368 // ------------------------------------------------\r
369 // 2.1.4), Create an usage instance for this token.\r
370 // ------------------------------------------------\r
371 //\r
372 usageInstance = new UsageInstance(token,\r
373 modules.get(index).usageId,\r
374 pcdType,\r
375 datum,\r
376 maxDatumSize);\r
8b7bd455 377 if (!token.addUsageInstance(usageInstance)) {\r
378 throw new PlatformPcdPreprocessException(\r
379 String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+\r
380 "in modules %s in <ModuleSA> to make sure no duplicated definitions in FPD file!",\r
381 token.cName,\r
382 moduleName,\r
383 moduleName));\r
384 }\r
bc262841 385 }\r
386 }\r
387\r
388 //\r
389 // ------------------------------------------------\r
390 // 3), Add unreference dynamic_Ex pcd token into Pcd database.\r
391 // ------------------------------------------------\r
392 //\r
393 List<Token> tokenArray = getUnreferencedDynamicPcd();\r
394 if (tokenArray != null) {\r
f28c0830 395 for (index = 0; index < tokenArray.size(); index++) {\r
bc262841 396 pcdDbManager.addTokenToDatabase(tokenArray.get(index).getPrimaryKeyString(),\r
397 tokenArray.get(index));\r
398 }\r
399 }\r
400 }\r
401\r
402 /**\r
403 Update dynamic information for PCD entry.\r
404\r
405 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in\r
406 FPD file.\r
407\r
408 @param moduleName The name of the module who use this PCD\r
409 @param token The token instance\r
410 @param datum The <datum> in module's PCD information\r
411 @param maxDatumSize The <maxDatumSize> in module's PCD information\r
412\r
413 @return Token\r
414 */\r
415 private Token updateDynamicInformation(String moduleName,\r
416 Token token,\r
417 String datum,\r
418 int maxDatumSize)\r
8b7bd455 419 throws PlatformPcdPreprocessException {\r
bc262841 420 int index = 0;\r
421 int offset;\r
422 String exceptionString = null;\r
423 SkuInstance skuInstance = null;\r
424 String temp;\r
425 boolean hasSkuId0 = false;\r
426 long tokenNumber = 0;\r
427 String hiiDefaultValue = null;\r
428 String[] variableGuidString = null;\r
429\r
430 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
431 DynamicPcdBuildDefinitions.PcdBuildData dynamicInfo = null;\r
432\r
433 dynamicInfo = getDynamicInfoFromFpd(token, moduleName);\r
434 if (dynamicInfo == null) {\r
8b7bd455 435 exceptionString = String.format("In FPD file, for Dynamic PCD %s used by module %s, "+\r
bc262841 436 "there is no dynamic information in <DynamicPcdBuildDefinitions> "+\r
437 "in FPD file, but it is required!",\r
438 token.cName,\r
439 moduleName);\r
8b7bd455 440 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 441 }\r
442\r
443 token.datumSize = dynamicInfo.getMaxDatumSize();\r
444\r
445 exceptionString = verifyDatum(token.cName,\r
446 moduleName,\r
447 null,\r
448 token.datumType,\r
449 token.datumSize);\r
450 if (exceptionString != null) {\r
8b7bd455 451 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 452 }\r
453\r
454 if ((maxDatumSize != 0) &&\r
455 (maxDatumSize != token.datumSize)) {\r
8b7bd455 456 exceptionString = String.format("In FPD file, for dynamic PCD %s, the datum size in module %s is %d, but "+\r
bc262841 457 "the datum size in <DynamicPcdBuildDefinitions> is %d, they are not match!",\r
458 token.cName,\r
459 moduleName,\r
460 maxDatumSize,\r
461 dynamicInfo.getMaxDatumSize());\r
8b7bd455 462 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 463 }\r
464 tokenNumber = Long.decode(dynamicInfo.getToken().toString());\r
465 if (tokenNumber != token.tokenNumber) {\r
8b7bd455 466 exceptionString = String.format("In FPD file, for dynamic PCD %s, the token number in module %s is 0x%x, but"+\r
bc262841 467 "in <DynamicPcdBuildDefinictions>, the token number is 0x%x, they are not match!",\r
468 token.cName,\r
469 moduleName,\r
470 token.tokenNumber,\r
471 tokenNumber);\r
8b7bd455 472 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 473 }\r
474\r
475 token.dynamicExTokenNumber = tokenNumber;\r
476\r
477 skuInfoList = dynamicInfo.getSkuInfoList();\r
478\r
479 //\r
480 // Loop all sku data\r
481 //\r
f28c0830 482 for (index = 0; index < skuInfoList.size(); index++) {\r
bc262841 483 skuInstance = new SkuInstance();\r
484 //\r
485 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
486 //\r
487 temp = skuInfoList.get(index).getSkuId().toString();\r
488 skuInstance.id = Integer.decode(temp);\r
489 if (skuInstance.id == 0) {\r
490 hasSkuId0 = true;\r
491 }\r
492 //\r
493 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
494 //\r
495 if (skuInfoList.get(index).getValue() != null) {\r
496 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
497 if ((exceptionString = verifyDatum(token.cName,\r
498 null,\r
499 skuInfoList.get(index).getValue().toString(),\r
500 token.datumType,\r
501 token.datumSize)) != null) {\r
8b7bd455 502 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 503 }\r
504\r
505 token.skuData.add(skuInstance);\r
506\r
507 //\r
508 // Judege wether is same of datum between module's information\r
509 // and dynamic information.\r
510 //\r
511 if (datum != null) {\r
512 if ((skuInstance.id == 0) &&\r
513 !datum.toString().equalsIgnoreCase(skuInfoList.get(index).getValue().toString())) {\r
8b7bd455 514 exceptionString = "In FPD file, for dynamic PCD " + token.cName + ", the value in module " + moduleName + " is " + datum.toString() + " but the "+\r
bc262841 515 "value of sku 0 data in <DynamicPcdBuildDefinition> is " + skuInstance.value.value + ". They are must be same!"+\r
516 " or you could not define value for a dynamic PCD in every <ModuleSA>!";\r
8b7bd455 517 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 518 }\r
519 }\r
520 continue;\r
521 }\r
522\r
523 //\r
524 // Judge whether is HII group case.\r
525 //\r
526 if (skuInfoList.get(index).getVariableName() != null) {\r
527 exceptionString = null;\r
528 if (skuInfoList.get(index).getVariableGuid() == null) {\r
8b7bd455 529 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
bc262841 530 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
531 token.cName,\r
532 index);\r
533 if (exceptionString != null) {\r
8b7bd455 534 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 535 }\r
536 }\r
537\r
538 if (skuInfoList.get(index).getVariableOffset() == null) {\r
8b7bd455 539 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
bc262841 540 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
541 token.cName,\r
542 index);\r
543 if (exceptionString != null) {\r
8b7bd455 544 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 545 }\r
546 }\r
547\r
548 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
8b7bd455 549 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
bc262841 550 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
551 token.cName,\r
552 index);\r
553 if (exceptionString != null) {\r
8b7bd455 554 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 555 }\r
556 }\r
557\r
558 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
559 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
560 } else {\r
561 hiiDefaultValue = null;\r
562 }\r
563\r
564 if ((exceptionString = verifyDatum(token.cName,\r
565 null,\r
566 hiiDefaultValue,\r
567 token.datumType,\r
568 token.datumSize)) != null) {\r
8b7bd455 569 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 570 }\r
571\r
572 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
573 if (offset > 0xFFFF) {\r
8b7bd455 574 throw new PlatformPcdPreprocessException(\r
575 String.format("In FPD file, for dynamic PCD %s , the variable offset defined in sku %d data "+\r
576 "exceed 64K, it is not allowed!",\r
577 token.cName,\r
578 index));\r
bc262841 579 }\r
580\r
581 //\r
582 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
583 //\r
584 variableGuidString = getGuidInfoFromSpd(skuInfoList.get(index).getVariableGuid().toString());\r
585 if (variableGuidString == null) {\r
8b7bd455 586 throw new PlatformPcdPreprocessException(\r
587 String.format("In FPD file, for dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
588 token.cName,\r
589 skuInfoList.get(index).getVariableGuid().toString()));\r
bc262841 590 }\r
591 String variableStr = skuInfoList.get(index).getVariableName();\r
592 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
593 Matcher matcher = pattern.matcher(variableStr);\r
594 List<String> varNameList = new ArrayList<String>();\r
595 while (matcher.find()){\r
8b7bd455 596 String str = variableStr.substring(matcher.start(),matcher.end());\r
597 varNameList.add(str);\r
bc262841 598 }\r
599\r
600 skuInstance.value.setHiiData(varNameList,\r
601 translateSchemaStringToUUID(variableGuidString[1]),\r
602 skuInfoList.get(index).getVariableOffset(),\r
603 skuInfoList.get(index).getHiiDefaultValue().toString());\r
604 token.skuData.add(skuInstance);\r
605 continue;\r
606 }\r
607\r
608 if (skuInfoList.get(index).getVpdOffset() != null) {\r
609 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
610 token.skuData.add(skuInstance);\r
611 continue;\r
612 }\r
613\r
8b7bd455 614 exceptionString = String.format("In FPD file, for dynamic PCD %s, the dynamic info must "+\r
bc262841 615 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
616 token.cName);\r
8b7bd455 617 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 618 }\r
619\r
620 if (!hasSkuId0) {\r
8b7bd455 621 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
bc262841 622 "no sku id = 0 data, which is required for every dynamic PCD",\r
623 token.cName);\r
8b7bd455 624 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 625 }\r
626\r
627 return token;\r
628 }\r
629\r
630 /**\r
8b7bd455 631 Get all dynamic PCD defined in <DynamicPcdBuildDefinitions> which unreferenced by\r
bc262841 632 any <ModuleSA> in FPD file.\r
8b7bd455 633\r
634 @return List<Token> Return PCD token\r
bc262841 635 **/\r
8b7bd455 636 private List<Token> getUnreferencedDynamicPcd () throws PlatformPcdPreprocessException {\r
bc262841 637 List<Token> tokenArray = new ArrayList<Token>();\r
638 Token token = null;\r
639 List<DynamicPcdBuildDefinitions.PcdBuildData> dynamicPcdBuildDataArray = null;\r
640 DynamicPcdBuildDefinitions.PcdBuildData pcdBuildData = null;\r
641 List<DynamicPcdBuildDefinitions.PcdBuildData.SkuInfo> skuInfoList = null;\r
642 Token.PCD_TYPE pcdType;\r
643 SkuInstance skuInstance = null;\r
644 String primaryKey = null;\r
645 boolean hasSkuId0 = false;\r
646 int index, offset, index2;\r
647 String temp;\r
648 String exceptionString;\r
649 String hiiDefaultValue;\r
650 String tokenSpaceStrRet[];\r
651 String variableGuidString[];\r
652\r
653 dynamicPcdBuildDataArray = getAllDynamicPcdInfoFromFpd();\r
654 if (dynamicPcdBuildDataArray == null) {\r
655 return null;\r
656 }\r
657\r
f28c0830 658 for (index2 = 0; index2 < dynamicPcdBuildDataArray.size(); index2++) {\r
bc262841 659 pcdBuildData = dynamicPcdBuildDataArray.get(index2);\r
660 tokenSpaceStrRet = this.getGuidInfoFromSpd(pcdBuildData.getTokenSpaceGuidCName());\r
661\r
662 if (tokenSpaceStrRet == null) {\r
8b7bd455 663 throw new PlatformPcdPreprocessException("Fail to get Token space guid for token" + pcdBuildData.getCName());\r
bc262841 664 }\r
665\r
666 primaryKey = Token.getPrimaryKeyString(pcdBuildData.getCName(),\r
667 tokenSpaceStrRet[1]);\r
668\r
669 if (pcdDbManager.isTokenInDatabase(primaryKey)) {\r
670 continue;\r
671 }\r
672\r
f28c0830 673 pcdType = Token.getPcdTypeFromString(pcdBuildData.getItemType().toString());\r
bc262841 674 if (pcdType != Token.PCD_TYPE.DYNAMIC_EX) {\r
8b7bd455 675 throw new PlatformPcdPreprocessException(\r
676 String.format("In FPD file, it not allowed for DYNAMIC PCD %s who is no used by any module",\r
677 pcdBuildData.getCName()));\r
bc262841 678 }\r
679\r
680 //\r
681 // Create new token for unreference dynamic PCD token\r
682 //\r
683 token = new Token(pcdBuildData.getCName(), tokenSpaceStrRet[1]);\r
684 token.datumSize = pcdBuildData.getMaxDatumSize();\r
685\r
686\r
687 token.datumType = Token.getdatumTypeFromString(pcdBuildData.getDatumType().toString());\r
688 token.tokenNumber = Long.decode(pcdBuildData.getToken().toString());\r
689 token.dynamicExTokenNumber = token.tokenNumber;\r
690 token.isDynamicPCD = true;\r
691 token.updateSupportPcdType(pcdType);\r
692\r
693 exceptionString = verifyDatum(token.cName,\r
694 null,\r
695 null,\r
696 token.datumType,\r
697 token.datumSize);\r
698 if (exceptionString != null) {\r
8b7bd455 699 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 700 }\r
701\r
702 skuInfoList = pcdBuildData.getSkuInfoList();\r
703\r
704 //\r
705 // Loop all sku data\r
706 //\r
f28c0830 707 for (index = 0; index < skuInfoList.size(); index++) {\r
bc262841 708 skuInstance = new SkuInstance();\r
709 //\r
710 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.\r
711 //\r
712 temp = skuInfoList.get(index).getSkuId().toString();\r
713 skuInstance.id = Integer.decode(temp);\r
714 if (skuInstance.id == 0) {\r
715 hasSkuId0 = true;\r
716 }\r
717 //\r
718 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.\r
719 //\r
720 if (skuInfoList.get(index).getValue() != null) {\r
721 skuInstance.value.setValue(skuInfoList.get(index).getValue().toString());\r
722 if ((exceptionString = verifyDatum(token.cName,\r
723 null,\r
724 skuInfoList.get(index).getValue().toString(),\r
725 token.datumType,\r
726 token.datumSize)) != null) {\r
8b7bd455 727 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 728 }\r
729\r
730 token.skuData.add(skuInstance);\r
731\r
732 continue;\r
733 }\r
734\r
735 //\r
736 // Judge whether is HII group case.\r
737 //\r
738 if (skuInfoList.get(index).getVariableName() != null) {\r
739 exceptionString = null;\r
740 if (skuInfoList.get(index).getVariableGuid() == null) {\r
8b7bd455 741 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
bc262841 742 "file, who use HII, but there is no <VariableGuid> defined for Sku %d data!",\r
743 token.cName,\r
744 index);\r
745 if (exceptionString != null) {\r
8b7bd455 746 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 747 }\r
748 }\r
749\r
750 if (skuInfoList.get(index).getVariableOffset() == null) {\r
8b7bd455 751 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
bc262841 752 "file, who use HII, but there is no <VariableOffset> defined for Sku %d data!",\r
753 token.cName,\r
754 index);\r
755 if (exceptionString != null) {\r
8b7bd455 756 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 757 }\r
758 }\r
759\r
760 if (skuInfoList.get(index).getHiiDefaultValue() == null) {\r
8b7bd455 761 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+\r
bc262841 762 "file, who use HII, but there is no <HiiDefaultValue> defined for Sku %d data!",\r
763 token.cName,\r
764 index);\r
765 if (exceptionString != null) {\r
8b7bd455 766 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 767 }\r
768 }\r
769\r
770 if (skuInfoList.get(index).getHiiDefaultValue() != null) {\r
771 hiiDefaultValue = skuInfoList.get(index).getHiiDefaultValue().toString();\r
772 } else {\r
773 hiiDefaultValue = null;\r
774 }\r
775\r
776 if ((exceptionString = verifyDatum(token.cName,\r
777 null,\r
778 hiiDefaultValue,\r
779 token.datumType,\r
780 token.datumSize)) != null) {\r
8b7bd455 781 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 782 }\r
783\r
784 offset = Integer.decode(skuInfoList.get(index).getVariableOffset());\r
785 if (offset > 0xFFFF) {\r
8b7bd455 786 throw new PlatformPcdPreprocessException(\r
787 String.format("In FPD file, for dynamic PCD %s , the variable offset defined in sku %d data "+\r
788 "exceed 64K, it is not allowed!",\r
789 token.cName,\r
790 index));\r
bc262841 791 }\r
792\r
793 //\r
794 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.\r
795 //\r
796 variableGuidString = this.getGuidInfoFromSpd(skuInfoList.get(index).getVariableGuid().toString());\r
797 if (variableGuidString == null) {\r
8b7bd455 798 throw new PlatformPcdPreprocessException(\r
799 String.format("In FPD file, for dynamic PCD %s, the variable guid %s can be found in all SPD file!",\r
800 token.cName,\r
801 skuInfoList.get(index).getVariableGuid().toString()));\r
bc262841 802 }\r
803 String variableStr = skuInfoList.get(index).getVariableName();\r
804 Pattern pattern = Pattern.compile("0x([a-fA-F0-9]){4}");\r
805 Matcher matcher = pattern.matcher(variableStr);\r
806 List<String> varNameList = new ArrayList<String>();\r
807 while (matcher.find()){\r
8b7bd455 808 String str = variableStr.substring(matcher.start(),matcher.end());\r
809 varNameList.add(str);\r
bc262841 810 }\r
811\r
812 skuInstance.value.setHiiData(varNameList,\r
813 translateSchemaStringToUUID(variableGuidString[1]),\r
814 skuInfoList.get(index).getVariableOffset(),\r
815 skuInfoList.get(index).getHiiDefaultValue().toString());\r
816 token.skuData.add(skuInstance);\r
817 continue;\r
818 }\r
819\r
820 if (skuInfoList.get(index).getVpdOffset() != null) {\r
821 skuInstance.value.setVpdData(skuInfoList.get(index).getVpdOffset());\r
822 token.skuData.add(skuInstance);\r
823 continue;\r
824 }\r
825\r
8b7bd455 826 exceptionString = String.format("In FPD file, for dynamic PCD %s, the dynamic info must "+\r
bc262841 827 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",\r
828 token.cName);\r
8b7bd455 829 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 830 }\r
831\r
832 if (!hasSkuId0) {\r
8b7bd455 833 exceptionString = String.format("In FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there are "+\r
bc262841 834 "no sku id = 0 data, which is required for every dynamic PCD",\r
835 token.cName);\r
8b7bd455 836 throw new PlatformPcdPreprocessException(exceptionString);\r
bc262841 837 }\r
838\r
839 tokenArray.add(token);\r
840 }\r
841\r
842 return tokenArray;\r
843 }\r
844\r
845 /**\r
846 Translate the schema string to UUID instance.\r
847\r
848 In schema, the string of UUID is defined as following two types string:\r
849 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(\r
850 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?\r
851\r
852 2) GuidNamingConvention: pattern =\r
853 [a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\r
854\r
855 This function will convert string and create uuid instance.\r
856\r
857 @param uuidString UUID string in XML file\r
858\r
859 @return UUID UUID instance\r
860 **/\r
861 private UUID translateSchemaStringToUUID(String uuidString)\r
8b7bd455 862 throws PlatformPcdPreprocessException {\r
bc262841 863 String temp;\r
864 String[] splitStringArray;\r
865 int index;\r
866 int chIndex;\r
867 int chLen;\r
868\r
869 if (uuidString == null) {\r
870 return null;\r
871 }\r
872\r
873 if (uuidString.length() == 0) {\r
874 return null;\r
875 }\r
876\r
877 if (uuidString.equals("0") ||\r
878 uuidString.equalsIgnoreCase("0x0")) {\r
879 return new UUID(0, 0);\r
880 }\r
881\r
882 uuidString = uuidString.replaceAll("\\{", "");\r
883 uuidString = uuidString.replaceAll("\\}", "");\r
884\r
885 //\r
886 // If the UUID schema string is GuidArrayType type then need translate\r
887 // to GuidNamingConvention type at first.\r
888 //\r
889 if ((uuidString.charAt(0) == '0') && ((uuidString.charAt(1) == 'x') || (uuidString.charAt(1) == 'X'))) {\r
890 splitStringArray = uuidString.split("," );\r
891 if (splitStringArray.length != 11) {\r
8b7bd455 892 throw new PlatformPcdPreprocessException ("Wrong format for UUID string: " + uuidString);\r
bc262841 893 }\r
894\r
895 //\r
896 // Remove blank space from these string and remove header string "0x"\r
897 //\r
f28c0830 898 for (index = 0; index < 11; index++) {\r
bc262841 899 splitStringArray[index] = splitStringArray[index].trim();\r
900 splitStringArray[index] = splitStringArray[index].substring(2, splitStringArray[index].length());\r
901 }\r
902\r
903 //\r
904 // Add heading '0' to normalize the string length\r
905 //\r
f28c0830 906 for (index = 3; index < 11; index++) {\r
bc262841 907 chLen = splitStringArray[index].length();\r
f28c0830 908 for (chIndex = 0; chIndex < 2 - chLen; chIndex++) {\r
bc262841 909 splitStringArray[index] = "0" + splitStringArray[index];\r
910 }\r
911 }\r
912\r
913 //\r
914 // construct the final GuidNamingConvention string\r
915 //\r
916 temp = String.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",\r
917 splitStringArray[0],\r
918 splitStringArray[1],\r
919 splitStringArray[2],\r
920 splitStringArray[3],\r
921 splitStringArray[4],\r
922 splitStringArray[5],\r
923 splitStringArray[6],\r
924 splitStringArray[7],\r
925 splitStringArray[8],\r
926 splitStringArray[9],\r
927 splitStringArray[10]);\r
928 uuidString = temp;\r
929 }\r
930\r
931 return UUID.fromString(uuidString);\r
932 }\r
933}\r
934\r