2 PCDAutoGenAction class.
4 This class is to manage how to generate the PCD information into Autogen.c and
7 Copyright (c) 2006, Intel Corporation
8 All rights reserved. This program and the accompanying materials
9 are licensed and made available under the terms and conditions of the BSD License
10 which accompanies this distribution. The full text of the license may be found at
11 http://opensource.org/licenses/bsd-license.php
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 package org
.tianocore
.build
.pcd
.action
;
20 import java
.util
.ArrayList
;
21 import java
.util
.List
;
24 import java
.util
.UUID
;
25 import java
.util
.regex
.Matcher
;
26 import java
.util
.regex
.Pattern
;
28 import org
.apache
.xmlbeans
.XmlObject
;
29 import org
.tianocore
.build
.global
.GlobalData
;
30 import org
.tianocore
.build
.global
.SurfaceAreaQuery
;
31 import org
.tianocore
.build
.pcd
.entity
.MemoryDatabaseManager
;
32 import org
.tianocore
.build
.pcd
.entity
.Token
;
33 import org
.tianocore
.build
.pcd
.entity
.UsageInstance
;
34 import org
.tianocore
.build
.pcd
.exception
.BuildActionException
;
35 import org
.tianocore
.build
.pcd
.exception
.EntityException
;
37 /** This class is to manage how to generate the PCD information into Autogen.c and
40 public class PCDAutoGenAction
extends BuildAction
{
42 /// The reference of DBManager in GlobalData class.
44 private MemoryDatabaseManager dbManager
;
46 /// The name of module which is analysised currently.
48 private String moduleName
;
50 /// The Guid of module which is analyzed currently.
52 private UUID moduleGuid
;
54 /// The name of package whose module is analysized currently.
56 private String packageName
;
58 /// The Guid of package whose module is analyszed curretnly.
60 private UUID packageGuid
;
62 /// The arch of current module
66 /// The version of current module
68 private String version
;
70 /// Whether current autogen is for building library used by current module.
72 private boolean isBuildUsedLibrary
;
74 /// The generated string for header file.
76 private String hAutoGenString
;
78 /// The generated string for C code file.
80 private String cAutoGenString
;
82 /// The name array of <PcdCoded> in a module.
84 private String
[] pcdNameArray
;
86 Set parameter ModuleName
88 @param moduleName the module name parameter.
90 public void setModuleName(String moduleName
) {
91 this.moduleName
= moduleName
;
95 set the moduleGuid parameter.
99 public void setModuleGuid(UUID moduleGuid
) {
100 this.moduleGuid
= moduleGuid
;
104 set packageName parameter.
108 public void setPackageName(String packageName
) {
109 this.packageName
= packageName
;
113 set packageGuid parameter.
117 public void setPackageGuid(UUID packageGuid
) {
118 this.packageGuid
= packageGuid
;
126 public void setArch(String arch
) {
131 set version parameter
135 public void setVersion(String version
) {
136 this.version
= version
;
140 set isBuildUsedLibrary parameter.
142 @param isBuildUsedLibrary
144 public void setIsBuildUsedLibrary(boolean isBuildUsedLibrary
) {
145 this.isBuildUsedLibrary
= isBuildUsedLibrary
;
148 set pcdNameArray parameter.
152 public void setPcdNameArray(String
[] pcdNameArray
) {
153 this.pcdNameArray
= pcdNameArray
;
157 Get the output of generated string for header file.
159 @return the string of header file for PCD
161 public String
OutputH() {
162 return hAutoGenString
;
166 Get the output of generated string for C Code file.
168 @return the string of C code file for PCD
170 public String
OutputC() {
171 return cAutoGenString
;
175 // Construct function
177 // This function mainly initialize some member variable.
179 // @param moduleName Parameter of this action class.
180 // @param isEmulatedPCDDriver Parameter of this action class.
182 // public PCDAutoGenAction(String moduleName,
184 // String packageName,
188 // boolean isBuildUsedLibrary,
189 // String[] pcdNameArray) {
191 // hAutoGenString = "";
192 // cAutoGenString = "";
194 // setModuleName(moduleName);
195 // setModuleGuid(moduleGuid);
196 // setPackageName(packageName);
197 // setPackageGuid(packageGuid);
198 // setPcdNameArray(pcdNameArray);
200 // setVersion(version);
201 // setIsBuildUsedLibrary(isBuildUsedLibrary);
208 This function mainly initialize some member variable.
210 @param moduleName Parameter of this action class.
211 @param isEmulatedPCDDriver Parameter of this action class.
213 public PCDAutoGenAction(String moduleName
,
214 String moduleGuidString
,
216 String packageGuidString
,
219 boolean isBuildUsedLibrary
,
220 String
[] pcdNameArray
)
221 throws BuildActionException
{
226 setModuleName(moduleName
);
227 setModuleGuid(translateSchemaStringToUUID(moduleGuidString
));
228 setPackageName(packageName
);
229 setPackageGuid(translateSchemaStringToUUID(packageGuidString
));
230 setPcdNameArray(pcdNameArray
);
233 setIsBuildUsedLibrary(isBuildUsedLibrary
);
234 } catch (EntityException e
){
235 throw new BuildActionException(e
.getMessage());
240 Translate the schema string to UUID instance.
242 In schema, the string of UUID is defined as following two types string:
243 1) GuidArrayType: pattern = 0x[a-fA-F0-9]{1,8},( )*0x[a-fA-F0-9]{1,4},(
244 )*0x[a-fA-F0-9]{1,4}(,( )*\{)?(,?( )*0x[a-fA-F0-9]{1,2}){8}( )*(\})?
246 2) GuidNamingConvention: pattern =
247 [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}
249 This function will convert string and create uuid instance.
251 @param uuidString UUID string in XML file
253 @return UUID UUID instance
255 private UUID
translateSchemaStringToUUID(String uuidString
)
256 throws EntityException
{
258 String
[] splitStringArray
;
263 if (uuidString
== null) {
267 if (uuidString
.length() == 0) {
271 if (uuidString
.equals("0") ||
272 uuidString
.equalsIgnoreCase("0x0")) {
273 return new UUID(0, 0);
276 uuidString
= uuidString
.replaceAll("\\{", "");
277 uuidString
= uuidString
.replaceAll("\\}", "");
280 // If the UUID schema string is GuidArrayType type then need translate
281 // to GuidNamingConvention type at first.
283 if ((uuidString
.charAt(0) == '0') && ((uuidString
.charAt(1) == 'x') || (uuidString
.charAt(1) == 'X'))) {
284 splitStringArray
= uuidString
.split("," );
285 if (splitStringArray
.length
!= 11) {
286 throw new EntityException ("[FPD file error] Wrong format for UUID string: " + uuidString
);
290 // Remove blank space from these string and remove header string "0x"
292 for (index
= 0; index
< 11; index
++) {
293 splitStringArray
[index
] = splitStringArray
[index
].trim();
294 splitStringArray
[index
] = splitStringArray
[index
].substring(2, splitStringArray
[index
].length());
298 // Add heading '0' to normalize the string length
300 for (index
= 3; index
< 11; index
++) {
301 chLen
= splitStringArray
[index
].length();
302 for (chIndex
= 0; chIndex
< 2 - chLen
; chIndex
++) {
303 splitStringArray
[index
] = "0" + splitStringArray
[index
];
308 // construct the final GuidNamingConvention string
310 temp
= String
.format("%s-%s-%s-%s%s-%s%s%s%s%s%s",
321 splitStringArray
[10]);
325 return UUID
.fromString(uuidString
);
329 check the parameter for action class.
331 @throws BuildActionException Bad parameter.
333 void checkParameter() throws BuildActionException
{
338 Core execution function for this action class.
340 All PCD information of this module comes from memory dabase. The collection
341 work should be done before this action execution.
342 Currently, we should generated all PCD information(maybe all dynamic) as array
343 in Pei emulated driver for simulating PCD runtime database.
345 @throws BuildActionException Failed to execute this aciton class.
347 void performAction() throws BuildActionException
{
348 ActionMessage
.debug(this,
349 "Starting PCDAutoGenAction to generate autogen.h and autogen.c!...");
351 // Check the PCD memory database manager is valid.
353 if(GlobalData
.getPCDMemoryDBManager() == null) {
354 throw new BuildActionException("Memory database has not been initlizated!");
357 dbManager
= GlobalData
.getPCDMemoryDBManager();
359 if(dbManager
.getDBSize() == 0) {
363 ActionMessage
.debug(this,
364 "PCD memory database contains " + dbManager
.getDBSize() + " PCD tokens");
368 generateAutogenForModule();
372 Generate the autogen string for a common module.
374 All PCD information of this module comes from memory dabase. The collection
375 work should be done before this action execution.
377 private void generateAutogenForModule()
380 List
<UsageInstance
> usageInstanceArray
, usageContext
;
381 String
[] guidStringArray
= null;
382 String guidStringCName
= null;
383 String guidString
= null;
384 UsageInstance usageInstance
= null;
386 if (!isBuildUsedLibrary
) {
387 usageInstanceArray
= dbManager
.getUsageInstanceArrayByModuleName(moduleName
,
393 dbManager
.UsageInstanceContext
= usageInstanceArray
;
394 dbManager
.CurrentModuleName
= moduleName
;
396 usageContext
= dbManager
.UsageInstanceContext
;
398 // For building MDE package, although all module are library, but PCD entries of
399 // these library should be used to autogen.
401 if (usageContext
== null) {
402 usageInstanceArray
= dbManager
.getUsageInstanceArrayByModuleName(moduleName
,
409 usageInstanceArray
= new ArrayList
<UsageInstance
>();
411 // Remove PCD entries which are not belong to this library.
413 for (index
= 0; index
< usageContext
.size(); index
++) {
414 if ((pcdNameArray
== null) || (pcdNameArray
.length
== 0)){
418 for (index2
= 0; index2
< pcdNameArray
.length
; index2
++) {
419 if (pcdNameArray
[index2
].equalsIgnoreCase(usageContext
.get(index
).parentToken
.cName
)) {
420 usageInstanceArray
.add(usageContext
.get(index
));
428 if(usageInstanceArray
.size() != 0) {
430 // Add "#include 'PcdLib.h'" for Header file
432 hAutoGenString
= "#include <MdePkg/Include/Library/PcdLib.h>\r\n";
436 // Generate all PCD entry for a module.
438 for(index
= 0; index
< usageInstanceArray
.size(); index
++) {
439 ActionMessage
.debug(this,
440 "Module " + moduleName
+ "'s PCD [" + Integer
.toHexString(index
) +
441 "]: " + usageInstanceArray
.get(index
).parentToken
.cName
);
443 usageInstance
= usageInstanceArray
.get(index
);
445 // Before generate any PCD information into autogen.h/autogen.c for a module,
446 // generate TokenSpaceGuid array variable firstly. For every dynamicEx type
447 // PCD in this module the token, they are all reference to TokenSpaceGuid
450 if (usageInstanceArray
.get(index
).modulePcdType
== Token
.PCD_TYPE
.DYNAMIC_EX
) {
451 guidStringArray
= usageInstance
.parentToken
.tokenSpaceName
.toString().split("-");
452 guidStringCName
= "_gPcd_TokenSpaceGuid_" +
453 usageInstance
.parentToken
.tokenSpaceName
.toString().replaceAll("-", "_");
454 guidString
= String
.format("{ 0x%s, 0x%s, 0x%s, {0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s, 0x%s}}",
458 (guidStringArray
[3].substring(0, 2)),
459 (guidStringArray
[3].substring(2, 4)),
460 (guidStringArray
[4].substring(0, 2)),
461 (guidStringArray
[4].substring(2, 4)),
462 (guidStringArray
[4].substring(4, 6)),
463 (guidStringArray
[4].substring(6, 8)),
464 (guidStringArray
[4].substring(8, 10)),
465 (guidStringArray
[4].substring(10, 12)));
467 Pattern pattern
= Pattern
.compile("(" + guidStringCName
+ ")+?");
468 Matcher matcher
= pattern
.matcher(cAutoGenString
+ " ");
470 // Find whether this guid array variable has been generated into autogen.c
471 // For different DyanmicEx pcd token who use same token space guid, the token space
472 // guid array should be only generated once.
474 if (!matcher
.find()) {
475 hAutoGenString
+= String
.format("extern EFI_GUID %s;\r\n",
477 if (!isBuildUsedLibrary
) {
478 cAutoGenString
+= String
.format("GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID %s = %s;\r\n",
485 usageInstance
.generateAutoGen(isBuildUsedLibrary
);
487 // For every PCD entry for this module(usage instance), autogen string would
490 hAutoGenString
+= usageInstance
.getHAutogenStr() + "\r\n";
491 cAutoGenString
+= usageInstance
.getCAutogenStr();
493 } catch(EntityException exp
) {
494 throw new BuildActionException("[PCD Autogen Error]: " + exp
.getMessage());
499 // Work around code, In furture following code should be modified that get
500 // these information from Uplevel Autogen tools.
502 if (moduleName
.equalsIgnoreCase("PcdPeim")) {
503 hAutoGenString
+= dbManager
.PcdPeimHString
;
504 cAutoGenString
+= dbManager
.PcdPeimCString
;
505 } else if (moduleName
.equalsIgnoreCase("PcdDxe")) {
506 hAutoGenString
+= dbManager
.PcdDxeHString
;
507 cAutoGenString
+= dbManager
.PcdDxeCString
;
510 ActionMessage
.debug(this,
511 "Module " + moduleName
+ "'s PCD header file:\r\n" + hAutoGenString
+ "\r\n"
513 ActionMessage
.debug(this,
514 "Module " + moduleName
+ "'s PCD C file:\r\n" + cAutoGenString
+ "\r\n"
521 @param argv paramter from command line
523 public static void main(String argv
[]) {
525 String WorkSpace
= "X:/edk2";
526 String logFilePath
= WorkSpace
+ "/EdkNt32Pkg/Nt32.fpd";
527 String
[] nameArray
= null;
530 // At first, CollectPCDAction should be invoked to collect
531 // all PCD information from SPD, MSA, FPD.
533 CollectPCDAction collectionAction
= new CollectPCDAction();
534 GlobalData
.initInfo("Tools" + File
.separator
+ "Conf" + File
.separator
+ "FrameworkDatabase.db",
538 collectionAction
.perform(WorkSpace
,
540 ActionMessage
.MAX_MESSAGE_LEVEL
);
541 } catch(Exception e
) {
546 // Then execute the PCDAuotoGenAction to get generated Autogen.h and Autogen.c
548 // PCDAutoGenAction autogenAction = new PCDAutoGenAction("MonoStatusCode",
556 // autogenAction.execute();
558 // System.out.println(autogenAction.OutputH());
559 // System.out.println("WQWQWQWQWQ");
560 // System.out.println(autogenAction.OutputC());