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