2 PlatformPcdPreprocessAction class.
4 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's
5 pcd build information from fpd file.
6 This class will be extended by building tools and wizard tools.
8 Copyright (c) 2006, Intel Corporation
9 All rights reserved. This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 package org
.tianocore
.pcd
.action
;
20 import java
.util
.ArrayList
;
21 import java
.util
.List
;
22 import java
.util
.UUID
;
23 import java
.util
.regex
.Matcher
;
24 import java
.util
.regex
.Pattern
;
26 import org
.tianocore
.DynamicPcdBuildDefinitionsDocument
.DynamicPcdBuildDefinitions
;
27 import org
.tianocore
.PcdBuildDefinitionDocument
.PcdBuildDefinition
;
28 import org
.tianocore
.pcd
.entity
.*;
29 import org
.tianocore
.pcd
.entity
.Token
;
30 import org
.tianocore
.pcd
.entity
.MemoryDatabaseManager
;
31 import org
.tianocore
.pcd
.exception
.PlatformPcdPreprocessException
;
34 The abstract parent class PlatformPcdPreprocessAction, This class is to collect platform's
35 pcd build information from fpd file.
36 This class will be extended by building tools and wizard tools.
39 public abstract class PlatformPcdPreprocessAction
{
41 /// PCD memory database
43 private MemoryDatabaseManager pcdDbManager
;
46 /// Errors string when perform preprocess
48 private String errorString
;
51 /// the count of errors when perform preprocess
53 private int errorCount
;
56 Default contructor function
58 public PlatformPcdPreprocessAction() {
65 Set parameter pcdDbManager
69 public void setPcdDbManager(MemoryDatabaseManager pcdDbManager
) {
70 this.pcdDbManager
= pcdDbManager
;
74 Get parameter pcdDbManager
76 @return MemoryDatabaseManager
78 public MemoryDatabaseManager
getPcdDbManager() {
83 Abstract function: retrieve module information from FPD file.
85 In building environement, this function will be implementated by FpdParserTask.
87 @return List<ModulePcdInfoFromFpd> the component array.
88 @throws PlatformPcdPreprocessException get all modules in <ModuleSA> in FPD file.
91 public abstract List
<ModulePcdInfoFromFpd
> getComponentsFromFpd()
92 throws PlatformPcdPreprocessException
;
95 Abstract function to get GUID string from SPD file.
97 In building evnironment, this function will be implementated by GlobaData.
99 @param guidCName the CName of GUID
101 @return String Guid information from SPD file.
102 @throws PlatformPcdPreprocessException
103 Fail to get Guid information from SPD file.
105 public abstract String
getGuidInfoFromSpd(String guidCName
) throws PlatformPcdPreprocessException
;
108 Abstract function: Verification the PCD data.
110 In different environment, such as building environment and wizard environment,
111 it has different implementation according to optimization.
113 @param cName The token name
114 @param moduleName The module who use this PCD token
115 @param datum The PCD's datum
116 @param datumType The PCD's datum type
117 @param maxDatumSize The max size for PCD's Datum.
119 @return String exception strings.
122 public abstract String
verifyDatum(String cName
, String moduleName
, String datum
,
123 Token
.DATUM_TYPE datumType
, int maxDatumSize
);
126 Abstract function: Get dynamic information for a token
131 @return DynamicPcdBuildDefinitions.PcdBuildData
133 public abstract DynamicPcdBuildDefinitions
.PcdBuildData
134 getDynamicInfoFromFpd(Token token
,
136 throws PlatformPcdPreprocessException
;
139 Abstract function: Get all dynamic PCD information from FPD file.
141 @return List<DynamicPcdBuildDefinitions.PcdBuildData> All DYNAMIC PCD list in <DynamicPcdBuildDefinitions> in FPD file.
142 @throws PlatformPcdPreprocessBuildException Failure to get dynamic information list.
145 public abstract List
<DynamicPcdBuildDefinitions
.PcdBuildData
>
146 getAllDynamicPcdInfoFromFpd()
147 throws PlatformPcdPreprocessException
;
150 Return the error string after preprocess
152 @return String error string
154 public String
getErrorString() {
158 public void putError(String error
) {
159 if (errorString
== null) {
160 errorString
= "### ERROR[" + errorCount
+ "] ###\r\n" + error
+ "\r\n";
162 errorString
+= "### ERROR[" + errorCount
+ "] ###\r\n" + error
+ "\r\n";
169 Collect all PCD information from FPD file into PCD memory database.
172 public void initPcdMemoryDbWithPlatformInfo()
173 throws PlatformPcdPreprocessException
{
176 List
<PcdBuildDefinition
.PcdData
> pcdBuildDataArray
= new ArrayList
<PcdBuildDefinition
.PcdData
>();
177 PcdBuildDefinition
.PcdData pcdBuildData
;
179 List
<ModulePcdInfoFromFpd
> modules
;
181 String exceptionString
;
182 UsageInstance usageInstance
;
183 Token
.PCD_TYPE pcdType
= Token
.PCD_TYPE
.UNKNOWN
;
184 Token
.DATUM_TYPE datumType
= Token
.DATUM_TYPE
.UNKNOWN
;
189 String tokenSpaceStrRet
;
190 ModulePcdInfoFromFpd curModule
;
193 // ----------------------------------------------
194 // 1), Get all <ModuleSA> from FPD file.
195 // ----------------------------------------------
197 modules
= getComponentsFromFpd();
199 if (modules
== null) {
200 throw new PlatformPcdPreprocessException(
201 "No modules found in the FPD file.\nPlease check whether there are elements in <FrameworkModules> in the FPD file!");
205 // -------------------------------------------------------------------
206 // 2), Loop all modules to process <PcdBuildDeclarations> for each module.
207 // -------------------------------------------------------------------
209 for (index
= 0; index
< modules
.size(); index
++) {
210 curModule
= modules
.get(index
);
213 // It is legal for a module does not contains ANY pcd build definitions.
215 if (curModule
.pcdBuildDefinition
== null) {
219 pcdBuildDataArray
= curModule
.pcdBuildDefinition
.getPcdDataList();
220 moduleName
= curModule
.usageId
.moduleName
;
223 // ----------------------------------------------------------------------
224 // 2.1), Loop all Pcd entry for a module and add it into memory database.
225 // ----------------------------------------------------------------------
227 for (pcdIndex
= 0; pcdIndex
< pcdBuildDataArray
.size(); pcdIndex
++) {
228 pcdBuildData
= pcdBuildDataArray
.get(pcdIndex
);
230 tokenSpaceStrRet
= getGuidInfoFromSpd(pcdBuildData
.getTokenSpaceGuidCName());
232 if (tokenSpaceStrRet
== null) {
233 putError("Failed to get Token Space Guid for token " + pcdBuildData
.getCName() +
234 " from any SPD file. You must have an <GuidDeclaration> for this Token Space Guid!");
236 // Do not break preprocess, continues to analysis.
237 // All errors will be summary to be shown.
242 primaryKey
= Token
.getPrimaryKeyString(pcdBuildData
.getCName(), tokenSpaceStrRet
);
243 pcdType
= Token
.getPcdTypeFromString(pcdBuildData
.getItemType().toString());
244 datumType
= Token
.getdatumTypeFromString(pcdBuildData
.getDatumType().toString());
245 tokenNumber
= Long
.decode(pcdBuildData
.getToken().toString());
246 if (pcdBuildData
.getValue() != null) {
247 datum
= pcdBuildData
.getValue().toString();
251 maxDatumSize
= pcdBuildData
.getMaxDatumSize();
253 if ((pcdType
== Token
.PCD_TYPE
.FEATURE_FLAG
) &&
254 (datumType
!= Token
.DATUM_TYPE
.BOOLEAN
)){
255 exceptionString
= String
.format("In FPD file, for PCD %s in module %s, the PCD type is FEATURE_FLAG but "+
256 "datum type for this PCD entry is not BOOLEAN!",
257 pcdBuildData
.getCName(),
259 putError(exceptionString
);
261 // Do not break preprocess, continues to analysis.
262 // All errors will be summary to be shown.
268 // -------------------------------------------------------------------------------------------
269 // 2.1.1), Do some necessary checking work for FixedAtBuild, FeatureFlag and PatchableInModule
270 // -------------------------------------------------------------------------------------------
272 if (!Token
.isDynamic(pcdType
)) {
274 // Value is required.
277 exceptionString
= String
.format("In the FPD file, there is no value for PCD entry %s in module %s!",
278 pcdBuildData
.getCName(),
280 putError(exceptionString
);
282 // Do not break preprocess, continues to analysis.
283 // All errors will be summary to be shown.
289 // Check whether the datum size is matched datum type.
291 if ((exceptionString
= verifyDatum(pcdBuildData
.getCName(),
295 maxDatumSize
)) != null) {
296 putError(exceptionString
);
298 // Do not break preprocess, continues to analysis.
299 // All errors will be summary to be shown.
306 // ---------------------------------------------------------------------------------
307 // 2.1.2), Create token or update token information for current anaylized PCD data.
308 // ---------------------------------------------------------------------------------
310 if (pcdDbManager
.isTokenInDatabase(primaryKey
)) {
312 // If the token is already exist in database, do some necessary checking
313 // and add a usage instance into this token in database
315 token
= pcdDbManager
.getTokenByKey(primaryKey
);
318 // checking for DatumType, DatumType should be unique for one PCD used in different
321 if (token
.datumType
!= datumType
) {
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!",
323 pcdBuildData
.getCName(),
324 pcdBuildData
.getDatumType().toString(),
325 Token
.getStringOfdatumType(token
.datumType
));
326 putError(exceptionString
);
328 // Do not break preprocess, continues to analysis.
329 // All errors will be summary to be shown.
335 // Check token number is valid
337 if (tokenNumber
!= token
.tokenNumber
) {
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!",
339 pcdBuildData
.getCName(),
341 putError(exceptionString
);
343 // Do not break preprocess, continues to analysis.
344 // All errors will be summary to be shown.
350 // For same PCD used in different modules, the PCD type should all be dynamic or non-dynamic.
352 if (token
.isDynamicPCD
!= Token
.isDynamic(pcdType
)) {
353 exceptionString
= String
.format("In the FPD file, for PCD entry %s in module %s, you defined dynamic or non-dynamic PCD type which"+
354 " is different from other module's definition.",
357 putError(exceptionString
);
359 // Do not break preprocess, continues to analysis.
360 // All errors will be summary to be shown.
365 if (token
.isDynamicPCD
) {
366 if ((maxDatumSize
!= 0) &&
367 (maxDatumSize
!= token
.datumSize
)){
368 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in module %s, the max datum size is %d which "+
369 "is different than <MaxDatumSize> %d defined in <DynamicPcdBuildDefinitions>!",
374 putError(exceptionString
);
376 // Do not break preprocess, continues to analysis.
377 // All errors will be summary to be shown.
385 // If the token is not in database, create a new token instance and add
386 // a usage instance into this token in database.
388 tokenSpaceStrRet
= getGuidInfoFromSpd(pcdBuildData
.getTokenSpaceGuidCName());
390 if (tokenSpaceStrRet
== null) {
391 putError("Failed to get the Token Space Guid for token" + token
.cName
+
392 " from any SPD file. You must have a <GuidDeclaration> for this Token Space Guid!");
394 // Do not break preprocess, continues to analysis.
395 // All errors will be summary to be shown.
400 token
= new Token(pcdBuildData
.getCName(), tokenSpaceStrRet
);
402 token
.datumType
= datumType
;
403 token
.tokenNumber
= tokenNumber
;
404 token
.isDynamicPCD
= Token
.isDynamic(pcdType
);
405 token
.datumSize
= maxDatumSize
;
407 if (token
.isDynamicPCD
) {
409 // For Dynamic and Dynamic Ex type, need find the dynamic information
410 // in <DynamicPcdBuildDefinition> section in FPD file.
412 if (null == updateDynamicInformation(moduleName
,
420 pcdDbManager
.addTokenToDatabase(primaryKey
, token
);
424 // -----------------------------------------------------------------------------------
425 // 2.1.3), Add the PcdType in current module into this Pcd token's supported PCD type.
426 // -----------------------------------------------------------------------------------
428 token
.updateSupportPcdType(pcdType
);
431 // ------------------------------------------------
432 // 2.1.4), Create an usage instance for this token.
433 // ------------------------------------------------
435 usageInstance
= new UsageInstance(token
,
440 if (!token
.addUsageInstance(usageInstance
)) {
441 putError(String
.format("PCD %s for module %s(%s) already exists in the database.\nPlease check all PCD build entries "+
442 "in the %s module's <ModuleSA> section to make sure there are no duplicated definitions in the FPD file!",
444 curModule
.usageId
.moduleGuid
,
453 // ------------------------------------------------
454 // 3), Add unreference dynamic_Ex pcd token into Pcd database.
455 // ------------------------------------------------
457 List
<Token
> tokenArray
= getUnreferencedDynamicPcd();
458 if (tokenArray
!= null) {
459 for (index
= 0; index
< tokenArray
.size(); index
++) {
460 pcdDbManager
.addTokenToDatabase(tokenArray
.get(index
).getPrimaryKeyString(),
461 tokenArray
.get(index
));
467 Update dynamic information for PCD entry.
469 Dynamic information is retrieved from <PcdDynamicBuildDeclarations> in
472 @param moduleName The name of the module who use this PCD
473 @param token The token instance
474 @param datum The <datum> in module's PCD information
475 @param maxDatumSize The <maxDatumSize> in module's PCD information
479 private Token
updateDynamicInformation(String moduleName
,
483 throws PlatformPcdPreprocessException
{
486 String exceptionString
= null;
487 SkuInstance skuInstance
= null;
489 boolean hasSkuId0
= false;
490 long tokenNumber
= 0;
491 String hiiDefaultValue
= null;
492 String variableGuidString
= null;
494 List
<DynamicPcdBuildDefinitions
.PcdBuildData
.SkuInfo
> skuInfoList
= null;
495 DynamicPcdBuildDefinitions
.PcdBuildData dynamicInfo
= null;
497 dynamicInfo
= getDynamicInfoFromFpd(token
, moduleName
);
498 if (dynamicInfo
== null) {
499 exceptionString
= String
.format("In the FPD file, the Dynamic PCD %s is used by module %s.\n" +
500 "However, there is no dynamic information in the <DynamicPcdBuildDefinitions> " +
501 "section of the FPD file. This section is required!",
504 putError(exceptionString
);
508 token
.datumSize
= dynamicInfo
.getMaxDatumSize();
510 exceptionString
= verifyDatum(token
.cName
,
515 if (exceptionString
!= null) {
516 throw new PlatformPcdPreprocessException(exceptionString
);
519 if ((maxDatumSize
!= 0) &&
520 (maxDatumSize
!= token
.datumSize
)) {
521 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s, the datum size in module %s is %d, but "+
522 "the datum size in <DynamicPcdBuildDefinitions> is %d, they do not match!",
526 dynamicInfo
.getMaxDatumSize());
527 putError(exceptionString
);
530 tokenNumber
= Long
.decode(dynamicInfo
.getToken().toString());
531 if (tokenNumber
!= token
.tokenNumber
) {
532 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s, the token number in module %s is 0x%x, but "+
533 "in the <DynamicPcdBuildDefinictions> section, the token number is 0x%x, they do not match!",
538 putError(exceptionString
);
542 token
.dynamicExTokenNumber
= tokenNumber
;
544 skuInfoList
= dynamicInfo
.getSkuInfoList();
549 for (index
= 0; index
< skuInfoList
.size(); index
++) {
550 skuInstance
= new SkuInstance();
552 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
554 temp
= skuInfoList
.get(index
).getSkuId().toString();
555 skuInstance
.id
= Integer
.decode(temp
);
556 if (skuInstance
.id
== 0) {
560 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
562 if (skuInfoList
.get(index
).getValue() != null) {
563 skuInstance
.value
.setValue(skuInfoList
.get(index
).getValue().toString());
564 if ((exceptionString
= verifyDatum(token
.cName
,
566 skuInfoList
.get(index
).getValue().toString(),
568 token
.datumSize
)) != null) {
569 putError(exceptionString
);
573 token
.skuData
.add(skuInstance
);
579 // Judge whether is HII group case.
581 if (skuInfoList
.get(index
).getVariableName() != null) {
582 exceptionString
= null;
583 if (skuInfoList
.get(index
).getVariableGuid() == null) {
584 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
585 "file, use of HII was defined, but there is no <VariableGuid> defined for SKU %d data!",
588 putError(exceptionString
);
592 if (skuInfoList
.get(index
).getVariableOffset() == null) {
593 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
594 "file, use of HII was defined, but there is no <VariableOffset> defined for SKU %d data!",
597 putError(exceptionString
);
601 if (skuInfoList
.get(index
).getHiiDefaultValue() == null) {
602 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions> section in FPD "+
603 "file, use of HII was defined, but there is no <HiiDefaultValue> defined for SKU %d data!",
606 putError(exceptionString
);
610 if (skuInfoList
.get(index
).getHiiDefaultValue() != null) {
611 hiiDefaultValue
= skuInfoList
.get(index
).getHiiDefaultValue().toString();
613 hiiDefaultValue
= null;
616 if ((exceptionString
= verifyDatum(token
.cName
,
620 token
.datumSize
)) != null) {
621 throw new PlatformPcdPreprocessException(exceptionString
);
624 offset
= Integer
.decode(skuInfoList
.get(index
).getVariableOffset());
625 if (offset
> 0xFFFF) {
626 putError(String
.format("In the FPD file, for dynamic PCD %s, the variable offset defined in SKU %d data "+
627 "exceeds 64K, which is not allowed!",
634 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.
636 variableGuidString
= getGuidInfoFromSpd(skuInfoList
.get(index
).getVariableGuid().toString());
637 if (variableGuidString
== null) {
638 putError(String
.format("In the FPD file, for dynamic PCD %s, the variable guid: %s cannot be found in any SPD file!",
640 skuInfoList
.get(index
).getVariableGuid().toString()));
643 String variableStr
= skuInfoList
.get(index
).getVariableName();
644 Pattern pattern
= Pattern
.compile("0x([a-fA-F0-9]){4}");
645 Matcher matcher
= pattern
.matcher(variableStr
);
646 List
<String
> varNameList
= new ArrayList
<String
>();
647 while (matcher
.find()){
648 String str
= variableStr
.substring(matcher
.start(),matcher
.end());
649 varNameList
.add(str
);
652 skuInstance
.value
.setHiiData(varNameList
,
653 translateSchemaStringToUUID(variableGuidString
),
654 skuInfoList
.get(index
).getVariableOffset(),
655 skuInfoList
.get(index
).getHiiDefaultValue().toString());
656 token
.skuData
.add(skuInstance
);
660 if (skuInfoList
.get(index
).getVpdOffset() != null) {
661 skuInstance
.value
.setVpdData(skuInfoList
.get(index
).getVpdOffset());
662 token
.skuData
.add(skuInstance
);
666 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s, the dynamic info must "+
667 "be one of: 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
669 putError(exceptionString
);
674 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there is "+
675 "no SKU ID = 0 data, which is required for every dynamic PCD",
677 putError(exceptionString
);
685 Get all dynamic PCD defined in <DynamicPcdBuildDefinitions> which unreferenced by
686 any <ModuleSA> in FPD file.
688 @return List<Token> Return PCD token
690 private List
<Token
> getUnreferencedDynamicPcd () throws PlatformPcdPreprocessException
{
691 List
<Token
> tokenArray
= new ArrayList
<Token
>();
693 List
<DynamicPcdBuildDefinitions
.PcdBuildData
> dynamicPcdBuildDataArray
= null;
694 DynamicPcdBuildDefinitions
.PcdBuildData pcdBuildData
= null;
695 List
<DynamicPcdBuildDefinitions
.PcdBuildData
.SkuInfo
> skuInfoList
= null;
696 Token
.PCD_TYPE pcdType
;
697 SkuInstance skuInstance
= null;
698 String primaryKey
= null;
699 boolean hasSkuId0
= false;
700 int index
, offset
, index2
;
702 String exceptionString
;
703 String hiiDefaultValue
;
704 String tokenSpaceStrRet
;
705 String variableGuidString
;
707 dynamicPcdBuildDataArray
= getAllDynamicPcdInfoFromFpd();
708 if (dynamicPcdBuildDataArray
== null) {
712 for (index2
= 0; index2
< dynamicPcdBuildDataArray
.size(); index2
++) {
713 pcdBuildData
= dynamicPcdBuildDataArray
.get(index2
);
714 tokenSpaceStrRet
= getGuidInfoFromSpd(pcdBuildData
.getTokenSpaceGuidCName());
716 if (tokenSpaceStrRet
== null) {
717 putError("Failed to get the Token Space Guid for token" + pcdBuildData
.getCName());
721 primaryKey
= Token
.getPrimaryKeyString(pcdBuildData
.getCName(),
724 if (pcdDbManager
.isTokenInDatabase(primaryKey
)) {
728 pcdType
= Token
.getPcdTypeFromString(pcdBuildData
.getItemType().toString());
729 if (pcdType
!= Token
.PCD_TYPE
.DYNAMIC_EX
) {
730 putError(String
.format("In the FPD file, it not allowed to define DYNAMIC PCD %s that is not used by any module",
731 pcdBuildData
.getCName()));
736 // Create new token for unreference dynamic PCD token
738 token
= new Token(pcdBuildData
.getCName(), tokenSpaceStrRet
);
739 token
.datumSize
= pcdBuildData
.getMaxDatumSize();
742 token
.datumType
= Token
.getdatumTypeFromString(pcdBuildData
.getDatumType().toString());
743 token
.tokenNumber
= Long
.decode(pcdBuildData
.getToken().toString());
744 token
.dynamicExTokenNumber
= token
.tokenNumber
;
745 token
.isDynamicPCD
= true;
746 token
.updateSupportPcdType(pcdType
);
748 exceptionString
= verifyDatum(token
.cName
,
753 if (exceptionString
!= null) {
754 putError(exceptionString
);
758 skuInfoList
= pcdBuildData
.getSkuInfoList();
763 for (index
= 0; index
< skuInfoList
.size(); index
++) {
764 skuInstance
= new SkuInstance();
766 // Although SkuId in schema is BigInteger, but in fact, sku id is 32 bit value.
768 temp
= skuInfoList
.get(index
).getSkuId().toString();
769 skuInstance
.id
= Integer
.decode(temp
);
770 if (skuInstance
.id
== 0) {
774 // Judge whether is DefaultGroup at first, because most case is DefautlGroup.
776 if (skuInfoList
.get(index
).getValue() != null) {
777 skuInstance
.value
.setValue(skuInfoList
.get(index
).getValue().toString());
778 if ((exceptionString
= verifyDatum(token
.cName
,
780 skuInfoList
.get(index
).getValue().toString(),
782 token
.datumSize
)) != null) {
783 putError(exceptionString
);
787 token
.skuData
.add(skuInstance
);
793 // Judge whether is HII group case.
795 if (skuInfoList
.get(index
).getVariableName() != null) {
796 exceptionString
= null;
797 if (skuInfoList
.get(index
).getVariableGuid() == null) {
798 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in the <DynamicPcdBuildDefinitions> section of the FPD "+
799 "file, use of HII is defined, but there is no <VariableGuid> defined for SKU %d data!",
802 putError(exceptionString
);
806 if (skuInfoList
.get(index
).getVariableOffset() == null) {
807 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in the <DynamicPcdBuildDefinitions> section of the FPD "+
808 "file, use of HII is defined, but there is no <VariableOffset> defined for SKU %d data!",
811 putError(exceptionString
);
815 if (skuInfoList
.get(index
).getHiiDefaultValue() == null) {
816 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in the <DynamicPcdBuildDefinitions> section of the FPD "+
817 "file, use of HII is defined, but there is no <HiiDefaultValue> defined for SKU %d data!",
820 putError(exceptionString
);
824 if (skuInfoList
.get(index
).getHiiDefaultValue() != null) {
825 hiiDefaultValue
= skuInfoList
.get(index
).getHiiDefaultValue().toString();
827 hiiDefaultValue
= null;
830 if ((exceptionString
= verifyDatum(token
.cName
,
834 token
.datumSize
)) != null) {
835 putError(exceptionString
);
839 offset
= Integer
.decode(skuInfoList
.get(index
).getVariableOffset());
840 if (offset
> 0xFFFF) {
841 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s, the variable offset defined in SKU %d data "+
842 "exceeds 64K, which is not allowed!",
845 putError(exceptionString
);
850 // Get variable guid string according to the name of guid which will be mapped into a GUID in SPD file.
852 variableGuidString
= getGuidInfoFromSpd(skuInfoList
.get(index
).getVariableGuid().toString());
853 if (variableGuidString
== null) {
854 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s, the variable guid %s cannot be found in any SPD file!",
856 skuInfoList
.get(index
).getVariableGuid().toString());
857 putError(exceptionString
);
860 String variableStr
= skuInfoList
.get(index
).getVariableName();
861 Pattern pattern
= Pattern
.compile("0x([a-fA-F0-9]){4}");
862 Matcher matcher
= pattern
.matcher(variableStr
);
863 List
<String
> varNameList
= new ArrayList
<String
>();
864 while (matcher
.find()){
865 String str
= variableStr
.substring(matcher
.start(),matcher
.end());
866 varNameList
.add(str
);
869 skuInstance
.value
.setHiiData(varNameList
,
870 translateSchemaStringToUUID(variableGuidString
),
871 skuInfoList
.get(index
).getVariableOffset(),
872 skuInfoList
.get(index
).getHiiDefaultValue().toString());
873 token
.skuData
.add(skuInstance
);
877 if (skuInfoList
.get(index
).getVpdOffset() != null) {
878 skuInstance
.value
.setVpdData(skuInfoList
.get(index
).getVpdOffset());
879 token
.skuData
.add(skuInstance
);
883 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s, the dynamic info must "+
884 "be one of 'DefaultGroup', 'HIIGroup', 'VpdGroup'.",
886 putError(exceptionString
);
890 exceptionString
= String
.format("In the FPD file, for dynamic PCD %s in <DynamicPcdBuildDefinitions>, there is "+
891 "no SKU ID = 0 data, which is required for every dynamic PCD",
893 putError(exceptionString
);
897 tokenArray
.add(token
);
904 Translate the schema string to UUID instance.
906 In schema, the string of UUID is defined as following two types string:
907 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
908 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
910 2) GuidNamingConvention: pattern =
911 [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}
913 This function will convert string and create uuid instance.
915 @param uuidString UUID string in XML file
917 @return UUID UUID instance
919 private UUID
translateSchemaStringToUUID(String uuidString
)
920 throws PlatformPcdPreprocessException
{
922 String
[] splitStringArray
;
927 if (uuidString
== null) {
931 if (uuidString
.length() == 0) {
935 if (uuidString
.equals("0") ||
936 uuidString
.equalsIgnoreCase("0x0")) {
937 return new UUID(0, 0);
940 uuidString
= uuidString
.replaceAll("\\{", "");
941 uuidString
= uuidString
.replaceAll("\\}", "");
944 // If the UUID schema string is GuidArrayType type then need translate
945 // to GuidNamingConvention type at first.
947 if ((uuidString
.charAt(0) == '0') && ((uuidString
.charAt(1) == 'x') || (uuidString
.charAt(1) == 'X'))) {
948 splitStringArray
= uuidString
.split("," );
949 if (splitStringArray
.length
!= 11) {
950 throw new PlatformPcdPreprocessException ("Wrong format for GUID string: " + uuidString
);
954 // Remove blank space from these string and remove header string "0x"
956 for (index
= 0; index
< 11; index
++) {
957 splitStringArray
[index
] = splitStringArray
[index
].trim();
958 splitStringArray
[index
] = splitStringArray
[index
].substring(2, splitStringArray
[index
].length());
962 // Add heading '0' to normalize the string length
964 for (index
= 3; index
< 11; index
++) {
965 chLen
= splitStringArray
[index
].length();
966 for (chIndex
= 0; chIndex
< 2 - chLen
; chIndex
++) {
967 splitStringArray
[index
] = "0" + splitStringArray
[index
];
972 // construct the final GuidNamingConvention string
974 temp
= String
.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
985 splitStringArray
[10]);
989 return UUID
.fromString(uuidString
);