summaryrefslogtreecommitdiff
path: root/BaseTools/Source
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-26 07:46:26 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-26 07:46:26 +0000
commit4234283c3acb8c35014acc1546621fbc2621b095 (patch)
tree208a4f87b2820ec1f3a414508ca1c215c5deed18 /BaseTools/Source
parentba944801a988dddf3ed217c72c8d880d0f03d150 (diff)
downloadedk2-platforms-4234283c3acb8c35014acc1546621fbc2621b095.tar.xz
Sync BaseTools Branch (version r2271) to EDKII main trunk.
BaseTool Branch: https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/branches/Releases/BaseTools_r2100 Signed-off-by: lgao4 Reviewed-by: hchen30 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12214 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'BaseTools/Source')
-rw-r--r--BaseTools/Source/C/Common/ParseInf.h9
-rw-r--r--BaseTools/Source/C/GenPage/GenPage.c29
-rw-r--r--BaseTools/Source/C/Include/Common/MdeModuleHii.h161
-rw-r--r--BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h27
-rw-r--r--BaseTools/Source/C/Include/Protocol/DevicePath.h548
-rw-r--r--BaseTools/Source/C/VfrCompile/EfiVfr.h4
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrCompiler.cpp40
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrCompiler.h7
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp4
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrFormPkg.h94
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrSyntax.g275
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp538
-rw-r--r--BaseTools/Source/C/VfrCompile/VfrUtilityLib.h32
-rw-r--r--BaseTools/Source/Python/AutoGen/AutoGen.py68
-rw-r--r--BaseTools/Source/Python/AutoGen/GenC.py3
-rw-r--r--BaseTools/Source/Python/AutoGen/GenMake.py3
-rw-r--r--BaseTools/Source/Python/Common/BuildToolError.py2
-rw-r--r--BaseTools/Source/Python/Common/Misc.py14
-rw-r--r--BaseTools/Source/Python/GenFds/FdfParser.py30
-rw-r--r--BaseTools/Source/Python/GenFds/FfsInfStatement.py16
-rw-r--r--BaseTools/Source/Python/GenFds/Fv.py6
-rw-r--r--BaseTools/Source/Python/GenFds/GenFds.py22
-rw-r--r--BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py215
-rw-r--r--BaseTools/Source/Python/GenFds/Region.py2
-rw-r--r--BaseTools/Source/Python/GenFds/Section.py12
-rw-r--r--BaseTools/Source/Python/Makefile10
-rw-r--r--BaseTools/Source/Python/PackagingTool/DependencyRules.py185
-rw-r--r--BaseTools/Source/Python/PackagingTool/InstallPkg.py309
-rw-r--r--BaseTools/Source/Python/PackagingTool/IpiDb.py629
-rw-r--r--BaseTools/Source/Python/PackagingTool/MkPkg.py294
-rw-r--r--BaseTools/Source/Python/PackagingTool/PackageFile.py160
-rw-r--r--BaseTools/Source/Python/PackagingTool/RmPkg.py218
-rw-r--r--BaseTools/Source/Python/UPT/Core/DependencyRules.py293
-rw-r--r--BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py228
-rw-r--r--BaseTools/Source/Python/UPT/Core/IpiDb.py867
-rw-r--r--BaseTools/Source/Python/UPT/Core/PackageFile.py249
-rw-r--r--BaseTools/Source/Python/UPT/Core/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Dll/sqlite3.dllbin0 -> 260096 bytes
-rw-r--r--BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py367
-rw-r--r--BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py988
-rw-r--r--BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py155
-rw-r--r--BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py18
-rw-r--r--BaseTools/Source/Python/UPT/GenMetaFile/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/InstallPkg.py770
-rw-r--r--BaseTools/Source/Python/UPT/Library/CommentGenerating.py217
-rw-r--r--BaseTools/Source/Python/UPT/Library/CommentParsing.py451
-rw-r--r--BaseTools/Source/Python/UPT/Library/DataType.py919
-rw-r--r--BaseTools/Source/Python/UPT/Library/ExpressionValidate.py489
-rw-r--r--BaseTools/Source/Python/UPT/Library/GlobalData.py94
-rw-r--r--BaseTools/Source/Python/UPT/Library/Misc.py921
-rw-r--r--BaseTools/Source/Python/UPT/Library/ParserValidate.py717
-rw-r--r--BaseTools/Source/Python/UPT/Library/Parsing.py993
-rw-r--r--BaseTools/Source/Python/UPT/Library/String.py968
-rw-r--r--BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py228
-rw-r--r--BaseTools/Source/Python/UPT/Library/Xml/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Library/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Logger/Log.py325
-rw-r--r--BaseTools/Source/Python/UPT/Logger/StringTable.py768
-rw-r--r--BaseTools/Source/Python/UPT/Logger/ToolError.py176
-rw-r--r--BaseTools/Source/Python/UPT/Logger/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Makefile41
-rw-r--r--BaseTools/Source/Python/UPT/MkPkg.py281
-rw-r--r--BaseTools/Source/Python/UPT/Object/POM/CommonObject.py789
-rw-r--r--BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py645
-rw-r--r--BaseTools/Source/Python/UPT/Object/POM/PackageObject.py190
-rw-r--r--BaseTools/Source/Python/UPT/Object/POM/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/DecObject.py611
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py621
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py93
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfCommonObject.py162
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py89
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py994
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py166
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py350
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfHeaderObject.py119
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py252
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py148
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py187
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py640
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py343
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py311
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py240
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py133
-rw-r--r--BaseTools/Source/Python/UPT/Object/Parser/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Object/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/Parser/DecParser.py989
-rw-r--r--BaseTools/Source/Python/UPT/Parser/DecParserMisc.py371
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py219
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py217
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py218
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py197
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py104
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py382
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py209
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py140
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfParser.py612
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfParserMisc.py218
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py184
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfSectionParser.py490
-rw-r--r--BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py145
-rw-r--r--BaseTools/Source/Python/UPT/Parser/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py607
-rw-r--r--BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py972
-rw-r--r--BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py221
-rw-r--r--BaseTools/Source/Python/UPT/PomAdapter/__init__.py20
-rw-r--r--BaseTools/Source/Python/UPT/RmPkg.py246
-rw-r--r--BaseTools/Source/Python/UPT/UPT.py238
-rw-r--r--BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py1419
-rw-r--r--BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py923
-rw-r--r--BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py284
-rw-r--r--BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py534
-rw-r--r--BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py386
-rw-r--r--BaseTools/Source/Python/UPT/Xml/CommonXml.py879
-rw-r--r--BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py284
-rw-r--r--BaseTools/Source/Python/UPT/Xml/IniToXml.py503
-rw-r--r--BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py997
-rw-r--r--BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py397
-rw-r--r--BaseTools/Source/Python/UPT/Xml/PcdXml.py403
-rw-r--r--BaseTools/Source/Python/UPT/Xml/XmlParser.py924
-rw-r--r--BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py89
-rw-r--r--BaseTools/Source/Python/UPT/Xml/__init__.py20
-rw-r--r--BaseTools/Source/Python/Workspace/WorkspaceDatabase.py9
-rw-r--r--BaseTools/Source/Python/build/build.py27
123 files changed, 35321 insertions, 2508 deletions
diff --git a/BaseTools/Source/C/Common/ParseInf.h b/BaseTools/Source/C/Common/ParseInf.h
index 88ded8760e..dfd180db74 100644
--- a/BaseTools/Source/C/Common/ParseInf.h
+++ b/BaseTools/Source/C/Common/ParseInf.h
@@ -31,7 +31,9 @@ Abstract:
#define _MAX_PATH 500
#endif
-
+#ifdef __cplusplus
+extern "C" {
+#endif
//
// Functions declarations
//
@@ -227,4 +229,9 @@ Returns:
TRUE if section found
--*/
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/BaseTools/Source/C/GenPage/GenPage.c b/BaseTools/Source/C/GenPage/GenPage.c
index c72011045c..e92bcf5d9e 100644
--- a/BaseTools/Source/C/GenPage/GenPage.c
+++ b/BaseTools/Source/C/GenPage/GenPage.c
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -63,7 +63,7 @@ UINT32 gPageTableOffsetInFile = EFI_PAGE_BASE_OFFSET_IN_LDR;
//
// Utility Name
//
-#define UTILITY_NAME "GenBootSector"
+#define UTILITY_NAME "GenPage"
//
// Utility version information
@@ -92,7 +92,7 @@ Returns:
--*/
{
printf ("%s v%d.%d -Utility to generate the EfiLoader image containing page table.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);
- printf ("Copyright (c) 2008 - 2010 Intel Corporation. All rights reserved.\n");
+ printf ("Copyright (c) 2008 - 2011 Intel Corporation. All rights reserved.\n");
}
VOID
@@ -103,14 +103,21 @@ Usage (
Version();
printf ("\nUsage: \n\
GenPage\n\
- -o, --output Filename containing page table\n\
- [-b, --baseaddr baseaddress of page table]\n\
- [-f, --offset offset in the file that page table will reside]\n\
- [-v, --verbose]\n\
- [--version]\n\
- [-q, --quiet disable all messages except fatal errors]\n\
- [-d, --debug[#]\n\
- [-h, --help]\n\
+ -o, --output Filename\n\
+ The file that contains both non-page table part and\n\
+ page table\n\
+ [-b, --baseaddr baseaddress]\n\
+ The page table location\n\
+ [-f, --offset offset]\n\
+ The position that the page table will appear in the\n\
+ output file\n\
+ [-v, --verbose] Turn on verbose output with informational messages\n\
+ printed\n\
+ [--version] Print version and copyright of this program and exit\n\
+ [-q, --quiet] Disable all messages except unrecoverable errors\n\
+ [-d, --debug[#]] Enable debug messages, at level #\n\
+ [-h, --help] Print copyright, version and usage of this program\n\
+ and exit\n\
EfiLoaderImageName\n");
}
diff --git a/BaseTools/Source/C/Include/Common/MdeModuleHii.h b/BaseTools/Source/C/Include/Common/MdeModuleHii.h
index 8b42061d71..b756fef2c3 100644
--- a/BaseTools/Source/C/Include/Common/MdeModuleHii.h
+++ b/BaseTools/Source/C/Include/Common/MdeModuleHii.h
@@ -1,7 +1,7 @@
/** @file
EDK II specific HII relative definition.
- Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
@@ -22,51 +22,45 @@
#define WIDE_CHAR 0xFFF1
#define NON_BREAKING_CHAR 0xFFF2
-#define GLYPH_WIDTH EFI_GLYPH_WIDTH
-#define GLYPH_HEIGHT EFI_GLYPH_HEIGHT
-
-//
-// State defined for password statemachine
-//
+///
+/// State defined for password statemachine .
+///
#define BROWSER_STATE_VALIDATE_PASSWORD 0
#define BROWSER_STATE_SET_PASSWORD 1
-
-//
-// Tiano Implementation specific Device Path definition.
-//
-#pragma pack(1)
-typedef struct {
- VENDOR_DEVICE_PATH VendorDevicePath;
- UINT32 Reserved;
- UINT64 UniqueId;
-} HII_VENDOR_DEVICE_PATH_NODE;
-#pragma pack()
-
-typedef struct {
- HII_VENDOR_DEVICE_PATH_NODE Node;
- EFI_DEVICE_PATH_PROTOCOL End;
-} HII_VENDOR_DEVICE_PATH;
-
-
-//
-// GUIDed opcodes defined for Tiano
-//
+///
+/// GUIDed opcodes defined for EDKII implementation.
+///
#define EFI_IFR_TIANO_GUID \
{ 0xf0b1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, 0xaf, 0x48, 0xce} }
#pragma pack(1)
+///
+/// EDKII implementation extension opcodes, new extension can be added here later.
+///
#define EFI_IFR_EXTEND_OP_LABEL 0x0
#define EFI_IFR_EXTEND_OP_BANNER 0x1
#define EFI_IFR_EXTEND_OP_TIMEOUT 0x2
#define EFI_IFR_EXTEND_OP_CLASS 0x3
#define EFI_IFR_EXTEND_OP_SUBCLASS 0x4
+///
+/// Label opcode.
+///
typedef struct _EFI_IFR_GUID_LABEL {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_LABEL.
+ ///
UINT8 ExtendOpCode;
+ ///
+ /// Label Number.
+ ///
UINT16 Number;
} EFI_IFR_GUID_LABEL;
@@ -74,20 +68,38 @@ typedef struct _EFI_IFR_GUID_LABEL {
#define EFI_IFR_BANNER_ALIGN_CENTER 1
#define EFI_IFR_BANNER_ALIGN_RIGHT 2
+///
+/// Banner opcode.
+///
typedef struct _EFI_IFR_GUID_BANNER {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
EFI_GUID Guid;
- UINT8 ExtendOpCode; // Extended opcode is EFI_IFR_EXTEND_OP_BANNER
- EFI_STRING_ID Title; // The string token for the banner title
- UINT16 LineNumber; // 1-based line number
- UINT8 Alignment; // left, center, or right-aligned
+ ///
+ /// EFI_IFR_EXTEND_OP_BANNER
+ ///
+ UINT8 ExtendOpCode;
+ EFI_STRING_ID Title; ///< The string token for the banner title.
+ UINT16 LineNumber; ///< 1-based line number.
+ UINT8 Alignment; ///< left, center, or right-aligned.
} EFI_IFR_GUID_BANNER;
+///
+/// Timeout opcode.
+///
typedef struct _EFI_IFR_GUID_TIMEOUT {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_TIMEOUT.
+ ///
UINT8 ExtendOpCode;
- UINT16 TimeOut;
+ UINT16 TimeOut; ///< TimeOut Value.
} EFI_IFR_GUID_TIMEOUT;
#define EFI_NON_DEVICE_CLASS 0x00
@@ -98,11 +110,20 @@ typedef struct _EFI_IFR_GUID_TIMEOUT {
#define EFI_ON_BOARD_DEVICE_CLASS 0x10
#define EFI_OTHER_DEVICE_CLASS 0x20
+///
+/// Device Class opcode.
+///
typedef struct _EFI_IFR_GUID_CLASS {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_CLASS.
+ ///
UINT8 ExtendOpCode;
- UINT16 Class;
+ UINT16 Class; ///< Device Class from the above.
} EFI_IFR_GUID_CLASS;
#define EFI_SETUP_APPLICATION_SUBCLASS 0x00
@@ -110,45 +131,93 @@ typedef struct _EFI_IFR_GUID_CLASS {
#define EFI_FRONT_PAGE_SUBCLASS 0x02
#define EFI_SINGLE_USE_SUBCLASS 0x03
+///
+/// SubClass opcode
+///
typedef struct _EFI_IFR_GUID_SUBCLASS {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_TIANO_GUID.
+ ///
EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_SUBCLASS.
+ ///
UINT8 ExtendOpCode;
- UINT16 SubClass;
+ UINT16 SubClass; ///< Sub Class type from the above.
} EFI_IFR_GUID_SUBCLASS;
-//
-// GUIDed opcodes defined for Tiano
-//
+///
+/// GUIDed opcodes support for framework vfr.
+///
#define EFI_IFR_FRAMEWORK_GUID \
{ 0x31ca5d1a, 0xd511, 0x4931, { 0xb7, 0x82, 0xae, 0x6b, 0x2b, 0x17, 0x8c, 0xd7 } }
+///
+/// Two extended opcodes are added, and new extensions can be added here later.
+/// One is for framework OneOf question Option Key value;
+/// another is for framework vareqval.
+///
#define EFI_IFR_EXTEND_OP_OPTIONKEY 0x0
#define EFI_IFR_EXTEND_OP_VAREQNAME 0x1
-//
-// Store the framework vfr option key value
-//
+
+///
+/// Store the framework vfr option key value.
+///
typedef struct _EFI_IFR_GUID_OPTIONKEY {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_FRAMEWORK_GUID.
+ ///
EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_OPTIONKEY.
+ ///
UINT8 ExtendOpCode;
+ ///
+ /// OneOf Questiond ID binded by OneOf Option.
+ ///
EFI_QUESTION_ID QuestionId;
+ ///
+ /// The OneOf Option Value.
+ ///
EFI_IFR_TYPE_VALUE OptionValue;
- EFI_QUESTION_ID KeyValue;
+ ///
+ /// The Framework OneOf Option Key Value.
+ ///
+ UINT16 KeyValue;
} EFI_IFR_GUID_OPTIONKEY;
-//
-// Store the framework vfr vareqval name number
-//
+///
+/// Store the framework vfr vareqval name number.
+///
typedef struct _EFI_IFR_GUID_VAREQNAME {
EFI_IFR_OP_HEADER Header;
+ ///
+ /// EFI_IFR_FRAMEWORK_GUID.
+ ///
EFI_GUID Guid;
+ ///
+ /// EFI_IFR_EXTEND_OP_VAREQNAME.
+ ///
UINT8 ExtendOpCode;
+ ///
+ /// Question ID of the Numeric Opcode created.
+ ///
EFI_QUESTION_ID QuestionId;
- EFI_STRING_ID NameId;
+ ///
+ /// For vareqval (0x100), NameId is 0x100.
+ /// This value will convert to a Unicode String following this rule;
+ /// sprintf(StringBuffer, "%d", NameId) .
+ /// The the Unicode String will be used as a EFI Variable Name.
+ ///
+ UINT16 NameId;
} EFI_IFR_GUID_VAREQNAME;
#pragma pack()
+extern EFI_GUID gEfiIfrTianoGuid;
+extern EFI_GUID gEfiIfrFrameworkGuid;
+
#endif
diff --git a/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h b/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h
index 61fc191618..1cabc959d8 100644
--- a/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h
+++ b/BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h
@@ -575,6 +575,13 @@ typedef struct {
UINT8 Day;
} EFI_HII_DATE;
+typedef struct {
+ EFI_QUESTION_ID QuestionId;
+ EFI_FORM_ID FormId;
+ EFI_GUID FormSetGuid;
+ EFI_STRING_ID DevicePath;
+} EFI_HII_REF;
+
typedef union {
UINT8 u8;
UINT16 u16;
@@ -584,6 +591,7 @@ typedef union {
EFI_HII_TIME time;
EFI_HII_DATE date;
EFI_STRING_ID string;
+ EFI_HII_REF ref;
} EFI_IFR_TYPE_VALUE;
#define EFI_IFR_FORM_OP 0x01
@@ -681,6 +689,8 @@ typedef union {
#define EFI_IFR_CATENATE_OP 0x5E
#define EFI_IFR_GUID_OP 0x5F
#define EFI_IFR_SECURITY_OP 0x60
+#define EFI_IFR_MODAL_TAG_OP 0x61
+#define EFI_IFR_REFRESH_ID_OP 0x62
typedef struct _EFI_IFR_OP_HEADER {
@@ -739,6 +749,8 @@ typedef struct _EFI_IFR_VARSTORE_EFI {
EFI_VARSTORE_ID VarStoreId;
EFI_GUID Guid;
UINT32 Attributes;
+ UINT16 Size;
+ UINT8 Name[1];
} EFI_IFR_VARSTORE_EFI;
typedef struct _EFI_IFR_VARSTORE_NAME_VALUE {
@@ -771,6 +783,10 @@ typedef struct _EFI_IFR_IMAGE {
EFI_IMAGE_ID Id;
} EFI_IFR_IMAGE;
+typedef struct _EFI_IFR_MODAL {
+ EFI_IFR_OP_HEADER Header;
+} EFI_IFR_MODAL;
+
typedef struct _EFI_IFR_LOCKED {
EFI_IFR_OP_HEADER Header;
} EFI_IFR_LOCKED;
@@ -844,6 +860,11 @@ typedef struct _EFI_IFR_REF4 {
EFI_STRING_ID DevicePath;
} EFI_IFR_REF4;
+typedef struct _EFI_IFR_REF5 {
+ EFI_IFR_OP_HEADER Header;
+ EFI_IFR_QUESTION_HEADER Question;
+} EFI_IFR_REF5;
+
typedef struct _EFI_IFR_RESET_BUTTON {
EFI_IFR_OP_HEADER Header;
EFI_IFR_STATEMENT_HEADER Statement;
@@ -993,6 +1014,11 @@ typedef struct _EFI_IFR_REFRESH {
UINT8 RefreshInterval;
} EFI_IFR_REFRESH;
+typedef struct _EFI_IFR_REFRESH_ID {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID RefreshEventGroupId;
+} EFI_IFR_REFRESH_ID;
+
typedef struct _EFI_IFR_VARSTORE_DEVICE {
EFI_IFR_OP_HEADER Header;
EFI_STRING_ID DevicePath;
@@ -1018,6 +1044,7 @@ typedef struct _EFI_IFR_ONE_OF_OPTION {
#define EFI_IFR_TYPE_UNDEFINED 0x09
#define EFI_IFR_TYPE_ACTION 0x0A
#define EFI_IFR_TYPE_BUFFER 0x0B
+#define EFI_IFR_TYPE_REF 0x0C
#define EFI_IFR_OPTION_DEFAULT 0x10
#define EFI_IFR_OPTION_DEFAULT_MFG 0x20
diff --git a/BaseTools/Source/C/Include/Protocol/DevicePath.h b/BaseTools/Source/C/Include/Protocol/DevicePath.h
deleted file mode 100644
index 9fc8cb1aff..0000000000
--- a/BaseTools/Source/C/Include/Protocol/DevicePath.h
+++ /dev/null
@@ -1,548 +0,0 @@
-/** @file
- The device path protocol as defined in UEFI 2.0.
-
- The device path represents a programatic path to a device. It's the view
- from a software point of view. It also must persist from boot to boot, so
- it can not contain things like PCI bus numbers that change from boot to boot.
-
- Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-
- This program and the accompanying materials are licensed and made available
- under the terms and conditions of the BSD License which accompanies this
- distribution. The full text of the license may be found at:
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
- File Name: DevicePath.h
-
-**/
-
-#ifndef __EFI_DEVICE_PATH_PROTOCOL_H__
-#define __EFI_DEVICE_PATH_PROTOCOL_H__
-
-#include <Guid/PcAnsi.h>
-
-//
-// Device Path protocol
-//
-#define EFI_DEVICE_PATH_PROTOCOL_GUID \
- { \
- 0x9576e91, 0x6d3f, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
- }
-
-//
-// Protocol GUID defined in EFI1.1.
-//
-
-//
-// Device Path information
-//
-#define DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH_PROTOCOL_GUID
-
-#pragma pack(1)
-
-typedef struct {
- UINT8 Type;
- UINT8 SubType;
- UINT8 Length[2];
-} EFI_DEVICE_PATH_PROTOCOL;
-
-//
-// For backward-compatible with EFI1.1.
-//
-typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
-
-//
-// Hardware Device Paths
-//
-#define HARDWARE_DEVICE_PATH 0x01
-
-#define HW_PCI_DP 0x01
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT8 Function;
- UINT8 Device;
-} PCI_DEVICE_PATH;
-
-#define HW_PCCARD_DP 0x02
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT8 FunctionNumber;
-} PCCARD_DEVICE_PATH;
-
-#define HW_MEMMAP_DP 0x03
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 MemoryType;
- EFI_PHYSICAL_ADDRESS StartingAddress;
- EFI_PHYSICAL_ADDRESS EndingAddress;
-} MEMMAP_DEVICE_PATH;
-
-#define HW_VENDOR_DP 0x04
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_GUID Guid;
-} VENDOR_DEVICE_PATH;
-
-#define HW_CONTROLLER_DP 0x05
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 ControllerNumber;
-} CONTROLLER_DEVICE_PATH;
-
-//
-// ACPI Device Paths
-//
-#define ACPI_DEVICE_PATH 0x02
-
-#define ACPI_DP 0x01
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 HID;
- UINT32 UID;
-} ACPI_HID_DEVICE_PATH;
-
-#define ACPI_EXTENDED_DP 0x02
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 HID;
- UINT32 UID;
- UINT32 CID;
- //
- // Optional variable length _HIDSTR
- // Optional variable length _UIDSTR
- //
-} ACPI_EXTENDED_HID_DEVICE_PATH;
-
-//
-// EISA ID Macro
-// EISA ID Definition 32-bits
-// bits[15:0] - three character compressed ASCII EISA ID.
-// bits[31:16] - binary number
-// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z'
-//
-#define PNP_EISA_ID_CONST 0x41d0
-#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16))
-#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
-#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId)))
-
-#define PNP_EISA_ID_MASK 0xffff
-#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16)
-
-
-#define ACPI_ADR_DP 0x03
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 ADR;
-} ACPI_ADR_DEVICE_PATH;
-
-
-//
-// Messaging Device Paths
-//
-#define MESSAGING_DEVICE_PATH 0x03
-
-#define MSG_ATAPI_DP 0x01
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT8 PrimarySecondary;
- UINT8 SlaveMaster;
- UINT16 Lun;
-} ATAPI_DEVICE_PATH;
-
-#define MSG_SCSI_DP 0x02
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT16 Pun;
- UINT16 Lun;
-} SCSI_DEVICE_PATH;
-
-#define MSG_FIBRECHANNEL_DP 0x03
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 Reserved;
- UINT64 WWN;
- UINT64 Lun;
-} FIBRECHANNEL_DEVICE_PATH;
-
-#define MSG_1394_DP 0x04
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 Reserved;
- UINT64 Guid;
-} F1394_DEVICE_PATH;
-
-#define MSG_USB_DP 0x05
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT8 ParentPortNumber;
- UINT8 InterfaceNumber;
-} USB_DEVICE_PATH;
-
-#define MSG_USB_CLASS_DP 0x0f
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT16 VendorId;
- UINT16 ProductId;
- UINT8 DeviceClass;
- UINT8 DeviceSubClass;
- UINT8 DeviceProtocol;
-} USB_CLASS_DEVICE_PATH;
-
-#define MSG_USB_WWID_DP 0x10
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT16 InterfaceNumber;
- UINT16 VendorId;
- UINT16 ProductId;
- // CHAR16 SerialNumber[...];
-} USB_WWID_DEVICE_PATH;
-
-
-#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT8 Lun;
-} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
-
-#define MSG_SATA_DP 0x12
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT16 HBAPortNumber;
- UINT16 PortMultiplierPortNumber;
- UINT16 Lun;
-} SATA_DEVICE_PATH;
-
-#define MSG_I2O_DP 0x06
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 Tid;
-} I2O_DEVICE_PATH;
-
-#define MSG_MAC_ADDR_DP 0x0b
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_MAC_ADDRESS MacAddress;
- UINT8 IfType;
-} MAC_ADDR_DEVICE_PATH;
-
-#define MSG_IPv4_DP 0x0c
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_IPv4_ADDRESS LocalIpAddress;
- EFI_IPv4_ADDRESS RemoteIpAddress;
- UINT16 LocalPort;
- UINT16 RemotePort;
- UINT16 Protocol;
- BOOLEAN StaticIpAddress;
-} IPv4_DEVICE_PATH;
-
-#define MSG_IPv6_DP 0x0d
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_IPv6_ADDRESS LocalIpAddress;
- EFI_IPv6_ADDRESS RemoteIpAddress;
- UINT16 LocalPort;
- UINT16 RemotePort;
- UINT16 Protocol;
- BOOLEAN StaticIpAddress;
-} IPv6_DEVICE_PATH;
-
-#define MSG_INFINIBAND_DP 0x09
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 ResourceFlags;
- UINT8 PortGid[16];
- UINT64 ServiceId;
- UINT64 TargetPortId;
- UINT64 DeviceId;
-} INFINIBAND_DEVICE_PATH;
-
-#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01
-#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02
-#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04
-#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08
-#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10
-
-#define MSG_UART_DP 0x0e
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 Reserved;
- UINT64 BaudRate;
- UINT8 DataBits;
- UINT8 Parity;
- UINT8 StopBits;
-} UART_DEVICE_PATH;
-
-//
-// Use VENDOR_DEVICE_PATH struct
-//
-#define MSG_VENDOR_DP 0x0a
-typedef VENDOR_DEVICE_PATH VENDOR_DEFINED_DEVICE_PATH;
-
-#define DEVICE_PATH_MESSAGING_PC_ANSI EFI_PC_ANSI_GUID
-#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID
-#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID
-#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID
-
-#define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL EFI_UART_DEVICE_PATH_GUID
-
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_GUID Guid;
- UINT32 FlowControlMap;
-} UART_FLOW_CONTROL_DEVICE_PATH;
-
-#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID
-
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_GUID Guid;
- UINT32 Reserved;
- UINT64 SasAddress;
- UINT64 Lun;
- UINT16 DeviceTopology;
- UINT16 RelativeTargetPort;
-} SAS_DEVICE_PATH;
-
-#define MSG_ISCSI_DP 0x13
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT16 NetworkProtocol;
- UINT16 LoginOption;
- UINT64 Lun;
- UINT16 TargetPortalGroupTag;
- // CHAR8 iSCSI Target Name
-} ISCSI_DEVICE_PATH;
-
-#define ISCSI_LOGIN_OPTION_NO_HEADER_DIGEST 0x0000
-#define ISCSI_LOGIN_OPTION_HEADER_DIGEST_USING_CRC32C 0x0002
-#define ISCSI_LOGIN_OPTION_NO_DATA_DIGEST 0x0000
-#define ISCSI_LOGIN_OPTION_DATA_DIGEST_USING_CRC32C 0x0008
-#define ISCSI_LOGIN_OPTION_AUTHMETHOD_CHAP 0x0000
-#define ISCSI_LOGIN_OPTION_AUTHMETHOD_NON 0x1000
-#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000
-#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000
-
-//
-// Media Device Path
-//
-#define MEDIA_DEVICE_PATH 0x04
-
-#define MEDIA_HARDDRIVE_DP 0x01
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 PartitionNumber;
- UINT64 PartitionStart;
- UINT64 PartitionSize;
- UINT8 Signature[16];
- UINT8 MBRType;
- UINT8 SignatureType;
-} HARDDRIVE_DEVICE_PATH;
-
-#define MBR_TYPE_PCAT 0x01
-#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
-
-#define SIGNATURE_TYPE_MBR 0x01
-#define SIGNATURE_TYPE_GUID 0x02
-
-#define MEDIA_CDROM_DP 0x02
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT32 BootEntry;
- UINT64 PartitionStart;
- UINT64 PartitionSize;
-} CDROM_DEVICE_PATH;
-
-//
-// Use VENDOR_DEVICE_PATH struct
-//
-#define MEDIA_VENDOR_DP 0x03
-
-#define MEDIA_FILEPATH_DP 0x04
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- CHAR16 PathName[1];
-} FILEPATH_DEVICE_PATH;
-
-#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName)
-
-#define MEDIA_PROTOCOL_DP 0x05
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_GUID Protocol;
-} MEDIA_PROTOCOL_DEVICE_PATH;
-
-
-#define MEDIA_PIWG_FW_VOL_DP 0x7
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_GUID FvName;
-} MEDIA_FW_VOL_DEVICE_PATH;
-
-
-#define MEDIA_PIWG_FW_FILE_DP 0x6
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- EFI_GUID FvFileName;
-} MEDIA_FW_VOL_FILEPATH_DEVICE_PATH;
-
-//
-// BBS Device Path
-//
-#define BBS_DEVICE_PATH 0x05
-#define BBS_BBS_DP 0x01
-typedef struct {
- EFI_DEVICE_PATH_PROTOCOL Header;
- UINT16 DeviceType;
- UINT16 StatusFlag;
- CHAR8 String[1];
-} BBS_BBS_DEVICE_PATH;
-
-//
-// DeviceType definitions - from BBS specification
-//
-#define BBS_TYPE_FLOPPY 0x01
-#define BBS_TYPE_HARDDRIVE 0x02
-#define BBS_TYPE_CDROM 0x03
-#define BBS_TYPE_PCMCIA 0x04
-#define BBS_TYPE_USB 0x05
-#define BBS_TYPE_EMBEDDED_NETWORK 0x06
-#define BBS_TYPE_BEV 0x80
-#define BBS_TYPE_UNKNOWN 0xFF
-
-
-//
-// Union of all possible Device Paths and pointers to Device Paths
-//
-
-typedef union {
- EFI_DEVICE_PATH_PROTOCOL DevPath;
- PCI_DEVICE_PATH Pci;
- PCCARD_DEVICE_PATH PcCard;
- MEMMAP_DEVICE_PATH MemMap;
- VENDOR_DEVICE_PATH Vendor;
-
- CONTROLLER_DEVICE_PATH Controller;
- ACPI_HID_DEVICE_PATH Acpi;
-
- ATAPI_DEVICE_PATH Atapi;
- SCSI_DEVICE_PATH Scsi;
- ISCSI_DEVICE_PATH Iscsi;
- FIBRECHANNEL_DEVICE_PATH FibreChannel;
-
- F1394_DEVICE_PATH F1394;
- USB_DEVICE_PATH Usb;
- SATA_DEVICE_PATH Sata;
- USB_CLASS_DEVICE_PATH UsbClass;
- I2O_DEVICE_PATH I2O;
- MAC_ADDR_DEVICE_PATH MacAddr;
- IPv4_DEVICE_PATH Ipv4;
- IPv6_DEVICE_PATH Ipv6;
- INFINIBAND_DEVICE_PATH InfiniBand;
- UART_DEVICE_PATH Uart;
-
- HARDDRIVE_DEVICE_PATH HardDrive;
- CDROM_DEVICE_PATH CD;
-
- FILEPATH_DEVICE_PATH FilePath;
- MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
-
- BBS_BBS_DEVICE_PATH Bbs;
-} EFI_DEV_PATH;
-
-
-
-typedef union {
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- PCI_DEVICE_PATH *Pci;
- PCCARD_DEVICE_PATH *PcCard;
- MEMMAP_DEVICE_PATH *MemMap;
- VENDOR_DEVICE_PATH *Vendor;
-
- CONTROLLER_DEVICE_PATH *Controller;
- ACPI_HID_DEVICE_PATH *Acpi;
- ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
-
- ATAPI_DEVICE_PATH *Atapi;
- SCSI_DEVICE_PATH *Scsi;
- FIBRECHANNEL_DEVICE_PATH *FibreChannel;
-
- F1394_DEVICE_PATH *F1394;
- USB_DEVICE_PATH *Usb;
- SATA_DEVICE_PATH *Sata;
- USB_CLASS_DEVICE_PATH *UsbClass;
- I2O_DEVICE_PATH *I2O;
- MAC_ADDR_DEVICE_PATH *MacAddr;
- IPv4_DEVICE_PATH *Ipv4;
- IPv6_DEVICE_PATH *Ipv6;
- INFINIBAND_DEVICE_PATH *InfiniBand;
- UART_DEVICE_PATH *Uart;
-
- HARDDRIVE_DEVICE_PATH *HardDrive;
- CDROM_DEVICE_PATH *CD;
-
- FILEPATH_DEVICE_PATH *FilePath;
- MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol;
-
- BBS_BBS_DEVICE_PATH *Bbs;
- UINT8 *Raw;
-} EFI_DEV_PATH_PTR;
-
-#pragma pack()
-
-#define EFI_DP_TYPE_MASK 0x7F
-#define EFI_DP_TYPE_UNPACKED 0x80
-#define END_DEVICE_PATH_TYPE 0x7f
-
-#define EFI_END_ENTIRE_DEVICE_PATH 0xff
-#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
-#define EFI_END_INSTANCE_DEVICE_PATH 0x01
-#define END_ENTIRE_DEVICE_PATH_SUBTYPE EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE
-#define END_INSTANCE_DEVICE_PATH_SUBTYPE EFI_END_INSTANCE_DEVICE_PATH
-
-#define EFI_END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL))
-#define END_DEVICE_PATH_LENGTH EFI_END_DEVICE_PATH_LENGTH
-
-#define DP_IS_END_TYPE(a)
-#define DP_IS_END_SUBTYPE(a) (((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE)
-#define DevicePathSubType(a) ((a)->SubType)
-#define IsDevicePathUnpacked(a) ((a)->Type & EFI_DP_TYPE_UNPACKED)
-
-#define EfiDevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8))
-#define DevicePathNodeLength(a) (EfiDevicePathNodeLength(a))
-#define EfiNextDevicePathNode(a) ((EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) (a)) + EfiDevicePathNodeLength (a)))
-#define NextDevicePathNode(a) (EfiNextDevicePathNode(a))
-
-#define EfiDevicePathType(a) (((a)->Type) & EFI_DP_TYPE_MASK)
-#define DevicePathType(a) (EfiDevicePathType(a))
-#define EfiIsDevicePathEndType(a) (EfiDevicePathType (a) == END_DEVICE_PATH_TYPE)
-#define IsDevicePathEndType(a) (EfiIsDevicePathEndType(a))
-
-
-#define EfiIsDevicePathEndSubType(a) ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
-#define IsDevicePathEndSubType(a) (EfiIsDevicePathEndSubType(a))
-#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == EFI_END_INSTANCE_DEVICE_PATH)
-
-#define EfiIsDevicePathEnd(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))
-#define IsDevicePathEnd(a) (EfiIsDevicePathEnd(a))
-#define EfiIsDevicePathEndInstance(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndInstanceSubType (a))
-
-
-#define SetDevicePathNodeLength(a,l) { \
- (a)->Length[0] = (UINT8) (l); \
- (a)->Length[1] = (UINT8) ((l) >> 8); \
- }
-
-#define SetDevicePathEndNode(a) { \
- (a)->Type = END_DEVICE_PATH_TYPE; \
- (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \
- (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \
- (a)->Length[1] = 0; \
- }
-
-extern EFI_GUID gEfiDevicePathProtocolGuid;
-
-#endif
diff --git a/BaseTools/Source/C/VfrCompile/EfiVfr.h b/BaseTools/Source/C/VfrCompile/EfiVfr.h
index 406a12491d..aad9417156 100644
--- a/BaseTools/Source/C/VfrCompile/EfiVfr.h
+++ b/BaseTools/Source/C/VfrCompile/EfiVfr.h
@@ -1,6 +1,6 @@
/** @file
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -23,7 +23,6 @@ Abstract:
#define _EFIVFR_H_
#include "Common/UefiBaseTypes.h"
-#include "Protocol/DevicePath.h"
#include "Common/UefiInternalFormRepresentation.h"
#include "Common/MdeModuleHii.h"
@@ -43,6 +42,7 @@ typedef enum {
QUESTION_NORMAL,
QUESTION_DATE,
QUESTION_TIME,
+ QUESTION_REF,
} EFI_QUESION_TYPE;
typedef enum {
diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
index 5985a7ad5d..926561760a 100644
--- a/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
@@ -22,6 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
PACKAGE_DATA gCBuffer;
PACKAGE_DATA gRBuffer;
+CVfrStringDB gCVfrStringDB;
VOID
CVfrCompiler::DebugError (
@@ -62,7 +63,9 @@ CVfrCompiler::OptionInitialization (
)
{
INT32 Index;
-
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
SetUtilityName ((CHAR8*) PROGRAM_NAME);
mOptions.VfrFileName[0] = '\0';
@@ -78,6 +81,8 @@ CVfrCompiler::OptionInitialization (
mOptions.SkipCPreprocessor = TRUE;
mOptions.CPreprocessorOptions = NULL;
mOptions.CompatibleMode = FALSE;
+ mOptions.HasOverrideClassGuid = FALSE;
+ memset (&mOptions.OverrideClassGuid, 0, sizeof (EFI_GUID));
if (Argc == 1) {
Usage ();
@@ -132,6 +137,22 @@ CVfrCompiler::OptionInitialization (
AppendCPreprocessorOptions (Argv[Index]);
} else if (stricmp(Argv[Index], "-c") == 0 || stricmp(Argv[Index], "--compatible-framework") == 0) {
mOptions.CompatibleMode = TRUE;
+ } else if (stricmp(Argv[Index], "-s") == 0|| stricmp(Argv[Index], "--string-db") == 0) {
+ Index++;
+ if ((Index >= Argc) || (Argv[Index][0] == '-')) {
+ DebugError (NULL, 0, 1001, "Missing option", "-s missing input string file name");
+ goto Fail;
+ }
+ gCVfrStringDB.SetStringFileName(Argv[Index]);
+ DebugMsg (NULL, 0, 9, (CHAR8 *) "Input string file path", Argv[Index]);
+ } else if ((stricmp (Argv[Index], "-g") == 0) || (stricmp (Argv[Index], "--guid") == 0)) {
+ Index++;
+ Status = StringToGuid (Argv[Index], &mOptions.OverrideClassGuid);
+ if (EFI_ERROR (Status)) {
+ DebugError (NULL, 0, 1000, "Invalid format:", "%s", Argv[Index]);
+ goto Fail;
+ }
+ mOptions.HasOverrideClassGuid = TRUE;
} else {
DebugError (NULL, 0, 1000, "Unknown option", "unrecognized option %s", Argv[Index]);
goto Fail;
@@ -399,6 +420,11 @@ CVfrCompiler::Usage (
" do not preprocessing input file",
" -c, --compatible-framework",
" compatible framework vfr file",
+ " -s, --string-db",
+ " input uni string package file",
+ " -g, --guid",
+ " override class guid input",
+ " format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
NULL
};
for (Index = 0; Help[Index] != NULL; Index++) {
@@ -472,7 +498,7 @@ Fail:
delete PreProcessCmd;
}
-extern UINT8 VfrParserStart (IN FILE *, IN BOOLEAN);
+extern UINT8 VfrParserStart (IN FILE *, IN INPUT_INFO_TO_SYNTAX *);
VOID
CVfrCompiler::Compile (
@@ -481,6 +507,7 @@ CVfrCompiler::Compile (
{
FILE *pInFile = NULL;
CHAR8 *InFileName = NULL;
+ INPUT_INFO_TO_SYNTAX InputInfo;
if (!IS_RUN_STATUS(STATUS_PREPROCESSED)) {
goto Fail;
@@ -495,7 +522,14 @@ CVfrCompiler::Compile (
goto Fail;
}
- if (VfrParserStart (pInFile, mOptions.CompatibleMode) != 0) {
+ InputInfo.CompatibleMode = mOptions.CompatibleMode;
+ if (mOptions.HasOverrideClassGuid) {
+ InputInfo.OverrideClassGuid = &mOptions.OverrideClassGuid;
+ } else {
+ InputInfo.OverrideClassGuid = NULL;
+ }
+
+ if (VfrParserStart (pInFile, &InputInfo) != 0) {
goto Fail;
}
diff --git a/BaseTools/Source/C/VfrCompile/VfrCompiler.h b/BaseTools/Source/C/VfrCompile/VfrCompiler.h
index 7525bb5603..1c83e87f5f 100644
--- a/BaseTools/Source/C/VfrCompile/VfrCompiler.h
+++ b/BaseTools/Source/C/VfrCompile/VfrCompiler.h
@@ -20,10 +20,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "EfiVfr.h"
#include "VfrFormPkg.h"
#include "VfrUtilityLib.h"
+#include "ParseInf.h"
#define PROGRAM_NAME "VfrCompile"
-#define VFR_COMPILER_VERSION " 1.95 (UEFI 2.1)"
-#define VFR_COMPILER_UPDATE_TIME " updated on 2011/02/25"
+#define VFR_COMPILER_VERSION " 2.00 (UEFI 2.3.1)"
+#define VFR_COMPILER_UPDATE_TIME " updated on 2011/07/15"
//
// This is how we invoke the C preprocessor on the VFR source file
// to resolve #defines, #includes, etc. To make C source files
@@ -54,6 +55,8 @@ typedef struct {
bool SkipCPreprocessor;
CHAR8 *CPreprocessorOptions;
BOOLEAN CompatibleMode;
+ BOOLEAN HasOverrideClassGuid;
+ EFI_GUID OverrideClassGuid;
} OPTIONS;
typedef enum {
diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
index 571af91b0a..6401e71f4d 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
@@ -1305,6 +1305,8 @@ static struct {
{ sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP
{ sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP
{ sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60
+ { sizeof (EFI_IFR_MODAL), 0}, // EFI_IFR_MODAL_OP - 0x61
+ { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62
};
#ifdef CIFROBJ_DEUBG
@@ -1327,7 +1329,7 @@ static struct {
"EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",
"EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",
"EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",
- "EFI_IFR_SECURITY",
+ "EFI_IFR_SECURITY", "EFI_IFR_MODAL", "EFI_IFR_REFRESH_ID",
};
VOID
diff --git a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
index 4cdd1cc5db..f908718c02 100644
--- a/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
+++ b/BaseTools/Source/C/VfrCompile/VfrFormPkg.h
@@ -96,6 +96,11 @@ struct SBufferNode {
struct SBufferNode *mNext;
};
+typedef struct {
+ BOOLEAN CompatibleMode;
+ EFI_GUID *OverrideClassGuid;
+} INPUT_INFO_TO_SYNTAX;
+
class CFormPkg {
private:
UINT32 mBufferSize;
@@ -144,7 +149,8 @@ public:
);
};
-extern CFormPkg gCFormPkg;
+extern CFormPkg gCFormPkg;
+extern CVfrStringDB gCVfrStringDB;
struct SIfrRecord {
UINT32 mLineNo;
@@ -233,6 +239,15 @@ public:
return FALSE;
}
}
+
+ inline bool ShrinkObjBin (IN UINT8 Size) {
+ if ((mDelayEmit == TRUE) && (mObjBinLen > Size)) {
+ mObjBinLen -= Size;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
};
/*
@@ -254,7 +269,7 @@ public:
VOID DecLength (UINT8 Size) {
if (mHeader->Length >= Size) {
- mHeader -= Size;
+ mHeader->Length -= Size;
}
}
@@ -755,10 +770,12 @@ private:
EFI_IFR_VARSTORE_EFI *mVarStoreEfi;
public:
- CIfrVarStoreEfi () : CIfrObj (EFI_IFR_VARSTORE_EFI_OP, (CHAR8 **)&mVarStoreEfi),
+ CIfrVarStoreEfi () : CIfrObj (EFI_IFR_VARSTORE_EFI_OP, (CHAR8 **)&mVarStoreEfi, sizeof (EFI_IFR_VARSTORE_EFI), TRUE),
CIfrOpHeader (EFI_IFR_VARSTORE_EFI_OP, &mVarStoreEfi->Header) {
mVarStoreEfi->VarStoreId = EFI_VAROFFSET_INVALID;
+ mVarStoreEfi->Size = 0;
memset (&mVarStoreEfi->Guid, 0, sizeof (EFI_GUID));
+ mVarStoreEfi->Name[0] = '\0';
}
VOID SetGuid (IN EFI_GUID *Guid) {
@@ -772,6 +789,36 @@ public:
VOID SetAttributes (IN UINT32 Attributes) {
mVarStoreEfi->Attributes = Attributes;
}
+ VOID SetSize (IN UINT16 Size) {
+ mVarStoreEfi->Size = Size;
+ }
+
+ VOID SetName (IN CHAR8 *Name) {
+ UINT8 Len;
+
+ if (Name != NULL) {
+ Len = (UINT8) strlen (Name);
+ if (Len != 0) {
+ if (ExpendObjBin (Len) == TRUE) {
+ IncLength (Len);
+ strcpy ((CHAR8 *)(mVarStoreEfi->Name), Name);
+ }
+ }
+ }
+ }
+
+ VOID SetBinaryLength (IN UINT16 Size) {
+ UINT16 Len;
+
+ Len = sizeof (EFI_IFR_VARSTORE_EFI);
+ if (Size > Len) {
+ ExpendObjBin(Size - Len);
+ IncLength(Size - Len);
+ } else {
+ ShrinkObjBin(Len - Size);
+ DecLength(Len - Size);
+ }
+ }
};
class CIfrVarStoreNameValue : public CIfrObj, public CIfrOpHeader {
@@ -809,6 +856,17 @@ public:
}
};
+class CIfrModal : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_MODAL *mModal;
+
+public:
+ CIfrModal () : CIfrObj (EFI_IFR_MODAL_TAG_OP, (CHAR8 **)&mModal),
+ CIfrOpHeader (EFI_IFR_MODAL_TAG_OP, &mModal->Header) {
+ }
+};
+
+
class CIfrLocked : public CIfrObj, public CIfrOpHeader {
private:
EFI_IFR_LOCKED *mLocked;
@@ -1043,8 +1101,8 @@ private:
EFI_IFR_REF4 *mRef4;
public:
- CIfrRef4 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef4, sizeof(EFI_IFR_REF3)),
- CIfrOpHeader (EFI_IFR_REF_OP, &mRef4->Header, sizeof (EFI_IFR_REF3)),
+ CIfrRef4 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef4, sizeof(EFI_IFR_REF4)),
+ CIfrOpHeader (EFI_IFR_REF_OP, &mRef4->Header, sizeof(EFI_IFR_REF4)),
CIfrQuestionHeader (&mRef4->Question) {
mRef4->FormId = 0;
mRef4->QuestionId = EFI_QUESTION_ID_INVALID;
@@ -1069,6 +1127,17 @@ public:
}
};
+class CIfrRef5 : public CIfrObj, public CIfrOpHeader, public CIfrQuestionHeader {
+private:
+ EFI_IFR_REF5 *mRef5;
+
+public:
+ CIfrRef5 () : CIfrObj (EFI_IFR_REF_OP, (CHAR8 **)&mRef5, sizeof (EFI_IFR_REF5)),
+ CIfrOpHeader (EFI_IFR_REF_OP, &mRef5->Header, sizeof (EFI_IFR_REF5)),
+ CIfrQuestionHeader (&mRef5->Question) {
+ }
+};
+
class CIfrResetButton : public CIfrObj, public CIfrOpHeader, public CIfrStatementHeader {
private:
EFI_IFR_RESET_BUTTON *mResetButton;
@@ -1481,6 +1550,21 @@ public:
}
};
+class CIfrRefreshId : public CIfrObj, public CIfrOpHeader {
+private:
+ EFI_IFR_REFRESH_ID *mRefreshId;
+
+public:
+ CIfrRefreshId () : CIfrObj (EFI_IFR_REFRESH_ID_OP, (CHAR8 **)&mRefreshId),
+ CIfrOpHeader (EFI_IFR_REFRESH_ID_OP, &mRefreshId->Header) {
+ memset (&mRefreshId->RefreshEventGroupId, 0, sizeof (EFI_GUID));
+ }
+
+ VOID SetRefreshEventGroutId (IN EFI_GUID *RefreshEventGroupId) {
+ memcpy (&mRefreshId->RefreshEventGroupId, RefreshEventGroupId, sizeof (EFI_GUID));
+ }
+};
+
class CIfrVarStoreDevice : public CIfrObj, public CIfrOpHeader {
private:
EFI_IFR_VARSTORE_DEVICE *mVarStoreDevice;
diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
index 02a7b5c1f4..081c67d715 100644
--- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g
+++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g
@@ -51,11 +51,12 @@ public:
UINT8
VfrParserStart (
IN FILE *File,
- IN BOOLEAN CompatibleMode
+ IN INPUT_INFO_TO_SYNTAX *InputInfo
)
{
ParserBlackBox<CVfrDLGLexer, EfiVfrParser, ANTLRToken> VfrParser(File);
- VfrParser.parser()->SetCompatibleMode (CompatibleMode);
+ VfrParser.parser()->SetCompatibleMode (InputInfo->CompatibleMode);
+ VfrParser.parser()->SetOverrideClassGuid (InputInfo->OverrideClassGuid);
return VfrParser.parser()->vfrProgram();
}
>>
@@ -237,6 +238,7 @@ VfrParserStart (
#token EndGuidOp("endguidop") "endguidop"
#token DataType("datatype") "datatype"
#token Data("data") "data"
+#token Modal("modal") "modal"
//
// Define the class and subclass tokens
@@ -340,6 +342,7 @@ vfrDataStructFields :
dataStructFieldString |
dataStructFieldDate |
dataStructFieldTime |
+ dataStructFieldRef |
dataStructFieldUser
)*
;
@@ -426,6 +429,16 @@ dataStructFieldTime :
";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum), N); >>
;
+dataStructFieldRef :
+ << UINT32 ArrayNum = 0; >>
+ D:"EFI_HII_REF"
+ N:StringIdentifier
+ {
+ OpenBracket I:Number CloseBracket << ArrayNum = _STOU32(I->getText()); >>
+ }
+ ";" << _PCATCH(gCVfrVarDataTypeDB.DataTypeAddField (N->getText(), D->getText(), ArrayNum), N); >>
+ ;
+
dataStructFieldUser :
<< UINT32 ArrayNum = 0; >>
T:StringIdentifier
@@ -497,19 +510,42 @@ vfrFormSetDefinition :
","
}
<<
+ if (mOverrideClassGuid != NULL && ClassGuidNum >= 3) {
+ _PCATCH (VFR_RETURN_INVALID_PARAMETER, L->getLine(), "Already has 3 class guids, can't add extra class guid!");
+ }
switch (ClassGuidNum) {
case 0:
- FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + sizeof(EFI_GUID));
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum = 2;
+ } else {
+ ClassGuidNum = 1;
+ }
+ FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
FSObj->SetClassGuid(&DefaultClassGuid);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
break;
case 1:
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum ++;
+ }
FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
FSObj->SetClassGuid(&ClassGuid1);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
break;
case 2:
+ if (mOverrideClassGuid != NULL) {
+ ClassGuidNum ++;
+ }
FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
FSObj->SetClassGuid(&ClassGuid1);
FSObj->SetClassGuid(&ClassGuid2);
+ if (mOverrideClassGuid != NULL) {
+ FSObj->SetClassGuid(mOverrideClassGuid);
+ }
break;
case 3:
FSObj = new CIfrFormSet(sizeof(EFI_IFR_FORM_SET) + ClassGuidNum * sizeof(EFI_GUID));
@@ -602,7 +638,9 @@ vfrStatementExtension:
<< TypeName = D->getText(); LineNum = D->getLine(); IsStruct = TRUE;>>
| T:"EFI_HII_TIME" {OpenBracket AN8:Number CloseBracket <<ArrayNum = _STOU32(AN8->getText());>>}
<< TypeName = T->getText(); LineNum = T->getLine(); IsStruct = TRUE;>>
- | TN:StringIdentifier {OpenBracket AN9:Number CloseBracket <<ArrayNum = _STOU32(AN9->getText());>>}
+ | R:"EFI_HII_REF" {OpenBracket AN9:Number CloseBracket <<ArrayNum = _STOU32(AN9->getText());>>}
+ << TypeName = R->getText(); LineNum = R->getLine(); IsStruct = TRUE;>>
+ | TN:StringIdentifier {OpenBracket AN10:Number CloseBracket <<ArrayNum = _STOU32(AN10->getText());>>}
<< TypeName = TN->getText(); LineNum = TN->getLine(); IsStruct = TRUE;>>
)
<<
@@ -794,6 +832,7 @@ vfrStatementVarStoreLinear :
| U64:"UINT64" "," << TypeName = U64->getText(); LineNum = U64->getLine(); >>
| D:"EFI_HII_DATE" "," << TypeName = D->getText(); LineNum = D->getLine(); >>
| T:"EFI_HII_TIME" "," << TypeName = T->getText(); LineNum = T->getLine(); >>
+ | R:"EFI_HII_REF" "," << TypeName = R->getText(); LineNum = R->getLine(); >>
)
{ Key "=" FID:Number "," << // Key is used to assign Varid in Framework VFR but no use in UEFI2.1 VFR
if (mCompatibleMode) {
@@ -838,22 +877,102 @@ vfrStatementVarStoreLinear :
vfrStatementVarStoreEfi :
<<
+ BOOLEAN IsUEFI23EfiVarstore = TRUE;
EFI_GUID Guid;
CIfrVarStoreEfi VSEObj;
- EFI_VARSTORE_ID VarStoreId;
+ EFI_VARSTORE_ID VarStoreId = EFI_VARSTORE_ID_INVALID;
UINT32 Attr = 0;
+ UINT32 Size;
+ CHAR8 *TypeName;
+ UINT32 LineNum;
+ CHAR8 *StoreName = NULL;
>>
E:Efivarstore << VSEObj.SetLineNo(E->getLine()); >>
- SN:StringIdentifier ","
+ (
+ TN:StringIdentifier "," << TypeName = TN->getText(); LineNum = TN->getLine(); >>
+ | U8:"UINT8" "," << TypeName = U8->getText(); LineNum = U8->getLine(); >>
+ | U16:"UINT16" "," << TypeName = U16->getText(); LineNum = U16->getLine(); >>
+ | C16:"CHAR16" "," << TypeName = (CHAR8 *) "UINT16"; LineNum = C16->getLine(); >>
+ | U32:"UINT32" "," << TypeName = U32->getText(); LineNum = U32->getLine(); >>
+ | U64:"UINT64" "," << TypeName = U64->getText(); LineNum = U64->getLine(); >>
+ | D:"EFI_HII_DATE" "," << TypeName = D->getText(); LineNum = D->getLine(); >>
+ | T:"EFI_HII_TIME" "," << TypeName = T->getText(); LineNum = T->getLine(); >>
+ | R:"EFI_HII_REF" "," << TypeName = R->getText(); LineNum = R->getLine(); >>
+ )
+ {
+ VarId "=" ID:Number "," <<
+ _PCATCH(
+ (INTN)(VarStoreId = _STOU16(ID->getText())) != 0,
+ (INTN)TRUE,
+ ID,
+ "varid 0 is not allowed."
+ );
+ >>
+ }
Attribute "=" vfrVarStoreEfiAttr[Attr] ( "\|" vfrVarStoreEfiAttr[Attr] )* ","
<< VSEObj.SetAttributes (Attr); >>
- Name "=" "STRING_TOKEN" "\(" VN:Number "\)" ","
- VarSize "=" N:Number ","
- Uuid "=" guidDefinition[Guid] << mCVfrDataStorage.DeclareEfiVarStore (SN->getText(), &Guid, _STOSID(VN->getText()), _STOU32(N->getText())); >>
- <<
- VSEObj.SetGuid (&Guid);
- _PCATCH(mCVfrDataStorage.GetVarStoreId(SN->getText(), &VarStoreId), SN);
+
+ (
+ Name "=" SN:StringIdentifier "," << StoreName = SN->getText(); >>
+ |
+ Name "=" "STRING_TOKEN" "\(" VN:Number "\)" ","
+ VarSize "=" N:Number "," <<
+ IsUEFI23EfiVarstore = FALSE;
+ StoreName = gCVfrStringDB.GetVarStoreNameFormStringId(_STOSID(VN->getText()));
+ if (StoreName == NULL) {
+ _PCATCH (VFR_RETURN_UNSUPPORTED, VN->getLine(), "Can't get varstore name for this StringId!");
+ }
+ Size = _STOU32(N->getText());
+ switch (Size) {
+ case 1:
+ TypeName = (CHAR8 *) "UINT8";
+ break;
+ case 2:
+ TypeName = (CHAR8 *) "UINT16";
+ break;
+ case 4:
+ TypeName = (CHAR8 *) "UINT32";
+ break;
+ case 8:
+ TypeName = (CHAR8 *) "UINT64";
+ break;
+ default:
+ _PCATCH (VFR_RETURN_UNSUPPORTED, N);
+ break;
+ }
+ >>
+ )
+
+ Uuid "=" guidDefinition[Guid] <<
+ if (IsUEFI23EfiVarstore) {
+ _PCATCH(mCVfrDataStorage.DeclareBufferVarStore (
+ StoreName,
+ &Guid,
+ &gCVfrVarDataTypeDB,
+ TypeName,
+ VarStoreId
+ ), LineNum);
+ _PCATCH(mCVfrDataStorage.GetVarStoreId(StoreName, &VarStoreId), SN);
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), LineNum);
+ } else {
+ _PCATCH(mCVfrDataStorage.DeclareBufferVarStore (
+ TN->getText(),
+ &Guid,
+ &gCVfrVarDataTypeDB,
+ TypeName,
+ VarStoreId
+ ), LineNum);
+ _PCATCH(mCVfrDataStorage.GetVarStoreId(TN->getText(), &VarStoreId), VN);
+ _PCATCH(gCVfrVarDataTypeDB.GetDataTypeSize(TypeName, &Size), N->getLine());
+ }
+ VSEObj.SetGuid (&Guid);
VSEObj.SetVarStoreId (VarStoreId);
+
+ VSEObj.SetSize ((UINT16) Size);
+ VSEObj.SetName (StoreName);
+ if (IsUEFI23EfiVarstore == FALSE && StoreName != NULL) {
+ delete StoreName;
+ }
>>
";"
;
@@ -978,39 +1097,31 @@ vfrQuestionHeader[CIfrQuestionHeader & QHObj, EFI_QUESION_TYPE QType = QUESTION_
case QUESTION_TIME:
mCVfrQuestionDB.RegisterNewTimeQuestion (QName, VarIdStr, QId);
break;
+ case QUESTION_REF:
+ //
+ // VarIdStr != NULL stand for question with storagae.
+ //
+ if (VarIdStr != NULL) {
+ mCVfrQuestionDB.RegisterRefQuestion (QName, VarIdStr, QId);
+ } else {
+ mCVfrQuestionDB.RegisterQuestion (QName, NULL, QId);
+ }
+ break;
default:
_PCATCH(VFR_RETURN_FATAL_ERROR);
}
$QHObj.SetQuestionId (QId);
- $QHObj.SetVarStoreInfo (&Info);
+ if (VarIdStr != NULL) {
+ $QHObj.SetVarStoreInfo (&Info);
+ }
>>
vfrStatementHeader[&$QHObj]
- << _SAVE_CURRQEST_VARINFO (Info); >>
- << if (VarIdStr != NULL) delete VarIdStr; >>
- ;
-
-vfrQuestionHeaderWithNoStorage[CIfrQuestionHeader *QHObj] :
- <<
- EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;
- CHAR8 *QName = NULL;
- >>
- {
- Name "=" QN:StringIdentifier "," <<
- QName = QN->getText();
- _PCATCH(mCVfrQuestionDB.FindQuestion (QName), VFR_RETURN_UNDEFINED, QN, "has already been used please used anther name");
- >>
- }
- {
- QuestionId "=" ID:Number "," <<
- QId = _STOQID(ID->getText());
- _PCATCH(mCVfrQuestionDB.FindQuestion (QId), VFR_RETURN_UNDEFINED, ID, "redefined quesiont ID");
- >>
- }
- <<
- mCVfrQuestionDB.RegisterQuestion (QName, NULL, QId);
- $QHObj->SetQuestionId (QId);
+ <<
+ if (VarIdStr != NULL) {
+ delete VarIdStr;
+ _SAVE_CURRQEST_VARINFO (Info);
+ }
>>
- vfrStatementHeader[$QHObj]
;
questionheaderFlagsField[UINT8 & Flags] :
@@ -1060,6 +1171,8 @@ vfrStorageVarId[EFI_VARSTORE_INFO & Info, CHAR8 *&QuestVarIdStr, BOOLEAN CheckFl
_PCATCH(mCVfrDataStorage.GetVarStoreId (SName, &$Info.mVarStoreId), SN1);
_PCATCH(mCVfrDataStorage.GetNameVarStoreInfo (&$Info, Idx), SN1);
}
+
+ QuestVarIdStr = VarIdStr;
>>
)
|
@@ -1194,6 +1307,9 @@ vfrQuestionDataFieldName [EFI_QUESTION_ID &QId, UINT32 &Mask, CHAR8 *&VarIdStr,
;
vfrConstantValueField[UINT8 Type] > [EFI_IFR_TYPE_VALUE Value] :
+ <<
+ EFI_GUID Guid;
+ >>
N1:Number <<
switch ($Type) {
case EFI_IFR_TYPE_NUM_SIZE_8 :
@@ -1216,6 +1332,7 @@ vfrConstantValueField[UINT8 Type] > [EFI_IFR_TYPE_VALUE Value] :
break;
case EFI_IFR_TYPE_TIME :
case EFI_IFR_TYPE_DATE :
+ case EFI_IFR_TYPE_REF :
default :
break;
}
@@ -1227,6 +1344,8 @@ vfrConstantValueField[UINT8 Type] > [EFI_IFR_TYPE_VALUE Value] :
| Z:Zero << $Value.u8 = _STOU8(Z->getText()); >>
| HOUR:Number ":" MINUTE:Number ":" SECOND:Number << $Value.time = _STOT(HOUR->getText(), MINUTE->getText(), SECOND->getText()); >>
| YEAR:Number "/" MONTH:Number "/" DAY:Number << $Value.date = _STOD(YEAR->getText(), MONTH->getText(), DAY->getText()); >>
+ | QI:Number";" FI:Number";" guidDefinition[Guid] ";" "STRING_TOKEN" "\(" DP:Number "\)"
+ << $Value.ref = _STOR(QI->getText(), FI->getText(), &Guid, DP->getText()); >>
| "STRING_TOKEN" "\(" S1:Number "\)" << $Value.string = _STOSID(S1->getText()); >>
;
@@ -1251,7 +1370,8 @@ vfrFormDefinition :
vfrStatementBanner |
// Just for framework vfr compatibility
vfrStatementInvalid |
- vfrStatementExtension
+ vfrStatementExtension |
+ vfrStatementModal
)*
E:EndForm <<
if (mCompatibleMode) {
@@ -1310,7 +1430,8 @@ vfrFormMapDefinition :
vfrStatementConditional |
vfrStatementLabel |
vfrStatementBanner |
- vfrStatementExtension
+ vfrStatementExtension |
+ vfrStatementModal
)*
E:EndForm << CRT_END_OP (E); >>
";"
@@ -1516,7 +1637,7 @@ vfrStatementCrossReference :
vfrStatementGoto :
<<
- UINT8 RefType = 1;
+ UINT8 RefType = 5;
EFI_STRING_ID DevPath = EFI_STRING_ID_INVALID;
EFI_GUID FSId = {0,};
EFI_FORM_ID FId;
@@ -1527,9 +1648,10 @@ vfrStatementGoto :
CIfrRef2 *R2Obj = NULL;
CIfrRef3 *R3Obj = NULL;
CIfrRef4 *R4Obj = NULL;
+ CIfrRef5 *R5Obj = NULL;
>>
G:Goto
- (
+ {
(
DevicePath "=" "STRING_TOKEN" "\(" P:Number "\)" ","
FormSetGuid "=" guidDefinition[FSId] ","
@@ -1569,9 +1691,16 @@ vfrStatementGoto :
FId = _STOFID(F4->getText());
>>
)
- )
+ }
<<
switch (RefType) {
+ case 5:
+ {
+ R5Obj = new CIfrRef5;
+ QHObj = R5Obj;
+ R5Obj->SetLineNo(G->getLine());
+ break;
+ }
case 4:
{
R4Obj = new CIfrRef4;
@@ -1613,13 +1742,13 @@ vfrStatementGoto :
default: break;
}
>>
- vfrQuestionHeaderWithNoStorage[QHObj]
+ vfrQuestionHeader[*QHObj, QUESTION_REF]
{ "," vfrStatementStatTagList }
{ "," F:FLAGS "=" vfrGotoFlags[QHObj, F->getLine()] }
{
"," Key "=" KN:Number << AssignQuestionKey (*QHObj, KN); >>
}
- ";" << if (R1Obj != NULL) {delete R1Obj;} if (R2Obj != NULL) {delete R2Obj;} if (R3Obj != NULL) {delete R3Obj;} if (R4Obj != NULL) {delete R4Obj;} >>
+ ";" << if (R1Obj != NULL) {delete R1Obj;} if (R2Obj != NULL) {delete R2Obj;} if (R3Obj != NULL) {delete R3Obj;} if (R4Obj != NULL) {delete R4Obj;} if (R5Obj != NULL) {delete R5Obj;}>>
;
vfrGotoFlags [CIfrQuestionHeader *QHObj, UINT32 LineNum] :
@@ -1792,7 +1921,7 @@ checkboxFlagsField[UINT8 & LFlags, UINT8 & HFlags] :
vfrStatementAction :
<< CIfrAction AObj; >>
L:Action << AObj.SetLineNo(L->getLine()); >>
- vfrQuestionHeaderWithNoStorage[&AObj] ","
+ vfrQuestionHeader[AObj] ","
{ F:FLAGS "=" vfrActionFlags[AObj, F->getLine()] "," }
Config "=" "STRING_TOKEN" "\(" S:Number "\)" "," << AObj.SetQuestionConfig (_STOSID(S->getText())); >>
vfrStatementQuestionTagList
@@ -2339,7 +2468,8 @@ vfrStatementQuestionTag :
vfrStatementDisableIfQuest |
vfrStatementRefresh |
vfrStatementVarstoreDevice |
- vfrStatementExtension
+ vfrStatementExtension |
+ vfrStatementRefreshEvent
;
vfrStatementQuestionTagList :
@@ -2490,6 +2620,11 @@ vfrLockedTag :
L:Locked << LObj.SetLineNo(L->getLine()); >>
;
+vfrModalTag :
+ << CIfrModal MObj; >>
+ L:Modal << MObj.SetLineNo(L->getLine()); >>
+ ;
+
vfrStatementStatTag :
vfrImageTag |
vfrLockedTag
@@ -2504,6 +2639,11 @@ vfrStatementImage :
";"
;
+vfrStatementModal :
+ vfrModalTag
+ ";"
+ ;
+
vfrStatementLocked :
vfrLockedTag
";"
@@ -2543,6 +2683,15 @@ vfrStatementRefresh :
Interval "=" I:Number << RObj.SetRefreshInterval (_STOU8(I->getText())); >>
;
+vfrStatementRefreshEvent :
+ <<
+ CIfrRefreshId RiObj;
+ EFI_GUID Guid;
+ >>
+ L:RefreshGuid << RiObj.SetLineNo(L->getLine()); >>
+ "=" guidDefinition[Guid] "," << RiObj.SetRefreshEventGroutId (&Guid); >>
+ ;
+
vfrStatementVarstoreDevice :
<< CIfrVarStoreDevice VDObj; >>
L:VarstoreDevice << VDObj.SetLineNo(L->getLine()); >>
@@ -2811,6 +2960,7 @@ vfrStatementInvalidSaveRestoreDefaults :
#token QuestionRefVal("questionrefval") "questionrefval"
#token StringRefVal("stringrefval") "stringrefval"
#token Map("map") "map"
+#token RefreshGuid("refreshguid") "refreshguid"
//
// Root expression extension function called by other function.
@@ -3687,6 +3837,7 @@ private:
EFI_VARSTORE_INFO mCurrQestVarInfo;
+ EFI_GUID *mOverrideClassGuid;
//
// For framework vfr compatibility
@@ -3720,6 +3871,7 @@ public:
UINT64 _STOU64 (IN CHAR8 *);
EFI_HII_DATE _STOD (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *);
EFI_HII_TIME _STOT (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *);
+ EFI_HII_REF _STOR (IN CHAR8 *, IN CHAR8 *, IN EFI_GUID *, IN CHAR8 *);
EFI_STRING_ID _STOSID (IN CHAR8 *);
EFI_FORM_ID _STOFID (IN CHAR8 *);
@@ -3737,6 +3889,7 @@ public:
VOID IdEqValDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN UINT16, IN EFI_COMPARE_TYPE);
VOID IdEqIdDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN EFI_COMPARE_TYPE);
VOID IdEqListDoSpecial (IN UINT32 &, IN UINT32, IN EFI_QUESTION_ID, IN CHAR8 *, IN UINT32, IN UINT16, IN UINT16 *);
+ VOID SetOverrideClassGuid (IN EFI_GUID *);
//
// For framework vfr compatibility
//
@@ -4158,6 +4311,25 @@ EfiVfrParser::_STRCAT (
*Dest = NewStr;
}
+EFI_HII_REF
+EfiVfrParser::_STOR (
+ IN CHAR8 *QuestionId,
+ IN CHAR8 *FormId,
+ IN EFI_GUID *FormSetGuid,
+ IN CHAR8 *DevicePath
+ )
+{
+ EFI_HII_REF Ref;
+ UINT32 Index;
+
+ memcpy (&Ref.FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
+ Ref.QuestionId = _STOQID (QuestionId);
+ Ref.FormId = _STOFID (FormId);
+ Ref.DevicePath = _STOSID (DevicePath);
+
+ return Ref;
+}
+
//
// framework vfr to default declare varstore for each structure
//
@@ -4225,6 +4397,9 @@ EfiVfrParser::_DeclareDefaultFrameworkVarStore (
VSEObj.SetAttributes (0x00000002); //hardcode EFI_VARIABLE_BOOTSERVICE_ACCESS attribute
VSEObj.SetGuid (&pNode->mGuid);
VSEObj.SetVarStoreId (pNode->mVarStoreId);
+ // Generate old efi varstore storage structure for compatiable with old "VarEqVal" opcode,
+ // which is 3 bytes less than new structure define in UEFI Spec 2.3.1.
+ VSEObj.SetBinaryLength (sizeof (EFI_IFR_VARSTORE_EFI) - 3);
#ifdef VFREXP_DEBUG
printf ("undefined Efi VarStoreName is %s and Id is 0x%x\n", pNode->mVarStoreName, pNode->mVarStoreId);
#endif
@@ -4523,6 +4698,12 @@ EfiVfrParser::IdEqListDoSpecial (
}
}
+VOID
+EfiVfrParser::SetOverrideClassGuid (IN EFI_GUID *OverrideClassGuid)
+{
+ mOverrideClassGuid = OverrideClassGuid;
+}
+
//
// For framework vfr compatibility
//
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
index b839a0ab0e..c3a729eabf 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -468,6 +468,7 @@ static struct {
{"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},
{"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
{"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},
+ {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},
{NULL, EFI_IFR_TYPE_OTHER, 0, 0}
};
@@ -635,7 +636,7 @@ CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
EFI_VFR_RETURN_CODE
CVfrVarDataTypeDB::GetTypeField (
- IN CHAR8 *FName,
+ IN CONST CHAR8 *FName,
IN SVfrDataType *Type,
OUT SVfrDataField *&Field
)
@@ -647,6 +648,20 @@ CVfrVarDataTypeDB::GetTypeField (
}
for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
+ //
+ // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
+ // add code to adjust it.
+ //
+ if (Type->mType == EFI_IFR_TYPE_TIME) {
+ if (strcmp (FName, "Hour") == 0) {
+ FName = "Hours";
+ } else if (strcmp (FName, "Minute") == 0) {
+ FName = "Minuts";
+ } else if (strcmp (FName, "Second") == 0) {
+ FName = "Seconds";
+ }
+ }
+
if (strcmp (pField->mFieldName, FName) == 0) {
Field = pField;
return VFR_RETURN_SUCCESS;
@@ -789,6 +804,37 @@ CVfrVarDataTypeDB::InternalTypesListInit (
pSecondsField->mArrayNum = 0;
New->mMembers = pHoursField;
+ } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
+ SVfrDataField *pQuestionIdField = new SVfrDataField;
+ SVfrDataField *pFormIdField = new SVfrDataField;
+ SVfrDataField *pFormSetGuidField = new SVfrDataField;
+ SVfrDataField *pDevicePathField = new SVfrDataField;
+
+ strcpy (pQuestionIdField->mFieldName, "QuestionId");
+ GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);
+ pQuestionIdField->mOffset = 0;
+ pQuestionIdField->mNext = pFormIdField;
+ pQuestionIdField->mArrayNum = 0;
+
+ strcpy (pFormIdField->mFieldName, "FormId");
+ GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
+ pFormIdField->mOffset = 2;
+ pFormIdField->mNext = pFormSetGuidField;
+ pFormIdField->mArrayNum = 0;
+
+ strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
+ GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
+ pFormSetGuidField->mOffset = 4;
+ pFormSetGuidField->mNext = pDevicePathField;
+ pFormSetGuidField->mArrayNum = 0;
+
+ strcpy (pDevicePathField->mFieldName, "DevicePath");
+ GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
+ pDevicePathField->mOffset = 20;
+ pDevicePathField->mNext = NULL;
+ pDevicePathField->mArrayNum = 0;
+
+ New->mMembers = pQuestionIdField;
} else {
New->mMembers = NULL;
}
@@ -2770,6 +2816,100 @@ Err:
}
}
+VOID
+CVfrQuestionDB::RegisterRefQuestion (
+ IN CHAR8 *Name,
+ IN CHAR8 *BaseVarId,
+ IN OUT EFI_QUESTION_ID &QuestionId
+ )
+{
+ SVfrQuestionNode *pNode[4] = {NULL, };
+ UINT32 Len;
+ CHAR8 *VarIdStr[4] = {NULL, };
+ CHAR8 Index;
+
+ if (BaseVarId == NULL) {
+ return;
+ }
+
+ Len = strlen (BaseVarId);
+
+ VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
+ if (VarIdStr[0] != NULL) {
+ strcpy (VarIdStr[0], BaseVarId);
+ strcat (VarIdStr[0], ".QuestionId");
+ }
+ VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
+ if (VarIdStr[1] != NULL) {
+ strcpy (VarIdStr[1], BaseVarId);
+ strcat (VarIdStr[1], ".FormId");
+ }
+ VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
+ if (VarIdStr[2] != NULL) {
+ strcpy (VarIdStr[2], BaseVarId);
+ strcat (VarIdStr[2], ".FormSetGuid");
+ }
+ VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
+ if (VarIdStr[3] != NULL) {
+ strcpy (VarIdStr[3], BaseVarId);
+ strcat (VarIdStr[3], ".DevicePath");
+ }
+
+ if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
+ goto Err;
+ }
+ if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
+ goto Err;
+ }
+ if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
+ goto Err;
+ }
+ if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
+ goto Err;
+ }
+
+ if (QuestionId == EFI_QUESTION_ID_INVALID) {
+ QuestionId = GetFreeQuestionId ();
+ } else {
+ if (ChekQuestionIdFree (QuestionId) == FALSE) {
+ goto Err;
+ }
+ MarkQuestionIdUsed (QuestionId);
+ }
+
+ pNode[0]->mQuestionId = QuestionId;
+ pNode[1]->mQuestionId = QuestionId;
+ pNode[2]->mQuestionId = QuestionId;
+ pNode[3]->mQuestionId = QuestionId;
+ pNode[0]->mQtype = QUESTION_REF;
+ pNode[1]->mQtype = QUESTION_REF;
+ pNode[2]->mQtype = QUESTION_REF;
+ pNode[3]->mQtype = QUESTION_REF;
+ pNode[0]->mNext = pNode[1];
+ pNode[1]->mNext = pNode[2];
+ pNode[2]->mNext = pNode[3];
+ pNode[3]->mNext = mQuestionList;
+ mQuestionList = pNode[0];
+
+ gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+ gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
+
+ return;
+
+ Err:
+ for (Index = 0; Index < 4; Index++) {
+ if (pNode[Index] != NULL) {
+ delete pNode[Index];
+ }
+
+ if (VarIdStr[Index] != NULL) {
+ delete VarIdStr[Index];
+ }
+ }
+}
+
EFI_VFR_RETURN_CODE
CVfrQuestionDB::UpdateQuestionId (
IN EFI_QUESTION_ID QId,
@@ -2894,6 +3034,402 @@ CVfrQuestionDB::FindQuestion (
return VFR_RETURN_UNDEFINED;
}
+CVfrStringDB::CVfrStringDB ()
+{
+ mStringFileName = NULL;
+}
+
+CVfrStringDB::~CVfrStringDB ()
+{
+ if (mStringFileName != NULL) {
+ delete mStringFileName;
+ }
+ mStringFileName = NULL;
+}
+
+
+VOID
+CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
+{
+ UINT32 FileLen = 0;
+
+ if (StringFileName == NULL) {
+ return;
+ }
+
+ FileLen = strlen (StringFileName) + 1;
+ mStringFileName = new CHAR8[FileLen];
+ if (mStringFileName == NULL) {
+ return;
+ }
+
+ strcpy (mStringFileName, StringFileName);
+ mStringFileName[FileLen - 1] = '\0';
+}
+
+CHAR8 *
+CVfrStringDB::GetVarStoreNameFormStringId (
+ IN EFI_STRING_ID StringId
+ )
+{
+ FILE *pInFile = NULL;
+ UINT32 NameOffset;
+ UINT32 Length;
+ UINT8 *StringPtr;
+ CHAR8 *StringName;
+ CHAR16 *UnicodeString;
+ CHAR8 *VarStoreName = NULL;
+ CHAR8 *DestTmp;
+ UINT8 *Current;
+ EFI_STATUS Status;
+ CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
+ UINT8 BlockType;
+ EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
+
+ if (mStringFileName == '\0' ) {
+ return NULL;
+ }
+
+ if ((pInFile = fopen (mStringFileName, "rb")) == NULL) {
+ return NULL;
+ }
+
+ //
+ // Get file length.
+ //
+ fseek (pInFile, 0, SEEK_END);
+ Length = ftell (pInFile);
+ fseek (pInFile, 0, SEEK_SET);
+
+ //
+ // Get file data.
+ //
+ StringPtr = new UINT8[Length];
+ if (StringPtr == NULL) {
+ fclose (pInFile);
+ return NULL;
+ }
+ fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
+ fclose (pInFile);
+
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
+ //
+ // Check the String package.
+ //
+ if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
+ delete StringPtr;
+ return NULL;
+ }
+
+ //
+ // Search the language, only search the "en-US".
+ //
+ Current = StringPtr;
+ while (strcmp (PkgHeader->Language, "en-US") != 0) {
+ Current += PkgHeader->Header.Length;
+ PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
+ //
+ // If can't find "en-US" string package, just return the first string package.
+ //
+ if (Current - StringPtr >= Length) {
+ Current = StringPtr;
+ break;
+ }
+ }
+
+ Current += PkgHeader->HdrSize;
+ //
+ // Find the string block according the stringId.
+ //
+ Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
+ if (Status != EFI_SUCCESS) {
+ delete StringPtr;
+ return NULL;
+ }
+
+ //
+ // Get varstore name according the string type.
+ //
+ switch (BlockType) {
+ case EFI_HII_SIBT_STRING_SCSU:
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ StringName = (CHAR8*)(Current + NameOffset);
+ VarStoreName = new CHAR8[strlen(StringName) + 1];
+ strcpy (VarStoreName, StringName);
+ break;
+ case EFI_HII_SIBT_STRING_UCS2:
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ UnicodeString = (CHAR16*)(Current + NameOffset);
+ Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
+ DestTmp = new CHAR8[Length / 2 + 1];
+ VarStoreName = DestTmp;
+ while (*UnicodeString != '\0') {
+ *(DestTmp++) = (CHAR8) *(UnicodeString++);
+ }
+ *DestTmp = '\0';
+ break;
+ default:
+ break;
+ }
+
+ delete StringPtr;
+
+ return VarStoreName;
+}
+
+EFI_STATUS
+CVfrStringDB::FindStringBlock (
+ IN UINT8 *StringData,
+ IN EFI_STRING_ID StringId,
+ OUT UINT32 *StringTextOffset,
+ OUT UINT8 *BlockType
+ )
+{
+ UINT8 *BlockHdr;
+ EFI_STRING_ID CurrentStringId;
+ UINT32 BlockSize;
+ UINT32 Index;
+ UINT8 *StringTextPtr;
+ UINT32 Offset;
+ UINT16 StringCount;
+ UINT16 SkipCount;
+ UINT8 Length8;
+ EFI_HII_SIBT_EXT2_BLOCK Ext2;
+ UINT32 Length32;
+ UINT32 StringSize;
+
+ CurrentStringId = 1;
+
+ //
+ // Parse the string blocks to get the string text and font.
+ //
+ BlockHdr = StringData;
+ BlockSize = 0;
+ Offset = 0;
+ while (*BlockHdr != EFI_HII_SIBT_END) {
+ switch (*BlockHdr) {
+ case EFI_HII_SIBT_STRING_SCSU:
+ Offset = sizeof (EFI_HII_STRING_BLOCK);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
+ BlockSize += StringTextPtr - BlockHdr;
+
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ memcpy (
+ &StringCount,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT16)
+ );
+ StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
+ BlockSize += StringTextPtr - BlockHdr;
+
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_STRING_UCS2:
+ Offset = sizeof (EFI_HII_STRING_BLOCK);
+ StringTextPtr = BlockHdr + Offset;
+ //
+ // Use StringSize to store the size of the specified string, including the NULL
+ // terminator.
+ //
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += Offset + StringSize;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ //
+ // Use StrSize to store the size of the specified string, including the NULL
+ // terminator.
+ //
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += Offset + StringSize;
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset;
+ memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ for (Index = 0; Index < StringCount; Index++) {
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += StringSize;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + StringSize;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset;
+ memcpy (
+ &StringCount,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT16)
+ );
+ for (Index = 0; Index < StringCount; Index++) {
+ StringSize = GetUnicodeStringTextSize (StringTextPtr);
+ BlockSize += StringSize;
+ if (CurrentStringId == StringId) {
+ *BlockType = *BlockHdr;
+ *StringTextOffset = StringTextPtr - StringData;
+ return EFI_SUCCESS;
+ }
+ StringTextPtr = StringTextPtr + StringSize;
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_DUPLICATE:
+ if (CurrentStringId == StringId) {
+ //
+ // Incoming StringId is an id of a duplicate string block.
+ // Update the StringId to be the previous string block.
+ // Go back to the header of string block to search.
+ //
+ memcpy (
+ &StringId,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
+ sizeof (EFI_STRING_ID)
+ );
+ CurrentStringId = 1;
+ BlockSize = 0;
+ } else {
+ BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
+ CurrentStringId++;
+ }
+ break;
+
+ case EFI_HII_SIBT_SKIP1:
+ SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
+ CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
+ break;
+
+ case EFI_HII_SIBT_SKIP2:
+ memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
+ break;
+
+ case EFI_HII_SIBT_EXT1:
+ memcpy (
+ &Length8,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT8)
+ );
+ BlockSize += Length8;
+ break;
+
+ case EFI_HII_SIBT_EXT2:
+ memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
+ BlockSize += Ext2.Length;
+ break;
+
+ case EFI_HII_SIBT_EXT4:
+ memcpy (
+ &Length32,
+ BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
+ sizeof (UINT32)
+ );
+
+ BlockSize += Length32;
+ break;
+
+ default:
+ break;
+ }
+
+ if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
+ *StringTextOffset = BlockHdr - StringData + Offset;
+ *BlockType = *BlockHdr;
+
+ if (StringId == CurrentStringId - 1) {
+ //
+ // if only one skip item, return EFI_NOT_FOUND.
+ //
+ if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_SUCCESS;
+ }
+ }
+
+ if (StringId < CurrentStringId - 1) {
+ return EFI_NOT_FOUND;
+ }
+ }
+ BlockHdr = StringData + BlockSize;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+UINT32
+CVfrStringDB::GetUnicodeStringTextSize (
+ IN UINT8 *StringSrc
+ )
+{
+ UINT32 StringSize;
+ CHAR16 *StringPtr;
+
+ StringSize = sizeof (CHAR16);
+ StringPtr = (UINT16*)StringSrc;
+ while (*StringPtr++ != L'\0') {
+ StringSize += sizeof (CHAR16);
+ }
+
+ return StringSize;
+}
+
BOOLEAN VfrCompatibleMode = FALSE;
CVfrVarDataTypeDB gCVfrVarDataTypeDB;
diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
index b921115b0a..9facce8149 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
@@ -175,7 +175,7 @@ private:
VOID RegisterNewType (IN SVfrDataType *);
EFI_VFR_RETURN_CODE ExtractStructTypeName (IN CHAR8 *&, OUT CHAR8 *);
- EFI_VFR_RETURN_CODE GetTypeField (IN CHAR8 *, IN SVfrDataType *, IN SVfrDataField *&);
+ EFI_VFR_RETURN_CODE GetTypeField (IN CONST CHAR8 *, IN SVfrDataType *, IN SVfrDataField *&);
EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &);
UINT8 GetFieldWidth (IN SVfrDataField *);
UINT32 GetFieldSize (IN SVfrDataField *, IN UINT32);
@@ -359,6 +359,7 @@ public:
VOID RegisterNewDateQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
VOID RegisterOldTimeQuestion (IN CHAR8 *, IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
VOID RegisterNewTimeQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
+ VOID RegisterRefQuestion (IN CHAR8 *, IN CHAR8 *, IN OUT EFI_QUESTION_ID &);
EFI_VFR_RETURN_CODE UpdateQuestionId (IN EFI_QUESTION_ID, IN EFI_QUESTION_ID);
VOID GetQuestionId (IN CHAR8 *, IN CHAR8 *, OUT EFI_QUESTION_ID &, OUT UINT32 &, OUT EFI_QUESION_TYPE *QType = NULL);
EFI_VFR_RETURN_CODE FindQuestion (IN EFI_QUESTION_ID);
@@ -423,4 +424,33 @@ public:
UINT8 GetRuleId (IN CHAR8 *);
};
+class CVfrStringDB {
+private:
+ CHAR8 *mStringFileName;
+
+ EFI_STATUS FindStringBlock (
+ IN UINT8 *StringData,
+ IN EFI_STRING_ID StringId,
+ OUT UINT32 *StringTextOffset,
+ OUT UINT8 *BlockType
+ );
+
+ UINT32 GetUnicodeStringTextSize (
+ IN UINT8 *StringSrc
+ );
+
+public:
+ CVfrStringDB ();
+ ~CVfrStringDB ();
+
+ VOID SetStringFileName (
+ IN CHAR8 *StringFileName
+ );
+
+ CHAR8 * GetVarStoreNameFormStringId (
+ IN EFI_STRING_ID StringId
+ );
+
+};
+
#endif
diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 4e2b2e47d2..ff1c4fd82c 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -169,10 +169,17 @@ class WorkspaceAutoGen(AutoGen):
# @param FlashDefinitionFile File of flash definition
# @param Fds FD list to be generated
# @param Fvs FV list to be generated
+ # @param Caps Capsule list to be generated
# @param SkuId SKU id from command line
#
def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,
- BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId='', UniFlag=None):
+ BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None):
+ if Fds is None:
+ Fds = []
+ if Fvs is None:
+ Fvs = []
+ if Caps is None:
+ Caps = []
self.MetaFile = ActivePlatform.MetaFile
self.WorkspaceDir = WorkspaceDir
self.Platform = ActivePlatform
@@ -188,6 +195,7 @@ class WorkspaceAutoGen(AutoGen):
self.FdfFile = FlashDefinitionFile
self.FdTargetList = Fds
self.FvTargetList = Fvs
+ self.CapTargetList = Caps
self.AutoGenObjectList = []
# there's many relative directory operations, so ...
@@ -228,6 +236,11 @@ class WorkspaceAutoGen(AutoGen):
#
self._CheckAllPcdsTokenValueConflict()
+ #
+ # Check PCD type and definition between DSC and DEC
+ #
+ self._CheckPcdDefineAndType()
+
self._BuildDir = None
self._FvDir = None
self._MakeFileDir = None
@@ -235,6 +248,56 @@ class WorkspaceAutoGen(AutoGen):
return True
+ def _CheckPcdDefineAndType(self):
+ PcdTypeList = [
+ "FixedAtBuild", "PatchableInModule", "FeatureFlag",
+ "Dynamic", #"DynamicHii", "DynamicVpd",
+ "DynamicEx", # "DynamicExHii", "DynamicExVpd"
+ ]
+
+ # This dict store PCDs which are not used by any modules with specified arches
+ UnusedPcd = sdict()
+ for Pa in self.AutoGenObjectList:
+ # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid
+ for Pcd in Pa.Platform.Pcds:
+ PcdType = Pa.Platform.Pcds[Pcd].Type
+
+ # If no PCD type, this PCD comes from FDF
+ if not PcdType:
+ continue
+
+ # Try to remove Hii and Vpd suffix
+ if PcdType.startswith("DynamicEx"):
+ PcdType = "DynamicEx"
+ elif PcdType.startswith("Dynamic"):
+ PcdType = "Dynamic"
+
+ for Package in Pa.PackageList:
+ # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType
+ if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:
+ break
+ for Type in PcdTypeList:
+ if (Pcd[0], Pcd[1], Type) in Package.Pcds:
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
+ % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),
+ ExtraData=None
+ )
+ return
+ else:
+ UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)
+
+ for Pcd in UnusedPcd:
+ EdkLogger.warn(
+ 'build',
+ "The PCD was not specified by any INF module in the platform for the given architecture.\n"
+ "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
+ % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),
+ ExtraData=None
+ )
+
def __repr__(self):
return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))
@@ -2125,9 +2188,8 @@ class ModuleAutoGen(AutoGen):
#
def _GetAutoGenFileList(self):
UniStringAutoGenC = True
- UniStringBinBuffer = None
+ UniStringBinBuffer = StringIO()
if self.BuildType == 'UEFI_HII':
- UniStringBinBuffer = StringIO()
UniStringAutoGenC = False
if self._AutoGenFileList == None:
self._AutoGenFileList = {}
diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py
index e6e8847623..4430c94e0b 100644
--- a/BaseTools/Source/Python/AutoGen/GenC.py
+++ b/BaseTools/Source/Python/AutoGen/GenC.py
@@ -1951,6 +1951,9 @@ def CreateHeaderCode(Info, AutoGenC, AutoGenH):
if Info.ModuleType in gModuleTypeHeaderFile \
and gModuleTypeHeaderFile[Info.ModuleType][0] != gBasicHeaderFile:
AutoGenH.Append("#include <%s>\n" % gModuleTypeHeaderFile[Info.ModuleType][0])
+ if 'PcdLib' in Info.Module.LibraryClasses:
+ AutoGenH.Append("#include <Library/PcdLib.h>\n")
+
AutoGenH.Append('\nextern GUID gEfiCallerIdGuid;\n\n')
if Info.IsLibrary:
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 6396c612ad..41a46fc69d 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -1253,7 +1253,7 @@ ${END}\t@cd $(BUILD_DIR)
#
fds: init
\t-@cd $(FV_DIR)
-${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -D ${macro} ${END}
+${BEGIN}\tGenFds -f ${fdf_file} -o $(BUILD_DIR) -t $(TOOLCHAIN) -b $(TARGET) -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}
#
# run command for emulator platform only
@@ -1365,6 +1365,7 @@ ${END}\t@cd $(BUILD_DIR)\n
"active_platform" : str(PlatformInfo),
"fd" : PlatformInfo.FdTargetList,
"fv" : PlatformInfo.FvTargetList,
+ "cap" : PlatformInfo.CapTargetList,
"extra_options" : ExtraOption,
"macro" : MacroList,
}
diff --git a/BaseTools/Source/Python/Common/BuildToolError.py b/BaseTools/Source/Python/Common/BuildToolError.py
index b5dc3712e0..4d4e07bd70 100644
--- a/BaseTools/Source/Python/Common/BuildToolError.py
+++ b/BaseTools/Source/Python/Common/BuildToolError.py
@@ -68,6 +68,8 @@ IO_UNKNOWN_ERROR = 0x6FFF
COMMAND_FAILURE = 0x7000
+PERMISSION_FAILURE = 0x8000
+
CODE_ERROR = 0xC0DE
AUTOGEN_ERROR = 0xF000
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 7498d9e1ee..0540636988 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -252,7 +252,15 @@ def SaveFileOnChange(File, Content, IsBinaryFile=True):
except:
EdkLogger.error(None, FILE_OPEN_FAILURE, ExtraData=File)
- CreateDirectory(os.path.dirname(File))
+ DirName = os.path.dirname(File)
+ if not CreateDirectory(DirName):
+ EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)
+ else:
+ if DirName == '':
+ DirName = os.getcwd()
+ if not os.access(DirName, os.W_OK):
+ EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)
+
try:
if GlobalData.gIsWindows:
try:
@@ -267,8 +275,8 @@ def SaveFileOnChange(File, Content, IsBinaryFile=True):
Fd = open(File, "wb")
Fd.write(Content)
Fd.close()
- except:
- EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData=File)
+ except IOError, X:
+ EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s'%X)
return True
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 733935afe9..5cdbe88889 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -1926,6 +1926,8 @@ class FdfParser:
pass
self.__GetSetStatements(FvObj)
+
+ self.__GetFvBaseAddress(FvObj)
self.__GetFvAlignment(FvObj)
@@ -1979,6 +1981,34 @@ class FdfParser:
raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
Obj.FvAlignment = self.__Token
return True
+
+ ## __GetFvBaseAddress() method
+ #
+ # Get BaseAddress for FV
+ #
+ # @param self The object pointer
+ # @param Obj for whom FvBaseAddress is got
+ # @retval True Successfully find a FvBaseAddress statement
+ # @retval False Not able to find a FvBaseAddress statement
+ #
+ def __GetFvBaseAddress(self, Obj):
+
+ if not self.__IsKeyword("FvBaseAddress"):
+ return False
+
+ if not self.__IsToken( "="):
+ raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
+
+ if not self.__GetNextToken():
+ raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
+
+ IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
+
+ if not IsValidBaseAddrValue.match(self.__Token.upper()):
+ raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
+ Obj.FvBaseAddress = self.__Token
+ return True
+
## __GetFvAttributes() method
#
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
index 2b556135d2..742b2162fe 100644
--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
@@ -53,7 +53,19 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.InDsc = True
self.OptRomDefs = {}
self.PiSpecVersion = '0x00000000'
-
+ self.InfModule = None
+ self.FinalBuildTargetList = []
+
+ ## GetFinalBuildTargetList() method
+ #
+ # Get final build target list
+ def GetFinalBuildTargetList(self):
+ if not self.InfModule or not self.CurrentArch:
+ return []
+ if not self.FinalBuildTargetList:
+ self.FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch)
+ return self.FinalBuildTargetList
+
## __InfParse() method
#
# Parse inf file to get module information
@@ -128,6 +140,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
if Inf._Defs != None and len(Inf._Defs) > 0:
self.OptRomDefs.update(Inf._Defs)
+
+ self.InfModule = Inf
GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)
GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)
diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py
index 7b6305b48e..773b0efbe8 100644
--- a/BaseTools/Source/Python/GenFds/Fv.py
+++ b/BaseTools/Source/Python/GenFds/Fv.py
@@ -46,6 +46,7 @@ class FV (FvClassObject):
self.InfFileName = None
self.FvAddressFileName = None
self.CapsuleName = None
+ self.FvBaseAddress = None
## AddToBuffer()
#
@@ -84,7 +85,10 @@ class FV (FvClassObject):
GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
-
+
+ if self.FvBaseAddress != None:
+ BaseAddress = self.FvBaseAddress
+
self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
#
# First Process the Apriori section
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index 04af6e2c67..9088a876e4 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -239,6 +239,13 @@ def main():
EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
"No such an FV in FDF file: %s" % Options.uiFvName)
+ if (Options.uiCapName) :
+ if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys():
+ GenFds.OnlyGenerateThisCap = Options.uiCapName
+ else:
+ EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
+ "No such a Capsule in FDF file: %s" % Options.uiCapName)
+
"""Modify images from build output if the feature of loading driver at fixed address is on."""
if GenFdsGlobalVariable.FixedLoadAddress:
GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)
@@ -302,7 +309,8 @@ def myOptionParser():
Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
- Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Buld the FV image using the [FV] section named by UiFvName")
+ Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")
+ Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")
Parser.add_option("-b", "--buildtarget", type="choice", choices=['DEBUG','RELEASE'], dest="BuildTarget", help="Build TARGET is one of list: DEBUG, RELEASE.",
action="callback", callback=SingleCheckCallback)
Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
@@ -325,6 +333,7 @@ class GenFds :
ImageBinDict = {}
OnlyGenerateThisFd = None
OnlyGenerateThisFv = None
+ OnlyGenerateThisCap = None
## GenFd()
#
@@ -337,11 +346,18 @@ class GenFds :
GenFdsGlobalVariable.SetDir ('', FdfParser, WorkSpace, ArchList)
GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
+ if GenFds.OnlyGenerateThisCap != None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
+ CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.get(GenFds.OnlyGenerateThisCap.upper())
+ if CapsuleObj != None:
+ CapsuleObj.GenCapsule()
+ return
+
if GenFds.OnlyGenerateThisFd != None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(GenFds.OnlyGenerateThisFd.upper())
if FdObj != None:
FdObj.GenFd()
- elif GenFds.OnlyGenerateThisFd == None:
+ return
+ elif GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisFv == None:
for FdName in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys():
FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[FdName]
FdObj.GenFd()
@@ -361,7 +377,7 @@ class GenFds :
FvObj.AddToBuffer(Buffer)
Buffer.close()
- if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None:
+ if GenFds.OnlyGenerateThisFv == None and GenFds.OnlyGenerateThisFd == None and GenFds.OnlyGenerateThisCap == None:
if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:
GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")
for CapsuleName in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys():
diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
index e9eace9c39..3abaef2023 100644
--- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
+++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
@@ -25,6 +25,12 @@ from Common.BuildToolError import *
from Common import EdkLogger
from Common.Misc import SaveFileOnChange
+from Common.TargetTxtClassObject import TargetTxtClassObject
+from Common.ToolDefClassObject import ToolDefClassObject
+from AutoGen.BuildEngine import BuildRule
+import Common.DataType as DataType
+from Common.Misc import PathClass
+
## Global variables
#
#
@@ -55,8 +61,191 @@ class GenFdsGlobalVariable:
FdfFileTimeStamp = 0
FixedLoadAddress = False
PlatformName = ''
+
+ BuildRuleFamily = "MSFT"
+ ToolChainFamily = "MSFT"
+ __BuildRuleDatabase = None
SectionHeader = struct.Struct("3B 1B")
+
+ ## LoadBuildRule
+ #
+ @staticmethod
+ def __LoadBuildRule():
+ if GenFdsGlobalVariable.__BuildRuleDatabase:
+ return GenFdsGlobalVariable.__BuildRuleDatabase
+ BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
+ TargetTxt = TargetTxtClassObject()
+ if os.path.isfile(BuildConfigurationFile) == True:
+ TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
+ if DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:
+ BuildRuleFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]
+ if BuildRuleFile in [None, '']:
+ BuildRuleFile = 'Conf/build_rule.txt'
+ GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule(BuildRuleFile)
+ ToolDefinitionFile = TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
+ if ToolDefinitionFile == '':
+ ToolDefinitionFile = "Conf/tools_def.txt"
+ if os.path.isfile(ToolDefinitionFile):
+ ToolDef = ToolDefClassObject()
+ ToolDef.LoadToolDefFile(ToolDefinitionFile)
+ ToolDefinition = ToolDef.ToolsDefTxtDatabase
+ if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \
+ and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \
+ and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:
+ GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]
+
+ if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \
+ and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \
+ and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:
+ GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]
+ return GenFdsGlobalVariable.__BuildRuleDatabase
+
+ ## GetBuildRules
+ # @param Inf: object of InfBuildData
+ # @param Arch: current arch
+ #
+ @staticmethod
+ def GetBuildRules(Inf, Arch):
+ if not Arch:
+ Arch = 'COMMON'
+
+ if not Arch in GenFdsGlobalVariable.OutputDirDict:
+ return {}
+
+ BuildRuleDatabase = GenFdsGlobalVariable.__LoadBuildRule()
+ if not BuildRuleDatabase:
+ return {}
+
+ PathClassObj = PathClass(str(Inf.MetaFile).lstrip(GenFdsGlobalVariable.WorkSpaceDir),
+ GenFdsGlobalVariable.WorkSpaceDir)
+ Macro = {}
+ Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir
+ Macro["MODULE_NAME" ] = Inf.BaseName
+ Macro["MODULE_GUID" ] = Inf.Guid
+ Macro["MODULE_VERSION" ] = Inf.Version
+ Macro["MODULE_TYPE" ] = Inf.ModuleType
+ Macro["MODULE_FILE" ] = str(PathClassObj)
+ Macro["MODULE_FILE_BASE_NAME" ] = PathClassObj.BaseName
+ Macro["MODULE_RELATIVE_DIR" ] = PathClassObj.SubDir
+ Macro["MODULE_DIR" ] = PathClassObj.SubDir
+
+ Macro["BASE_NAME" ] = Inf.BaseName
+
+ Macro["ARCH" ] = Arch
+ Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag
+ Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
+ Macro["TARGET" ] = GenFdsGlobalVariable.TargetName
+
+ Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch]
+ Macro["BIN_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
+ Macro["LIB_DIR" ] = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
+ BuildDir = os.path.join(
+ GenFdsGlobalVariable.OutputDirDict[Arch],
+ Arch,
+ PathClassObj.SubDir,
+ PathClassObj.BaseName
+ )
+ Macro["MODULE_BUILD_DIR" ] = BuildDir
+ Macro["OUTPUT_DIR" ] = os.path.join(BuildDir, "OUTPUT")
+ Macro["DEBUG_DIR" ] = os.path.join(BuildDir, "DEBUG")
+
+ BuildRules = {}
+ for Type in BuildRuleDatabase.FileTypeList:
+ #first try getting build rule by BuildRuleFamily
+ RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
+ if not RuleObject:
+ # build type is always module type, but ...
+ if Inf.ModuleType != Inf.BuildType:
+ RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
+ #second try getting build rule by ToolChainFamily
+ if not RuleObject:
+ RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
+ if not RuleObject:
+ # build type is always module type, but ...
+ if Inf.ModuleType != Inf.BuildType:
+ RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
+ if not RuleObject:
+ continue
+ RuleObject = RuleObject.Instantiate(Macro)
+ BuildRules[Type] = RuleObject
+ for Ext in RuleObject.SourceFileExtList:
+ BuildRules[Ext] = RuleObject
+ return BuildRules
+
+ ## GetModuleCodaTargetList
+ #
+ # @param Inf: object of InfBuildData
+ # @param Arch: current arch
+ #
+ @staticmethod
+ def GetModuleCodaTargetList(Inf, Arch):
+ BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
+ if not BuildRules:
+ return []
+
+ TargetList = set()
+ FileList = []
+ for File in Inf.Sources:
+ if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \
+ File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):
+ FileList.append((File, DataType.TAB_UNKNOWN_FILE))
+
+ for File in Inf.Binaries:
+ if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:
+ FileList.append((File, File.Type))
+
+ for File, FileType in FileList:
+ LastTarget = None
+ RuleChain = []
+ SourceList = [File]
+ Index = 0
+ while Index < len(SourceList):
+ Source = SourceList[Index]
+ Index = Index + 1
+
+ if File.IsBinary and File == Source and Inf.Binaries != None and File in Inf.Binaries:
+ # Skip all files that are not binary libraries
+ if not Inf.LibraryClass:
+ continue
+ RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
+ elif FileType in BuildRules:
+ RuleObject = BuildRules[FileType]
+ elif Source.Ext in BuildRules:
+ RuleObject = BuildRules[Source.Ext]
+ else:
+ # stop at no more rules
+ if LastTarget:
+ TargetList.add(str(LastTarget))
+ break
+
+ FileType = RuleObject.SourceFileType
+
+ # stop at STATIC_LIBRARY for library
+ if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
+ if LastTarget:
+ TargetList.add(str(LastTarget))
+ break
+
+ Target = RuleObject.Apply(Source)
+ if not Target:
+ if LastTarget:
+ TargetList.add(str(LastTarget))
+ break
+ elif not Target.Outputs:
+ # Only do build for target with outputs
+ TargetList.add(str(Target))
+
+ # to avoid cyclic rule
+ if FileType in RuleChain:
+ break
+
+ RuleChain.append(FileType)
+ SourceList.extend(Target.Outputs)
+ LastTarget = Target
+ FileType = DataType.TAB_UNKNOWN_FILE
+
+ return list(TargetList)
## SetDir()
#
@@ -459,17 +648,21 @@ class GenFdsGlobalVariable:
PcdValue = ''
for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList:
- PcdDict = Platform.Pcds
- for Key in PcdDict:
- PcdObj = PcdDict[Key]
- if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
- if PcdObj.Type != 'FixedAtBuild':
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
- if PcdObj.DatumType != 'VOID*':
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
-
- PcdValue = PcdObj.DefaultValue
- return PcdValue
+ #
+ # Only process platform which match current build option.
+ #
+ if Platform.MetaFile == GenFdsGlobalVariable.ActivePlatform:
+ PcdDict = Platform.Pcds
+ for Key in PcdDict:
+ PcdObj = PcdDict[Key]
+ if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
+ if PcdObj.Type != 'FixedAtBuild':
+ EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
+ if PcdObj.DatumType != 'VOID*':
+ EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
+
+ PcdValue = PcdObj.DefaultValue
+ return PcdValue
for Package in GenFdsGlobalVariable.WorkSpace.PackageList:
PcdDict = Package.Pcds
diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py
index bfa65c8054..7879a9e29c 100644
--- a/BaseTools/Source/Python/GenFds/Region.py
+++ b/BaseTools/Source/Python/GenFds/Region.py
@@ -216,7 +216,7 @@ class Region(RegionClassObject):
"Size of File (%s) is larger than Region Size 0x%X specified." \
% (RegionData, Size))
GenFdsGlobalVariable.InfLogger(' Region File Name = %s'%RegionData)
- BinFile = open (RegionData, 'r+b')
+ BinFile = open (RegionData, 'rb')
Buffer.write(BinFile.read())
BinFile.close()
Size = Size - FileLength
diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py
index a6d3c6319d..d26f464ab9 100644
--- a/BaseTools/Source/Python/GenFds/Section.py
+++ b/BaseTools/Source/Python/GenFds/Section.py
@@ -139,14 +139,10 @@ class Section (SectionClassObject):
else:
GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName))
- if Suffix != None and os.path.exists(FfsInf.EfiOutputPath):
- # Update to search files with suffix in all sub-dirs.
- Tuple = os.walk(FfsInf.EfiOutputPath)
- for Dirpath, Dirnames, Filenames in Tuple:
- for F in Filenames:
- if os.path.splitext(F)[1] in (Suffix):
- FullName = os.path.join(Dirpath, F)
- FileList.append(FullName)
+ if Suffix != None:
+ for File in FfsInf.GetFinalBuildTargetList():
+ if os.path.splitext(File)[1] in (Suffix):
+ FileList.append(File)
#Process the file lists is alphabetical for a same section type
if len (FileList) > 1:
diff --git a/BaseTools/Source/Python/Makefile b/BaseTools/Source/Python/Makefile
index b3efe538d9..b34b56db07 100644
--- a/BaseTools/Source/Python/Makefile
+++ b/BaseTools/Source/Python/Makefile
@@ -17,12 +17,11 @@
FREEZE=$(PYTHON_FREEZER_PATH)\FreezePython.exe
-MODULES=encodings.cp437,encodings.gbk,encodings.utf_16,encodings.utf_8,encodings.utf_16_le,encodings.latin_1
+MODULES=encodings.cp437,encodings.gbk,encodings.utf_16,encodings.utf_8,encodings.utf_16_le,encodings.latin_1,encodings.ascii
BIN_DIR=$(EDK_TOOLS_PATH)\Bin\Win32
-
-APPLICATIONS=$(BIN_DIR)\build.exe $(BIN_DIR)\GenFds.exe $(BIN_DIR)\Trim.exe $(BIN_DIR)\MigrationMsa2Inf.exe $(BIN_DIR)\Fpd2Dsc.exe $(BIN_DIR)\TargetTool.exe $(BIN_DIR)\spd2dec.exe $(BIN_DIR)\GenDepex.exe $(BIN_DIR)\GenPatchPcdTable.exe $(BIN_DIR)\PatchPcdValue.exe $(BIN_DIR)\BPDG.exe
+APPLICATIONS=$(BIN_DIR)\build.exe $(BIN_DIR)\GenFds.exe $(BIN_DIR)\Trim.exe $(BIN_DIR)\MigrationMsa2Inf.exe $(BIN_DIR)\Fpd2Dsc.exe $(BIN_DIR)\TargetTool.exe $(BIN_DIR)\spd2dec.exe $(BIN_DIR)\GenDepex.exe $(BIN_DIR)\GenPatchPcdTable.exe $(BIN_DIR)\PatchPcdValue.exe $(BIN_DIR)\BPDG.exe $(BIN_DIR)\UPT.exe
COMMON_PYTHON=$(BASE_TOOLS_PATH)\Source\Python\Common\BuildToolError.py \
$(BASE_TOOLS_PATH)\Source\Python\Common\Database.py \
@@ -103,7 +102,10 @@ $(BIN_DIR)\PatchPcdValue.exe: $(BASE_TOOLS_PATH)\Source\Python\PatchPcdValue\Pat
$(BIN_DIR)\BPDG.exe: $(BASE_TOOLS_PATH)\Source\Python\BPDG\BPDG.py $(COMMON_PYTHON)
@pushd . & @cd BPDG & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) BPDG.py & @popd
-
+
+$(BIN_DIR)\UPT.exe: $(BASE_TOOLS_PATH)\Source\Python\UPT\UPT.py $(BASE_TOOLS_PATH)\Source\Python\UPT\UPT.py
+ @pushd . & @cd UPT & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) UPT.py & @popd
+
clean:
cleanall:
@del /f /q $(BIN_DIR)\*.pyd $(BIN_DIR)\*.dll
diff --git a/BaseTools/Source/Python/PackagingTool/DependencyRules.py b/BaseTools/Source/Python/PackagingTool/DependencyRules.py
deleted file mode 100644
index 741736e39d..0000000000
--- a/BaseTools/Source/Python/PackagingTool/DependencyRules.py
+++ /dev/null
@@ -1,185 +0,0 @@
-## @file
-# This file is for installed package information database operations
-#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import sqlite3
-import os
-
-import Common.EdkLogger as EdkLogger
-import IpiDb
-
-(DEPEX_CHECK_SUCCESS, DEPEX_CHECK_MODULE_NOT_FOUND, \
-DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3)
-
-## IpiDb
-#
-# This class represents the installed package information database
-# Add/Remove/Get installed distribution package information here.
-#
-#
-# @param object: Inherited from object class
-# @param DbPath: A string for the path of the database
-#
-# @var Conn: Connection of the database
-# @var Cur: Cursor of the connection
-#
-class DependencyRules(object):
- def __init__(self, Db):
- self.IpiDb = Db
-
- ## Check whether a module exists in current workspace.
- #
- # @param Guid:
- # @param Version:
- #
- def CheckModuleExists(self, Guid, Version, ReturnCode = DEPEX_CHECK_SUCCESS):
- EdkLogger.verbose("\nCheck module exists in workspace started ...")
- ModuleList = []
- ModuleList = self.IpiDb.GetModInPackage(Guid, Version)
- ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version))
- EdkLogger.verbose("Check module exists in workspace ... DONE!")
- if len(ModuleList) > 0:
- return True
- else:
- ReturnCode = DEPEX_CHECK_MODULE_NOT_FOUND
- return False
-
-
- ## Check whether a module depex satisfied by current workspace.
- #
- # @param ModuleObj:
- # @param DpObj:
- #
- def CheckModuleDepexSatisfied(self, ModuleObj, DpObj = None, ReturnCode = DEPEX_CHECK_SUCCESS):
- EdkLogger.verbose("\nCheck module depex met by workspace started ...")
- for Dep in ModuleObj.PackageDependencies:
- Exist = self.CheckPackageExists(Dep.PackageGuid, Dep.PackageVersion, ReturnCode)
- if not Exist:
- if DpObj == None:
- ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
- return False
- for GuidVerPair in DpObj.PackageSurfaceArea.keys():
- if Dep.PackageGuid == GuidVerPair[0]:
- if Dep.PackageVersion == None or len(Dep.PackageVersion) == 0:
- break
- if Dep.PackageVersion == GuidVerPair[1]:
- break
- else:
- ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
- return False
- else:
- ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
- return False
- return True
-
- EdkLogger.verbose("Check module depex met by workspace ... DONE!")
-
- ## Check whether a package exists in current workspace.
- #
- # @param Guid:
- # @param Version:
- #
- def CheckPackageExists(self, Guid, Version, ReturnCode = DEPEX_CHECK_SUCCESS):
- EdkLogger.verbose("\nCheck package exists in workspace started ...")
- PkgList = []
- PkgList = self.IpiDb.GetPackage(Guid, Version)
- if len(PkgList) > 0:
- return True
- else:
- ReturnCode = DEPEX_CHECK_PACKAGE_NOT_FOUND
- return False
-
- EdkLogger.verbose("Check package exists in workspace ... DONE!")
-
- ## Check whether a package depex satisfied by current workspace.
- #
- # @param ModuleObj:
- # @param DpObj:
- #
- def CheckPackageDepexSatisfied(self, PkgObj, DpObj = None, ReturnCode = DEPEX_CHECK_SUCCESS):
-
- for ModKey in PkgObj.Modules.keys():
- ModObj = PkgObj.Modules[ModKey]
- if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
- continue
- else:
- return False
- return True
-
- ## Check whether a DP exists in current workspace.
- #
- # @param Guid:
- # @param Version:
- #
- def CheckDpExists(self, Guid, Version, ReturnCode = DEPEX_CHECK_SUCCESS):
- EdkLogger.verbose("\nCheck DP exists in workspace started ...")
- DpList = []
- DpList = self.IpiDb.GetDp(Guid, Version)
- if len(DpList) > 0:
- return True
- else:
- ReturnCode = DEPEX_CHECK_DP_NOT_FOUND
- return False
-
- EdkLogger.verbose("Check DP exists in workspace ... DONE!")
-
- ## Check whether a DP depex satisfied by current workspace.
- #
- # @param ModuleObj:
- # @param DpObj:
- #
- def CheckDpDepexSatisfied(self, DpObj, ReturnCode = DEPEX_CHECK_SUCCESS):
-
- for PkgKey in DpObj.PackageSurfaceArea.keys():
- PkgObj = DpObj.PackageSurfaceArea[PkgKey]
- if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):
- continue
- else:
- return False
-
- for ModKey in DpObj.ModuleSurfaceArea.keys():
- ModObj = PkgObj.ModuleSurfaceArea[ModKey]
- if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
- continue
- else:
- return False
-
- return True
-
- ## Check whether a DP depex satisfied by current workspace.
- #
- # @param ModuleObj:
- # @param DpObj:
- #
- def CheckDpDepexForRemove(self, DpGuid, DpVersion, ReturnCode = DEPEX_CHECK_SUCCESS):
-
- # Get mod list that is dependent on pkg installed from this DP.
- ModList = self.IpiDb.GetDpDependentModuleList(DpGuid, DpVersion)
-
- if len(ModList) > 0:
- return False
-
- return True
-##
-#
-# This acts like the main() function for the script, unless it is 'import'ed into another
-# script.
-#
-if __name__ == '__main__':
- EdkLogger.Initialize()
- EdkLogger.SetLevel(EdkLogger.DEBUG_0)
-
-
- \ No newline at end of file
diff --git a/BaseTools/Source/Python/PackagingTool/InstallPkg.py b/BaseTools/Source/Python/PackagingTool/InstallPkg.py
deleted file mode 100644
index 8e4d45da21..0000000000
--- a/BaseTools/Source/Python/PackagingTool/InstallPkg.py
+++ /dev/null
@@ -1,309 +0,0 @@
-## @file
-# Install distribution package.
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import sys
-import glob
-import shutil
-import traceback
-import platform
-from optparse import OptionParser
-
-import Common.EdkLogger as EdkLogger
-from Common.BuildToolError import *
-from Common.Misc import *
-from Common.XmlParser import *
-from Common.InfClassObjectLight import Inf
-from Common.DecClassObjectLight import Dec
-
-from PackageFile import *
-from IpiDb import *
-from DependencyRules import *
-import md5
-
-# Version and Copyright
-VersionNumber = "0.1"
-__version__ = "%prog Version " + VersionNumber
-__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
-
-## Check environment variables
-#
-# Check environment variables that must be set for build. Currently they are
-#
-# WORKSPACE The directory all packages/platforms start from
-# EDK_TOOLS_PATH The directory contains all tools needed by the build
-# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
-#
-# If any of above environment variable is not set or has error, the build
-# will be broken.
-#
-def CheckEnvVariable():
- # check WORKSPACE
- if "WORKSPACE" not in os.environ:
- EdkLogger.error("InstallPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
- ExtraData="WORKSPACE")
-
- WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
- if not os.path.exists(WorkspaceDir):
- EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
- elif ' ' in WorkspaceDir:
- EdkLogger.error("InstallPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
- ExtraData=WorkspaceDir)
- os.environ["WORKSPACE"] = WorkspaceDir
-
-## Parse command line options
-#
-# Using standard Python module optparse to parse command line option of this tool.
-#
-# @retval Opt A optparse.Values object containing the parsed options
-# @retval Args Target of build command
-#
-def MyOptionParser():
- UsageString = "%prog -i <distribution_package> [-t] [-f] [-q | -v] [-h]"
-
- Parser = OptionParser(description=__copyright__,version=__version__,prog="InstallPkg",usage=UsageString)
-
- Parser.add_option("-?", action="help", help="show this help message and exit")
-
- Parser.add_option("-i", "--distribution-package", action="store", type="string", dest="PackageFile",
- help="The distribution package to be installed")
-
- Parser.add_option("-t", "--install-tools", action="store_true", type=None, dest="Tools",
- help="Specify it to install tools or ignore the tools of the distribution package.")
-
- Parser.add_option("-f", "--misc-files", action="store_true", type=None, dest="MiscFiles",
- help="Specify it to install misc file or ignore the misc files of the distribution package.")
-
- Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
- help="Disable all messages except FATAL ERRORS.")
-
- Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
- help="Turn on verbose output")
-
- Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
- help="Enable debug messages at specified level.")
-
- Parser.set_defaults(LogLevel=EdkLogger.INFO)
-
- (Opt, Args)=Parser.parse_args()
-
- return Opt
-
-def InstallNewPackage(WorkspaceDir, Path):
- FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
- if os.path.exists(FullPath):
- print "Directory [%s] already exists, please select another location, press [Enter] with no input to quit:" %Path
- Input = sys.stdin.readline()
- Input = Input.replace('\r', '').replace('\n', '')
- if Input == '':
- EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "User interrupt")
- Input = Input.replace('\r', '').replace('\n', '')
- return InstallNewPackage(WorkspaceDir, Input)
- else:
- return Path
-
-def InstallNewFile(WorkspaceDir, File):
- FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
- if os.path.exists(FullPath):
- print "File [%s] already exists, please select another path, press [Enter] with no input to quit:" %File
- Input = sys.stdin.readline()
- Input = Input.replace('\r', '').replace('\n', '')
- if Input == '':
- EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "User interrupt")
- Input = Input.replace('\r', '').replace('\n', '')
- return InstallNewFile(WorkspaceDir, Input)
- else:
- return File
-
-## Tool entrance method
-#
-# This method mainly dispatch specific methods per the command line options.
-# If no error found, return zero value so the caller of this tool can know
-# if it's executed successfully or not.
-#
-# @retval 0 Tool was successful
-# @retval 1 Tool failed
-#
-def Main():
- EdkLogger.Initialize()
- Options = None
- DistFileName = 'dist.pkg'
- ContentFileName = 'content.zip'
- DistFile, ContentZipFile, UnpackDir = None, None, None
-
- Options = MyOptionParser()
- try:
- if Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.SetLevel(Options.LogLevel + 1)
- else:
- EdkLogger.SetLevel(Options.LogLevel)
-
- CheckEnvVariable()
- WorkspaceDir = os.environ["WORKSPACE"]
- if not Options.PackageFile:
- EdkLogger.error("InstallPkg", OPTION_NOT_SUPPORTED, ExtraData="Must specify one distribution package")
-
- # unzip dist.pkg file
- EdkLogger.quiet("Unzipping and parsing distribution package XML file ... ")
- DistFile = PackageFile(Options.PackageFile)
- UnpackDir = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))
- DistPkgFile = DistFile.UnpackFile(DistFileName, os.path.normpath(os.path.join(UnpackDir, DistFileName)))
- if not DistPkgFile:
- EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "File [%s] is broken in distribution package" %DistFileName)
-
- # Generate distpkg
- DistPkgObj = DistributionPackageXml()
- DistPkg = DistPkgObj.FromXml(DistPkgFile)
-
- # prepare check dependency
- Db = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db")))
- Db.InitDatabase()
- Dep = DependencyRules(Db)
-
- # Check distribution package exist
- if Dep.CheckDpExists(DistPkg.Header.Guid, DistPkg.Header.Version):
- EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "This distribution package has been installed", ExtraData=DistPkg.Header.Name)
-
- # unzip contents.zip file
- ContentFile = DistFile.UnpackFile(ContentFileName, os.path.normpath(os.path.join(UnpackDir, ContentFileName)))
- ContentZipFile = PackageFile(ContentFile)
- if not ContentFile:
- EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "File [%s] is broken in distribution package" %ContentFileName)
-
- # verify MD5 signature
- Md5Sigature = md5.new(open(ContentFile).read())
- if DistPkg.Header.Signature != Md5Sigature.hexdigest():
- EdkLogger.error("InstallPkg", FILE_CHECKSUM_FAILURE, ExtraData=ContentFile)
-
- # Check package exist and install
- for Guid,Version,Path in DistPkg.PackageSurfaceArea:
- PackagePath = os.path.dirname(Path)
- NewPackagePath = PackagePath
- Package = DistPkg.PackageSurfaceArea[Guid,Version,Path]
- EdkLogger.info("Installing package ... %s" % Package.PackageHeader.Name)
- if Dep.CheckPackageExists(Guid, Version):
- EdkLogger.quiet("Package [%s] has been installed" %Path)
- NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath)
- Package.FileList = []
- for Item in Package.MiscFiles.Files:
- FromFile = os.path.join(PackagePath, Item.Filename)
- ToFile = os.path.normpath(os.path.join(WorkspaceDir, NewPackagePath, Item.Filename))
- ContentZipFile.UnpackFile(FromFile, ToFile)
- Package.FileList.append(ToFile)
-
- # Update package
- Package.PackageHeader.CombinePath = Package.PackageHeader.CombinePath.replace(PackagePath, NewPackagePath, 1)
- # Update modules of package
- Module = None
- for ModuleGuid, ModuleVersion, ModulePath in Package.Modules:
- Module = Package.Modules[ModuleGuid, ModuleVersion, ModulePath]
- NewModulePath = ModulePath.replace(PackagePath, NewPackagePath, 1)
- del Package.Modules[ModuleGuid, ModuleVersion, ModulePath]
- Package.Modules[ModuleGuid, ModuleVersion, NewModulePath] = Module
- del DistPkg.PackageSurfaceArea[Guid,Version,Path]
- DistPkg.PackageSurfaceArea[Guid,Version,Package.PackageHeader.CombinePath] = Package
-
-# SaveFileOnChange(os.path.join(Options.InstallDir, ModulePath, Module.Header.Name, ".inf"), Inf.ModuleToInf(Module), False)
-# EdkLogger.info("Installing package ... %s" % Package.Header.Name)
-# shutil.copytree(os.path.join(ContentFileDir, Path), Options.InstallDir)
-# SaveFileOnChange(os.path.join(Options.InstallDir, Path, Package.Header.Name, ".dec"), Dec.PackageToDec(Package), False)
-
- # Check module exist and install
- Module = None
- for Guid,Version,Path in DistPkg.ModuleSurfaceArea:
- ModulePath = os.path.dirname(Path)
- NewModulePath = ModulePath
- Module = DistPkg.ModuleSurfaceArea[Guid,Version,Path]
- EdkLogger.info("Installing module ... %s" % Module.ModuleHeader.Name)
- if Dep.CheckModuleExists(Guid, Version):
- EdkLogger.quiet("Module [%s] has been installed" %Path)
- NewModulePath = InstallNewPackage(WorkspaceDir, ModulePath)
- Module.FileList = []
- for Item in Module.MiscFiles.Files:
- ModulePath = ModulePath[os.path.normpath(ModulePath).rfind(os.path.normpath('/'))+1:]
- FromFile = os.path.join(ModulePath, Item.Filename)
- ToFile = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath, Item.Filename))
- ContentZipFile.UnpackFile(FromFile, ToFile)
- Module.FileList.append(ToFile)
-
-# EdkLogger.info("Installing module ... %s" % Module.Header.Name)
-# shutil.copytree(os.path.join(ContentFileDir, Path), Options.InstallDir)
-# SaveFileOnChange(os.path.join(Options.InstallDir, Path, Module.Header.Name, ".inf"), Inf.ModuleToInf(Module), False)
-
- # Update module
- Module.ModuleHeader.CombinePath = Module.ModuleHeader.CombinePath.replace(os.path.dirname(Path), NewModulePath, 1)
- del DistPkg.ModuleSurfaceArea[Guid,Version,Path]
- DistPkg.ModuleSurfaceArea[Guid,Version,Module.ModuleHeader.CombinePath] = Module
-#
-#
-# for Guid,Version,Path in DistPkg.PackageSurfaceArea:
-# print Guid,Version,Path
-# for item in DistPkg.PackageSurfaceArea[Guid,Version,Path].FileList:
-# print item
-# for Guid,Version,Path in DistPkg.ModuleSurfaceArea:
-# print Guid,Version,Path
-# for item in DistPkg.ModuleSurfaceArea[Guid,Version,Path].FileList:
-# print item
-
- if Options.Tools:
- EdkLogger.info("Installing tools ... ")
- for File in DistPkg.Tools.Files:
- FromFile = File.Filename
- ToFile = InstallNewFile(WorkspaceDir, FromFile)
- ContentZipFile.UnpackFile(FromFile, ToFile)
- if Options.MiscFiles:
- EdkLogger.info("Installing misc files ... ")
- for File in DistPkg.MiscellaneousFiles.Files:
- FromFile = File.Filename
- ToFile = InstallNewFile(WorkspaceDir, FromFile)
- ContentZipFile.UnpackFile(FromFile, ToFile)
-
- # update database
- EdkLogger.quiet("Update Distribution Package Database ...")
- Db.AddDPObject(DistPkg)
-
- except FatalError, X:
- if Options and Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- ReturnCode = X.args[0]
- except KeyboardInterrupt:
- ReturnCode = ABORT_ERROR
- if Options and Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- except:
- EdkLogger.error(
- "\nInstallPkg",
- CODE_ERROR,
- "Unknown fatal error when installing [%s]" % Options.PackageFile,
- ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
- RaiseError=False
- )
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- ReturnCode = CODE_ERROR
- finally:
- EdkLogger.quiet("Removing temp files ... ")
- if DistFile:
- DistFile.Close()
- if ContentZipFile:
- ContentZipFile.Close()
- if UnpackDir:
- shutil.rmtree(UnpackDir)
-
- EdkLogger.quiet("DONE")
- Progressor.Abort()
-
-if __name__ == '__main__':
- sys.exit(Main())
diff --git a/BaseTools/Source/Python/PackagingTool/IpiDb.py b/BaseTools/Source/Python/PackagingTool/IpiDb.py
deleted file mode 100644
index 6da3e18975..0000000000
--- a/BaseTools/Source/Python/PackagingTool/IpiDb.py
+++ /dev/null
@@ -1,629 +0,0 @@
-## @file
-# This file is for installed package information database operations
-#
-# Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import sqlite3
-import os
-import time
-import Common.EdkLogger as EdkLogger
-
-from CommonDataClass import DistributionPackageClass
-
-## IpiDb
-#
-# This class represents the installed package information databse
-# Add/Remove/Get installed distribution package information here.
-#
-#
-# @param object: Inherited from object class
-# @param DbPath: A string for the path of the database
-#
-# @var Conn: Connection of the database
-# @var Cur: Cursor of the connection
-#
-class IpiDatabase(object):
- def __init__(self, DbPath):
- Dir = os.path.dirname(DbPath)
- if not os.path.isdir(Dir):
- os.mkdir(Dir)
- self.Conn = sqlite3.connect(DbPath, isolation_level = 'DEFERRED')
- self.Conn.execute("PRAGMA page_size=4096")
- self.Conn.execute("PRAGMA synchronous=OFF")
- self.Cur = self.Conn.cursor()
- self.DpTable = 'DpInfo'
- self.PkgTable = 'PkgInfo'
- self.ModInPkgTable = 'ModInPkgInfo'
- self.StandaloneModTable = 'StandaloneModInfo'
- self.ModDepexTable = 'ModDepexInfo'
- self.DpFileListTable = 'DpFileListInfo'
-
- ## Initialize build database
- #
- #
- def InitDatabase(self):
- EdkLogger.verbose("\nInitialize IPI database started ...")
-
- #
- # Create new table
- #
- SqlCommand = """create table IF NOT EXISTS %s (DpGuid TEXT NOT NULL,
- DpVersion TEXT NOT NULL,
- InstallTime REAL NOT NULL,
- PkgFileName TEXT,
- PRIMARY KEY (DpGuid, DpVersion)
- )""" % self.DpTable
- self.Cur.execute(SqlCommand)
-
- SqlCommand = """create table IF NOT EXISTS %s (FilePath TEXT NOT NULL,
- DpGuid TEXT,
- DpVersion TEXT,
- PRIMARY KEY (FilePath)
- )""" % self.DpFileListTable
- self.Cur.execute(SqlCommand)
-
- SqlCommand = """create table IF NOT EXISTS %s (PackageGuid TEXT NOT NULL,
- PackageVersion TEXT NOT NULL,
- InstallTime REAL NOT NULL,
- DpGuid TEXT,
- DpVersion TEXT,
- InstallPath TEXT NOT NULL,
- PRIMARY KEY (PackageGuid, PackageVersion, InstallPath)
- )""" % self.PkgTable
- self.Cur.execute(SqlCommand)
-
- SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL,
- ModuleVersion TEXT NOT NULL,
- InstallTime REAL NOT NULL,
- PackageGuid TEXT,
- PackageVersion TEXT,
- InstallPath TEXT NOT NULL,
- PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
- )""" % self.ModInPkgTable
- self.Cur.execute(SqlCommand)
-
- SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL,
- ModuleVersion TEXT NOT NULL,
- InstallTime REAL NOT NULL,
- DpGuid TEXT,
- DpVersion TEXT,
- InstallPath TEXT NOT NULL,
- PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
- )""" % self.StandaloneModTable
- self.Cur.execute(SqlCommand)
-
- SqlCommand = """create table IF NOT EXISTS %s (ModuleGuid TEXT NOT NULL,
- ModuleVersion TEXT NOT NULL,
- InstallPath TEXT NOT NULL,
- DepexGuid TEXT,
- DepexVersion TEXT
- )""" % self.ModDepexTable
- self.Cur.execute(SqlCommand)
-
- self.Conn.commit()
-
- EdkLogger.verbose("Initialize IPI database ... DONE!")
-
- ## Add a distribution install information from DpObj
- #
- # @param DpObj:
- #
- def AddDPObject(self, DpObj):
-
- for PkgKey in DpObj.PackageSurfaceArea.keys():
- PkgGuid = PkgKey[0]
- PkgVersion = PkgKey[1]
- PkgInstallPath = PkgKey[2]
- self.AddPackage(PkgGuid, PkgVersion, DpObj.Header.Guid, DpObj.Header.Version, PkgInstallPath)
- PkgObj = DpObj.PackageSurfaceArea[PkgKey]
- for ModKey in PkgObj.Modules.keys():
- ModGuid = ModKey[0]
- ModVersion = ModKey[1]
- ModInstallPath = ModKey[2]
- self.AddModuleInPackage(ModGuid, ModVersion, PkgGuid, PkgVersion, ModInstallPath)
- ModObj = PkgObj.Modules[ModKey]
- for Dep in ModObj.PackageDependencies:
- DepexGuid = Dep.PackageGuid
- DepexVersion = Dep.PackageVersion
- self.AddModuleDepex(ModGuid, ModVersion, ModInstallPath, DepexGuid, DepexVersion)
- for FilePath in PkgObj.FileList:
- self.AddDpFilePathList(DpObj.Header.Guid, DpObj.Header.Version, FilePath)
-
- for ModKey in DpObj.ModuleSurfaceArea.keys():
- ModGuid = ModKey[0]
- ModVersion = ModKey[1]
- ModInstallPath = ModKey[2]
- self.AddStandaloneModule(ModGuid, ModVersion, DpObj.Header.Guid, DpObj.Header.Version, ModInstallPath)
- ModObj = DpObj.ModuleSurfaceArea[ModKey]
- for Dep in ModObj.PackageDependencies:
- DepexGuid = Dep.PackageGuid
- DepexVersion = Dep.PackageVersion
- self.AddModuleDepex(ModGuid, ModVersion, ModInstallPath, DepexGuid, DepexVersion)
- for FilePath in ModObj.FileList:
- self.AddDpFilePathList(DpObj.Header.Guid, DpObj.Header.Version, FilePath)
-
- self.AddDp(DpObj.Header.Guid, DpObj.Header.Version, DpObj.Header.FileName)
- ## Add a distribution install information
- #
- # @param Guid:
- # @param Version:
- # @param PkgFileName:
- #
- def AddDp(self, Guid, Version, PkgFileName = None):
-
- if Version == None or len(Version.strip()) == 0:
- Version = 'N/A'
-
- #
- # Add newly installed DP information to DB.
- #
- if PkgFileName == None or len(PkgFileName.strip()) == 0:
- PkgFileName = 'N/A'
- (Guid, Version, PkgFileName) = (Guid, Version, PkgFileName)
- CurrentTime = time.time()
- SqlCommand = """insert into %s values('%s', '%s', %s, '%s')""" % (self.DpTable, Guid, Version, CurrentTime, PkgFileName)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- ## Add a file list from DP
- #
- # @param DpGuid:
- # @param DpVersion:
- # @param Path
- #
- def AddDpFilePathList(self, DpGuid, DpVersion, Path):
-
- SqlCommand = """insert into %s values('%s', '%s', '%s')""" % (self.DpFileListTable, Path, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- ## Add a package install information
- #
- # @param Guid:
- # @param Version:
- # @param DpGuid:
- # @param DpVersion:
- # @param Path
- #
- def AddPackage(self, Guid, Version, DpGuid = None, DpVersion = None, Path = ''):
-
- if Version == None or len(Version.strip()) == 0:
- Version = 'N/A'
-
- if DpGuid == None or len(DpGuid.strip()) == 0:
- DpGuid = 'N/A'
-
- if DpVersion == None or len(DpVersion.strip()) == 0:
- DpVersion = 'N/A'
-
- #
- # Add newly installed package information to DB.
- #
-
- CurrentTime = time.time()
- SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.PkgTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- ## Add a module that from a package install information
- #
- # @param Guid:
- # @param Version:
- # @param PkgFileName:
- #
- def AddModuleInPackage(self, Guid, Version, PkgGuid = None, PkgVersion = None, Path = ''):
-
- if Version == None or len(Version.strip()) == 0:
- Version = 'N/A'
-
- if PkgGuid == None or len(PkgGuid.strip()) == 0:
- PkgGuid = 'N/A'
-
- if PkgVersion == None or len(PkgVersion.strip()) == 0:
- PkgVersion = 'N/A'
-
- #
- # Add module from package information to DB.
- #
- CurrentTime = time.time()
- SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.ModInPkgTable, Guid, Version, CurrentTime, PkgGuid, PkgVersion, Path)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- ## Add a module that is standalone install information
- #
- # @param Guid:
- # @param Version:
- # @param PkgFileName:
- #
- def AddStandaloneModule(self, Guid, Version, DpGuid = None, DpVersion = None, Path = ''):
-
- if Version == None or len(Version.strip()) == 0:
- Version = 'N/A'
-
- if DpGuid == None or len(DpGuid.strip()) == 0:
- DpGuid = 'N/A'
-
- if DpVersion == None or len(DpVersion.strip()) == 0:
- DpVersion = 'N/A'
-
- #
- # Add module standalone information to DB.
- #
- CurrentTime = time.time()
- SqlCommand = """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % (self.StandaloneModTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- ## Add a module depex
- #
- # @param Guid:
- # @param Version:
- # @param DepexGuid:
- # @param DepexVersion:
- #
- def AddModuleDepex(self, Guid, Version, Path, DepexGuid = None, DepexVersion = None):
-
- if DepexGuid == None or len(DepexGuid.strip()) == 0:
- DepexGuid = 'N/A'
-
- if DepexVersion == None or len(DepexVersion.strip()) == 0:
- DepexVersion = 'N/A'
-
- #
- # Add module depex information to DB.
- #
-
- SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s')""" % (self.ModDepexTable, Guid, Version, Path, DepexGuid, DepexVersion)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- ## Remove a distribution install information, if no version specified, remove all DPs with this Guid.
- #
- # @param DpObj:
- #
- def RemoveDpObj(self, DpGuid, DpVersion):
-
- PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
-
- # delete from ModDepex the standalone module's dependency
- SqlCommand = """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
- (select ModuleGuid from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s')
- and ModDepexInfo.ModuleVersion in
- (select ModuleVersion from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s')
- and ModDepexInfo.InstallPath in
- (select InstallPath from StandaloneModInfo as B where B.DpGuid = '%s' and B.DpVersion = '%s') """ \
- %(DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion)
-
-# SqlCommand = """delete from %s where %s.DpGuid ='%s' and %s.DpVersion = '%s' and
-# %s.ModuleGuid = %s.ModuleGuid and %s.ModuleVersion = %s.ModuleVersion and
-# %s.InstallPath = %s.InstallPath""" \
-# % (self.ModDepexTable, self.StandaloneModTable, DpGuid, self.StandaloneModTable, DpVersion, self.ModDepexTable, self.StandaloneModTable, self.ModDepexTable, self.StandaloneModTable, self.ModDepexTable, self.StandaloneModTable)
-# print SqlCommand
- self.Cur.execute(SqlCommand)
-
- # delete from ModDepex the from pkg module's dependency
- for Pkg in PkgList:
-# SqlCommand = """delete from %s where %s.PackageGuid ='%s' and %s.PackageVersion = '%s' and
-# %s.ModuleGuid = %s.ModuleGuid and %s.ModuleVersion = %s.ModuleVersion and
-# %s.InstallPath = %s.InstallPath""" \
-# % (self.ModDepexTable, self.ModInPkgTable, Pkg[0], self.ModInPkgTable, Pkg[1], self.ModDepexTable, self.ModInPkgTable, self.ModDepexTable, self.ModInPkgTable, self.ModDepexTable, self.ModInPkgTable)
- SqlCommand = """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
- (select ModuleGuid from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')
- and ModDepexInfo.ModuleVersion in
- (select ModuleVersion from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')
- and ModDepexInfo.InstallPath in
- (select InstallPath from ModInPkgInfo where ModInPkgInfo.PackageGuid ='%s' and ModInPkgInfo.PackageVersion = '%s')""" \
- % (Pkg[0], Pkg[1],Pkg[0], Pkg[1],Pkg[0], Pkg[1])
-
- self.Cur.execute(SqlCommand)
-
- # delete the standalone module
- SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.StandaloneModTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- # delete the from pkg module
- for Pkg in PkgList:
- SqlCommand = """delete from %s where %s.PackageGuid ='%s' and %s.PackageVersion = '%s'""" \
- % (self.ModInPkgTable, self.ModInPkgTable, Pkg[0], self.ModInPkgTable, Pkg[1])
- self.Cur.execute(SqlCommand)
-
- # delete packages
- SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.PkgTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- # delete file list from DP
- SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpFileListTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- # delete DP
- SqlCommand = """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- self.Conn.commit()
-
- ## Get a list of distribution install information.
- #
- # @param Guid:
- # @param Version:
- #
- def GetDp(self, Guid, Version):
-
- if Version == None or len(Version.strip()) == 0:
- Version = 'N/A'
- EdkLogger.verbose("\nGetting list of DP install information started ...")
- (DpGuid, DpVersion) = (Guid, Version)
- SqlCommand = """select * from %s where DpGuid ='%s'""" % (self.DpTable, DpGuid)
- self.Cur.execute(SqlCommand)
-
- else:
- EdkLogger.verbose("\nGetting DP install information started ...")
- (DpGuid, DpVersion) = (Guid, Version)
- SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- DpList = []
- for DpInfo in self.Cur:
- DpGuid = DpInfo[0]
- DpVersion = DpInfo[1]
- InstallTime = DpInfo[2]
- PkgFileName = DpInfo[3]
- DpList.append((DpGuid, DpVersion, InstallTime, PkgFileName))
-
- EdkLogger.verbose("Getting DP install information ... DONE!")
- return DpList
-
- ## Get a list of distribution install file path information.
- #
- # @param Guid:
- # @param Version:
- #
- def GetDpFileList(self, Guid, Version):
-
- (DpGuid, DpVersion) = (Guid, Version)
- SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % (self.DpFileListTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- PathList = []
- for Result in self.Cur:
- Path = Result[0]
- PathList.append(Path)
-
- return PathList
-
- ## Get a list of package information.
- #
- # @param Guid:
- # @param Version:
- #
- def GetPackage(self, Guid, Version, DpGuid = '', DpVersion = ''):
-
- if DpVersion == '' or DpGuid == '':
-
- (PackageGuid, PackageVersion) = (Guid, Version)
- SqlCommand = """select * from %s where PackageGuid ='%s' and PackageVersion = '%s'""" % (self.PkgTable, PackageGuid, PackageVersion)
- self.Cur.execute(SqlCommand)
-
- elif Version == None or len(Version.strip()) == 0:
-
- SqlCommand = """select * from %s where PackageGuid ='%s'""" % (self.PkgTable, Guid)
- self.Cur.execute(SqlCommand)
- else:
- (PackageGuid, PackageVersion) = (Guid, Version)
- SqlCommand = """select * from %s where PackageGuid ='%s' and PackageVersion = '%s'
- and DpGuid = '%s' and DpVersion = '%s'""" % (self.PkgTable, PackageGuid, PackageVersion, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- PkgList = []
- for PkgInfo in self.Cur:
- PkgGuid = PkgInfo[0]
- PkgVersion = PkgInfo[1]
- InstallTime = PkgInfo[2]
- InstallPath = PkgInfo[5]
- PkgList.append((PkgGuid, PkgVersion, InstallTime, DpGuid, DpVersion, InstallPath))
-
- return PkgList
-
- ## Get a list of module in package information.
- #
- # @param Guid:
- # @param Version:
- #
- def GetModInPackage(self, Guid, Version, PkgGuid = '', PkgVersion = ''):
-
- if PkgVersion == '' or PkgGuid == '':
-
- (ModuleGuid, ModuleVersion) = (Guid, Version)
- SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s'""" % (self.ModInPkgTable, ModuleGuid, ModuleVersion)
- self.Cur.execute(SqlCommand)
-
- else:
- (ModuleGuid, ModuleVersion) = (Guid, Version)
- SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and PackageGuid ='%s' and PackageVersion = '%s'
- """ % (self.ModInPkgTable, ModuleGuid, ModuleVersion, PkgGuid, PkgVersion)
- self.Cur.execute(SqlCommand)
-
- ModList = []
- for ModInfo in self.Cur:
- ModGuid = ModInfo[0]
- ModVersion = ModInfo[1]
- InstallTime = ModInfo[2]
- InstallPath = ModInfo[5]
- ModList.append((ModGuid, ModVersion, InstallTime, PkgGuid, PkgVersion, InstallPath))
-
- return ModList
-
- ## Get a list of module standalone.
- #
- # @param Guid:
- # @param Version:
- #
- def GetStandaloneModule(self, Guid, Version, DpGuid = '', DpVersion = ''):
-
- if DpGuid == '':
-
- (ModuleGuid, ModuleVersion) = (Guid, Version)
- SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s'""" % (self.StandaloneModTable, ModuleGuid, ModuleVersion)
- self.Cur.execute(SqlCommand)
-
- else:
- (ModuleGuid, ModuleVersion) = (Guid, Version)
- SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and DpGuid ='%s' and DpVersion = '%s'
- """ % (self.StandaloneModTable, ModuleGuid, ModuleVersion, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- ModList = []
- for ModInfo in self.Cur:
- ModGuid = ModInfo[0]
- ModVersion = ModInfo[1]
- InstallTime = ModInfo[2]
- InstallPath = ModInfo[5]
- ModList.append((ModGuid, ModVersion, InstallTime, DpGuid, DpVersion, InstallPath))
-
- return ModList
-
- ## Get a list of module information that comes from DP.
- #
- # @param DpGuid:
- # @param DpVersion:
- #
- def GetStandaloneModuleInstallPathListFromDp(self, DpGuid, DpVersion):
-
- PathList = []
- SqlCommand = """select t1.InstallPath from %s t1 where t1.DpGuid ='%s' and t1.DpVersion = '%s'
- """ % (self.StandaloneModTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- for Result in self.Cur:
- InstallPath = Result[0]
- PathList.append(InstallPath)
-
- return PathList
-
- ## Get a list of package information.
- #
- # @param DpGuid:
- # @param DpVersion:
- #
- def GetPackageListFromDp(self, DpGuid, DpVersion):
-
-
- SqlCommand = """select * from %s where DpGuid ='%s' and DpVersion = '%s'
- """ % (self.PkgTable, DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
-
- PkgList = []
- for PkgInfo in self.Cur:
- PkgGuid = PkgInfo[0]
- PkgVersion = PkgInfo[1]
- InstallPath = PkgInfo[5]
- PkgList.append((PkgGuid, PkgVersion, InstallPath))
-
- return PkgList
-
- ## Get a list of modules that depends on package information from a DP.
- #
- # @param DpGuid:
- # @param DpVersion:
- #
- def GetDpDependentModuleList(self, DpGuid, DpVersion):
-
- ModList = []
- PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
- if len(PkgList) > 0:
- return ModList
-
- for Pkg in PkgList:
- SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath
- from %s as t1, %s as t2, where t1.ModuleGuid = t2.ModuleGuid and
- t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s' and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
- t1.PackageGuid != '%s' and t1.PackageVersion != '%s'
- """ % (self.ModInPkgTable, self.ModDepexTable, Pkg[0], Pkg[1], Pkg[0], Pkg[1])
- self.Cur.execute(SqlCommand)
- for ModInfo in self.Cur:
- ModGuid = ModInfo[0]
- ModVersion = ModInfo[1]
- InstallPath = ModInfo[2]
- ModList.append((ModGuid, ModVersion, InstallPath))
-
- SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath
- from %s as t1, %s as t2, where t1.ModuleGuid = t2.ModuleGuid and
- t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s' and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
- t1.DpGuid != '%s' and t1.DpVersion != '%s'
- """ % (self.StandaloneModTable, self.ModDepexTable, Pkg[0], Pkg[1], DpGuid, DpVersion)
- self.Cur.execute(SqlCommand)
- for ModInfo in self.Cur:
- ModGuid = ModInfo[0]
- ModVersion = ModInfo[1]
- InstallPath = ModInfo[2]
- ModList.append((ModGuid, ModVersion, InstallPath))
-
-
- return ModList
-
- ## Get a module depex
- #
- # @param Guid:
- # @param Version:
- # @param Path:
- #
- def GetModuleDepex(self, Guid, Version, Path):
-
- #
- # Get module depex information to DB.
- #
-
- SqlCommand = """select * from %s where ModuleGuid ='%s' and ModuleVersion = '%s' and InstallPath ='%s'
- """ % (self.ModDepexTable, Guid, Version, Path)
- self.Cur.execute(SqlCommand)
- self.Conn.commit()
-
- DepexList = []
- for DepInfo in self.Cur:
- DepexGuid = DepInfo[3]
- DepexVersion = DepInfo[4]
- DepexList.append((DepexGuid, DepexVersion))
-
- return DepexList
-
- ## Close entire database
- #
- # Close the connection and cursor
- #
- def CloseDb(self):
-
- self.Cur.close()
- self.Conn.close()
-
- ## Convert To Sql String
- #
- # 1. Replace "'" with "''" in each item of StringList
- #
- # @param StringList: A list for strings to be converted
- #
- def __ConvertToSqlString(self, StringList):
- return map(lambda s: s.replace("'", "''") , StringList)
-##
-#
-# This acts like the main() function for the script, unless it is 'import'ed into another
-# script.
-#
-if __name__ == '__main__':
- EdkLogger.Initialize()
- EdkLogger.SetLevel(EdkLogger.DEBUG_0)
- DATABASE_PATH = "C://MyWork//Conf//.cache//XML.db"
- Db = IpiDatabase(DATABASE_PATH)
- Db.InitDatabase()
-
- \ No newline at end of file
diff --git a/BaseTools/Source/Python/PackagingTool/MkPkg.py b/BaseTools/Source/Python/PackagingTool/MkPkg.py
deleted file mode 100644
index f6d693d2da..0000000000
--- a/BaseTools/Source/Python/PackagingTool/MkPkg.py
+++ /dev/null
@@ -1,294 +0,0 @@
-## @file
-# Install distribution package.
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import os.path
-import sys
-import glob
-import shutil
-import traceback
-import platform
-from optparse import OptionParser
-import md5
-import time
-import uuid
-
-from PackageFile import *
-import Common.EdkLogger as EdkLogger
-from Common.BuildToolError import *
-from Common.Misc import *
-from Common.XmlParser import *
-from CommonDataClass.DistributionPackageClass import *
-from Common.DecClassObjectLight import Dec
-from Common.InfClassObjectLight import Inf
-
-from PackageFile import *
-
-# Version and Copyright
-VersionNumber = "0.1"
-__version__ = "%prog Version " + VersionNumber
-__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
-
-## Check environment variables
-#
-# Check environment variables that must be set for build. Currently they are
-#
-# WORKSPACE The directory all packages/platforms start from
-# EDK_TOOLS_PATH The directory contains all tools needed by the build
-# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
-#
-# If any of above environment variable is not set or has error, the build
-# will be broken.
-#
-def CheckEnvVariable():
- # check WORKSPACE
- if "WORKSPACE" not in os.environ:
- EdkLogger.error("MkPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
- ExtraData="WORKSPACE")
-
- WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
- if not os.path.exists(WorkspaceDir):
- EdkLogger.error("MkPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
- elif ' ' in WorkspaceDir:
- EdkLogger.error("MkPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
- ExtraData=WorkspaceDir)
- os.environ["WORKSPACE"] = WorkspaceDir
-
-## Parse command line options
-#
-# Using standard Python module optparse to parse command line option of this tool.
-#
-# @retval Opt A optparse.Values object containing the parsed options
-# @retval Args Target of build command
-#
-def MyOptionParser():
- UsageString = "%prog -m <module_file> -p <package_file> [-o distribution_file] " + \
- "[-x xml-file-header] [-t tools-directory] [-f misc-files] [-q | -v] [-h]"
-
- Parser = OptionParser(description=__copyright__,version=__version__,prog="MkPkg",usage=UsageString)
-
- Parser.add_option("-?", action="help", help="show this help message and exit")
-
- Parser.add_option("-o", "--output-file", action="store", type="string", dest="DistributionFile",
- help="Specify the distribution file to be created.")
-
- Parser.add_option("-f", "--misc-files", action="append", type="string", dest="MiscFiles",
- help="Specify any misc files.")
-
- Parser.add_option("-x", "--xml-file-header", action="store", type=None, dest="TemplateFile",
- help="Specify the xml file which includes header information for creating the distribution file.")
-
- Parser.add_option("-t", "--tools-directory", action="store", type=None, dest="ToolsDir",
- help="Specify the directory name of tools.")
-
- Parser.add_option("-m", "--module", action="append", type="string", dest="ModuleFileList",
- help="The inf file of module to be distributed standalone.")
-
- Parser.add_option("-p", "--package", action="append", type="string", dest="PackageFileList",
- help="The dec file of package to be distributed.")
-
- Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
- help="Disable all messages except FATAL ERRORS.")
-
- Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
- help="Turn on verbose output")
-
- Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
- help="Enable debug messages at specified level.")
-
- Parser.set_defaults(LogLevel=EdkLogger.INFO)
-
- (Opt, Args)=Parser.parse_args()
- # error check
- if not Opt.ModuleFileList and not Opt.PackageFileList:
- EdkLogger.error("MkPkg", OPTION_NOT_SUPPORTED, ExtraData="At least one package file or module file must be specified")
- if Opt.TemplateFile:
- if not os.path.exists(Opt.TemplateFile):
- EdkLogger.error(
- "\nMkPkg",
- FILE_NOT_FOUND,
- "Template file [%s] not found" % Opt.TemplateFile
- )
- return Opt
-
-## Tool entrance method
-#
-# This method mainly dispatch specific methods per the command line options.
-# If no error found, return zero value so the caller of this tool can know
-# if it's executed successfully or not.
-#
-# @retval 0 Tool was successful
-# @retval 1 Tool failed
-#
-def Main():
- EdkLogger.Initialize()
- Options = MyOptionParser()
- try:
- if Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.SetLevel(Options.LogLevel + 1)
- else:
- EdkLogger.SetLevel(Options.LogLevel)
-
- CheckEnvVariable()
- WorkspaceDir = os.environ["WORKSPACE"]
-
- # Init DistributionFile
- if not Options.DistributionFile:
- Options.DistributionFile = "DistributionPackage.zip"
-
- # Check Tools Dir
- if Options.ToolsDir:
- if not os.path.isdir(os.path.normpath(os.path.join(WorkspaceDir, Options.ToolsDir))):
- EdkLogger.error(
- "\nMkPkg",
- FILE_NOT_FOUND,
- "Tools directory [%s] not found" % Options.ToolsDir
- )
-
- # Check misc files
- if Options.MiscFiles:
- for Item in Options.MiscFiles:
- FullPath = os.path.normpath(os.path.join(WorkspaceDir, Item))
- if not os.path.isfile(FullPath):
- EdkLogger.error(
- "\nMkPkg",
- FILE_NOT_FOUND,
- "Misc file [%s] not found" % Item
- )
-
- #Check package file existing and valid
- if Options.PackageFileList:
- for Item in Options.PackageFileList:
- (Name, Ext) = os.path.splitext(Item)
- if Ext.upper() != '.DEC':
- EdkLogger.error(
- "\nMkPkg",
- OPTION_VALUE_INVALID,
- "[%s] is not a valid package name" % Item
- )
- Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
- if not os.path.exists(Path):
- EdkLogger.error(
- "\nMkPkg",
- FILE_NOT_FOUND,
- "[%s] not found" % Item
- )
- #Check module file existing and valid
- if Options.ModuleFileList:
- for Item in Options.ModuleFileList:
- (Name, Ext) = os.path.splitext(Item)
- if Ext.upper() != '.INF':
- EdkLogger.error(
- "\nMkPkg",
- OPTION_VALUE_INVALID,
- "[%s] is not a valid module name" % Item
- )
- Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
- if not os.path.exists(Path):
- EdkLogger.error(
- "\nMkPkg",
- FILE_NOT_FOUND,
- "[%s] not found" % Item
- )
-
- ContentFile = PackageFile("content.zip", "w")
- DistPkg = DistributionPackageClass()
- DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, Options.ModuleFileList)
- DistPkgXml = DistributionPackageXml()
- for Item in DistPkg.PackageSurfaceArea:
- ContentFile.Pack(os.path.dirname(os.path.normpath(os.path.join(WorkspaceDir,Item[2]))))
- for Item in DistPkg.ModuleSurfaceArea:
- ContentFile.Pack(os.path.dirname(os.path.normpath(os.path.join(WorkspaceDir,Item[2]))))
-
- # Add tools files and information
- if Options.ToolsDir:
- ToolsFiles = MiscFileClass()
- ToolsRoot = os.path.normpath(os.path.join(WorkspaceDir, Options.ToolsDir))
- ContentFile.Pack(ToolsRoot)
- ToolsFileList = GetFiles(ToolsRoot, ['CVS', '.svn'])
- for Item in ToolsFileList:
- OriPath = Item[len(WorkspaceDir)+1:]
- FileObj = FileClass()
- FileObj.Filename = OriPath
- (Name, Ext) = os.path.splitext(OriPath)
- if Ext.upper() in ['EXE', 'COM', 'EFI']:
- FileObj.Executable = 'True'
- ToolsFiles.Files.append(FileObj)
- DistPkg.Tools = ToolsFiles
-
- # Add misc files and information
- if Options.MiscFiles:
- MiscFiles = MiscFileClass()
- for Item in Options.MiscFiles:
- ContentFile.PackFile(Item)
- FileObj = FileClass()
- FileObj.Filename = Item
- (Name, Ext) = os.path.splitext(Item)
- if Ext.upper() in ['EXE', 'COM', 'EFI']:
- FileObj.Executable = 'True'
- MiscFiles.Files.append(FileObj)
- DistPkg.MiscellaneousFiles = MiscFiles
-
- print "Compressing Distribution Package File ..."
- ContentFile.Close()
-
- # Add temp distribution header
- if Options.TemplateFile:
- TempXML = DistributionPackageXml()
- DistPkg.Header = TempXML.FromXml(Options.TemplateFile).Header
- # Add init dp information
- else:
- DistPkg.Header.Name = 'Distribution Package'
- DistPkg.Header.Guid = str(uuid.uuid4())
- DistPkg.Header.Version = '1.0'
-
- # Add Md5Sigature
- Md5Sigature = md5.new(open(str(ContentFile)).read())
- DistPkg.Header.Signature = Md5Sigature.hexdigest()
- # Add current Date
- DistPkg.Header.Date = str(time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()))
-
- # Finish final dp file
- DistPkgFile = PackageFile(Options.DistributionFile, "w")
- DistPkgFile.PackFile(str(ContentFile))
- DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), "dist.pkg")
- DistPkgFile.Close()
- print "DONE"
-
- except FatalError, X:
- if Options and Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- ReturnCode = X.args[0]
- except KeyboardInterrupt:
- ReturnCode = ABORT_ERROR
- if Options and Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- except:
- EdkLogger.error(
- "\nMkPkg",
- CODE_ERROR,
- "Unknown fatal error when creating [%s]" % Options.DistributionFile,
- ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
- RaiseError=False
- )
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- ReturnCode = CODE_ERROR
- finally:
- Progressor.Abort()
-
-if __name__ == '__main__':
- sys.exit(Main())
-
diff --git a/BaseTools/Source/Python/PackagingTool/PackageFile.py b/BaseTools/Source/Python/PackagingTool/PackageFile.py
deleted file mode 100644
index 6194231441..0000000000
--- a/BaseTools/Source/Python/PackagingTool/PackageFile.py
+++ /dev/null
@@ -1,160 +0,0 @@
-## @file
-#
-# PackageFile class represents the zip file of a distribution package.
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import sys
-import zipfile
-import tempfile
-
-from Common import EdkLogger
-from Common.Misc import *
-from Common.BuildToolError import *
-
-class PackageFile:
- def __init__(self, FileName, Mode="r"):
- self._FileName = FileName
- if Mode not in ["r", "w", "a"]:
- Mode = "r"
- try:
- self._ZipFile = zipfile.ZipFile(FileName, Mode, zipfile.ZIP_DEFLATED)
- self._Files = {}
- for F in self._ZipFile.namelist():
- self._Files[os.path.normpath(F)] = F
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_OPEN_FAILURE,
- ExtraData="%s (%s)" % (FileName, str(X)))
-
- BadFile = self._ZipFile.testzip()
- if BadFile != None:
- EdkLogger.error("PackagingTool", FILE_CHECKSUM_FAILURE,
- ExtraData="[%s] in %s" % (BadFile, FileName))
-
- def __str__(self):
- return self._FileName
-
- def Unpack(self, To):
- for F in self._ZipFile.namelist():
- ToFile = os.path.normpath(os.path.join(To, F))
- print F, "->", ToFile
- self.Extract(F, ToFile)
-
- def UnpackFile(self, File, ToFile):
- File = File.replace('\\', '/')
- if File in self._ZipFile.namelist():
- print File, "->", ToFile
- self.Extract(File, ToFile)
-
- return ToFile
-
- return ''
-
- def Extract(self, Which, To):
- Which = os.path.normpath(Which)
- if Which not in self._Files:
- EdkLogger.error("PackagingTool", FILE_NOT_FOUND,
- ExtraData="[%s] in %s" % (Which, self._FileName))
- try:
- FileContent = self._ZipFile.read(self._Files[Which])
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_DECOMPRESS_FAILURE,
- ExtraData="[%s] in %s (%s)" % (Which, self._FileName, str(X)))
- try:
- CreateDirectory(os.path.dirname(To))
- ToFile = open(To, "wb")
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_OPEN_FAILURE,
- ExtraData="%s (%s)" % (To, str(X)))
-
- try:
- ToFile.write(FileContent)
- ToFile.close()
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_WRITE_FAILURE,
- ExtraData="%s (%s)" % (To, str(X)))
-
- def Remove(self, Files):
- TmpDir = os.path.join(tempfile.gettempdir(), ".packaging")
- if os.path.exists(TmpDir):
- RemoveDirectory(TmpDir, True)
-
- os.mkdir(TmpDir)
- self.Unpack(TmpDir)
- for F in Files:
- F = os.path.normpath(F)
- if F not in self._Files:
- EdkLogger.error("PackagingTool", FILE_NOT_FOUND,
- ExtraData="%s is not in %s!" % (F, self._FileName))
- #os.remove(os.path.join(TmpDir, F)) # no need to really remove file
- self._Files.pop(F)
- self._ZipFile.close()
-
- self._ZipFile = zipfile.ZipFile(self._FileName, "w", zipfile.ZIP_DEFLATED)
- Cwd = os.getcwd()
- os.chdir(TmpDir)
- self.PackFiles(self._Files)
- os.chdir(Cwd)
- RemoveDirectory(TmpDir, True)
-
- def Pack(self, Top):
- if not os.path.isdir(Top):
- EdkLogger.error("PackagingTool", FILE_UNKNOWN_ERROR, "%s is not a directory!" %Top)
-
- FilesToPack = []
- ParentDir = os.path.dirname(Top)
- BaseDir = os.path.basename(Top)
- Cwd = os.getcwd()
- os.chdir(ParentDir)
- for Root, Dirs, Files in os.walk(BaseDir):
- if 'CVS' in Dirs:
- Dirs.remove('CVS')
- if '.svn' in Dirs:
- Dirs.remove('.svn')
- for F in Files:
- FilesToPack.append(os.path.join(Root, F))
- self.PackFiles(FilesToPack)
- os.chdir(Cwd)
-
- def PackFiles(self, Files):
- for F in Files:
- try:
- print "packing ...", F
- self._ZipFile.write(F)
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE,
- ExtraData="%s (%s)" % (F, str(X)))
-
- def PackFile(self, File, ArcName=None):
- try:
- print "packing ...", File
- self._ZipFile.write(File, ArcName)
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE,
- ExtraData="%s (%s)" % (File, str(X)))
-
- def PackData(self, Data, ArcName):
- try:
- self._ZipFile.writestr(ArcName, Data)
- except BaseException, X:
- EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE,
- ExtraData="%s (%s)" % (ArcName, str(X)))
-
- def Close(self):
- self._ZipFile.close()
-
-if __name__ == '__main__':
- pass
-
diff --git a/BaseTools/Source/Python/PackagingTool/RmPkg.py b/BaseTools/Source/Python/PackagingTool/RmPkg.py
deleted file mode 100644
index 38908a331f..0000000000
--- a/BaseTools/Source/Python/PackagingTool/RmPkg.py
+++ /dev/null
@@ -1,218 +0,0 @@
-## @file
-# Install distribution package.
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-
-##
-# Import Modules
-#
-import os
-import sys
-import traceback
-import platform
-from optparse import OptionParser
-
-import Common.EdkLogger as EdkLogger
-from Common.BuildToolError import *
-from Common.Misc import *
-from Common.XmlParser import *
-
-from IpiDb import *
-from DependencyRules import *
-
-# Version and Copyright
-VersionNumber = "0.1"
-__version__ = "%prog Version " + VersionNumber
-__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
-
-## Check environment variables
-#
-# Check environment variables that must be set for build. Currently they are
-#
-# WORKSPACE The directory all packages/platforms start from
-# EDK_TOOLS_PATH The directory contains all tools needed by the build
-# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
-#
-# If any of above environment variable is not set or has error, the build
-# will be broken.
-#
-def CheckEnvVariable():
- # check WORKSPACE
- if "WORKSPACE" not in os.environ:
- EdkLogger.error("RmPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
- ExtraData="WORKSPACE")
-
- WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
- if not os.path.exists(WorkspaceDir):
- EdkLogger.error("RmPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
- elif ' ' in WorkspaceDir:
- EdkLogger.error("RmPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
- ExtraData=WorkspaceDir)
- os.environ["WORKSPACE"] = WorkspaceDir
-
-## Parse command line options
-#
-# Using standard Python module optparse to parse command line option of this tool.
-#
-# @retval Opt A optparse.Values object containing the parsed options
-# @retval Args Target of build command
-#
-def MyOptionParser():
- UsageString = "%prog -g <guid> -n <version> [-y] [-q | -v] [-h]"
-
- Parser = OptionParser(description=__copyright__,version=__version__,prog="RmPkg",usage=UsageString)
-
- Parser.add_option("-?", action="help", help="show this help message and exit")
-
-# Parser.add_option("-f", "--force", action="store_true", type=None, dest="ForceRemove",
-# help="Force creation - overwrite existing one.")
-
- Parser.add_option("-y", "--yes", action="store_true", dest="Yes",
- help="Not asking for confirmation when deleting files.")
-
- Parser.add_option("-n", "--package-version", action="store", type="string", dest="PackageVersion",
- help="The version of distribution package to be removed.")
-
- Parser.add_option("-g", "--package-guid", action="store", type="string", dest="PackageGuid",
- help="The GUID of distribution package to be removed.")
-
- Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
- help="Disable all messages except FATAL ERRORS.")
-
- Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
- help="Turn on verbose output")
-
- Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
- help="Enable debug messages at specified level.")
-
- Parser.set_defaults(LogLevel=EdkLogger.INFO)
-
- (Opt, Args)=Parser.parse_args()
-
- return Opt
-
-## Remove all empty dirs under the path
-def RemoveEmptyDirs(Path):
- # Remove all sub dirs
- for Root, Dirs, Files in os.walk(Path):
- for Dir in Dirs:
- FullPath = os.path.normpath(os.path.join(Root, Dir))
- if os.path.isdir(FullPath):
- if os.listdir(FullPath) == []:
- os.rmdir(FullPath)
- else:
- RemoveEmptyDirs(FullPath)
- # Remove itself
- if os.path.isdir(Path) and os.listdir(Path) == []:
- os.rmdir(Path)
-
-
-## Tool entrance method
-#
-# This method mainly dispatch specific methods per the command line options.
-# If no error found, return zero value so the caller of this tool can know
-# if it's executed successfully or not.
-#
-# @retval 0 Tool was successful
-# @retval 1 Tool failed
-#
-def Main():
- EdkLogger.Initialize()
- Options = MyOptionParser()
- try:
- if not Options.PackageGuid and not Options.PackageVersion:
- EdkLogger.error("RmPkg", OPTION_MISSING, ExtraData="The GUID and Version of distribution package must be specified")
-
- if Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.SetLevel(Options.LogLevel + 1)
- else:
- EdkLogger.SetLevel(Options.LogLevel)
-
- CheckEnvVariable()
- WorkspaceDir = os.environ["WORKSPACE"]
-
- # Prepare check dependency
- Db = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db")))
- Db.InitDatabase()
- Dep = DependencyRules(Db)
-
- Guid = Options.PackageGuid
- Version = Options.PackageVersion
-
- # Check Dp existing
- if not Dep.CheckDpExists(Guid, Version):
- EdkLogger.error("RmPkg", UNKNOWN_ERROR, "This distribution package are not installed!")
-
- # Check Dp depex
- if not Dep.CheckDpDepexForRemove(Guid, Version):
- print "Some packages/modules are depending on this distribution package, do you really want to remove it?"
- print "Press Y to delete all files or press other keys to quit:"
- Input = Input = sys.stdin.readline()
- Input = Input.replace('\r', '').replace('\n', '')
- if Input.upper() != 'Y':
- EdkLogger.error("RmPkg", UNKNOWN_ERROR, "User interrupt")
-
- # Remove all files
- if not Options.Yes:
- print "All files of the distribution package will be removed, do you want to continue?"
- print "Press Y to remove all files or press other keys to quit:"
- Input = Input = sys.stdin.readline()
- Input = Input.replace('\r', '').replace('\n', '')
- if Input.upper() != 'Y':
- EdkLogger.error("RmPkg", UNKNOWN_ERROR, "User interrupt")
-
- # Remove all files
- MissingFileList = []
- for Item in Db.GetDpFileList(Guid, Version):
- if os.path.isfile(Item):
- print "Removing file [%s] ..." % Item
- os.remove(Item)
- else:
- MissingFileList.append(Item)
-
- # Remove all empty dirs of package
- for Item in Db.GetPackageListFromDp(Guid, Version):
- Dir = os.path.dirname(Item[2])
- RemoveEmptyDirs(Dir)
-
- # Remove all empty dirs of module
- for Item in Db.GetStandaloneModuleInstallPathListFromDp(Guid, Version):
- Dir = os.path.dirname(Item)
- RemoveEmptyDirs(Dir)
-
- # update database
- EdkLogger.quiet("Update Distribution Package Database ...")
- Db.RemoveDpObj(Guid, Version)
- EdkLogger.quiet("DONE")
-
- except FatalError, X:
- if Options and Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- ReturnCode = X.args[0]
- except KeyboardInterrupt:
- ReturnCode = ABORT_ERROR
- if Options and Options.LogLevel < EdkLogger.DEBUG_9:
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- except:
- EdkLogger.error(
- "\nRmPkg",
- CODE_ERROR,
- "Unknown fatal error when removing package",
- ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
- RaiseError=False
- )
- EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
- ReturnCode = CODE_ERROR
- finally:
- Progressor.Abort()
-
-if __name__ == '__main__':
- sys.exit(Main())
diff --git a/BaseTools/Source/Python/UPT/Core/DependencyRules.py b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
new file mode 100644
index 0000000000..ac656bb02a
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Core/DependencyRules.py
@@ -0,0 +1,293 @@
+## @file
+# This file is for installed package information database operations
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Dependency
+'''
+
+##
+# Import Modules
+#
+from os import getenv
+from os import environ
+from os.path import dirname
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Library.Parsing import GetWorkspacePackage
+from Library.Parsing import GetWorkspaceModule
+from PomAdapter.InfPomAlignment import InfPomAlignment
+from Logger.ToolError import FatalError
+from Logger.ToolError import EDK1_INF_ERROR
+from Logger.ToolError import UNKNOWN_ERROR
+(DEPEX_CHECK_SUCCESS, DEPEX_CHECK_MODULE_NOT_FOUND, \
+DEPEX_CHECK_PACKAGE_NOT_FOUND, DEPEX_CHECK_DP_NOT_FOUND) = (0, 1, 2, 3)
+
+
+## IpiDb
+#
+# This class represents the installed package information database
+# Add/Remove/Get installed distribution package information here.
+#
+#
+# @param object: Inherited from object class
+#
+class DependencyRules(object):
+ def __init__(self, Datab):
+ self.IpiDb = Datab
+ self.WsPkgList = GetWorkspacePackage()
+ self.WsModuleList = GetWorkspaceModule()
+
+ ## Check whether a module exists in current workspace.
+ #
+ # @param Guid: Guid of a module
+ # @param Version: Version of a module
+ #
+ def CheckModuleExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
+ if ReturnCode:
+ pass
+ Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST)
+ ModuleList = self.IpiDb.GetModInPackage(Guid, Version)
+ ModuleList.extend(self.IpiDb.GetStandaloneModule(Guid, Version))
+ Logger.Verbose(ST.MSG_CHECK_MODULE_EXIST_FINISH)
+ if len(ModuleList) > 0:
+ return True
+ else:
+ return False
+
+ ## Check whether a module depex satisfied by current workspace or dist.
+ #
+ # @param ModuleObj: A module object
+ # @param DpObj: A depex object
+ #
+ def CheckModuleDepexSatisfied(self, ModuleObj, DpObj=None, \
+ ReturnCode=DEPEX_CHECK_SUCCESS):
+ if ReturnCode:
+ pass
+ Logger.Verbose(ST.MSG_CHECK_MODULE_DEPEX_START)
+ Result = True
+ Dep = None
+ if ModuleObj.GetPackageDependencyList():
+ Dep = ModuleObj.GetPackageDependencyList()[0]
+ for Dep in ModuleObj.GetPackageDependencyList():
+ #
+ # first check whether the dependency satisfied by current workspace
+ #
+ Exist = self.CheckPackageExists(Dep.GetGuid(), Dep.GetVersion())
+ #
+ # check whether satisfied by current distribution
+ #
+ if not Exist:
+ if DpObj == None:
+ Result = False
+ break
+ for GuidVerPair in DpObj.PackageSurfaceArea.keys():
+ if Dep.GetGuid() == GuidVerPair[0]:
+ if Dep.GetVersion() == None or \
+ len(Dep.GetVersion()) == 0:
+ Result = True
+ break
+ if Dep.GetVersion() == GuidVerPair[1]:
+ Result = True
+ break
+ else:
+ Result = False
+ break
+
+ if not Result:
+ Logger.Error("CheckModuleDepex", UNKNOWN_ERROR, \
+ ST.ERR_DEPENDENCY_NOT_MATCH % (ModuleObj.GetName(), \
+ Dep.GetPackageFilePath(), \
+ Dep.GetGuid(), \
+ Dep.GetVersion()))
+ return Result
+
+ ## Check whether a package exists in current workspace.
+ #
+ # @param Guid: Guid of a package
+ # @param Version: Version of a package
+ #
+ def CheckPackageExists(self, Guid, Version):
+ Logger.Verbose(ST.MSG_CHECK_PACKAGE_START)
+ for (PkgName, PkgGuid, PkgVer, PkgPath) in self.WsPkgList:
+ if PkgName or PkgPath:
+ pass
+ if (PkgGuid == Guid):
+ #
+ # if version is not empty and not equal, then not match
+ #
+ if Version and (PkgVer != Version):
+ return False
+ else:
+ return True
+ else:
+ return False
+
+ Logger.Verbose(ST.MSG_CHECK_PACKAGE_FINISH)
+
+ ## Check whether a package depex satisfied by current workspace.
+ #
+ # @param PkgObj: A package object
+ # @param DpObj: A package depex object
+ #
+ def CheckPackageDepexSatisfied(self, PkgObj, DpObj=None, \
+ ReturnCode=DEPEX_CHECK_SUCCESS):
+
+ ModuleDict = PkgObj.GetModuleDict()
+ for ModKey in ModuleDict.keys():
+ ModObj = ModuleDict[ModKey]
+ if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
+ continue
+ else:
+ return False
+ return True
+
+ ## Check whether a DP exists in current workspace.
+ #
+ # @param Guid: Guid of a module
+ # @param Version: Version of a module
+ #
+ def CheckDpExists(self, Guid, Version, ReturnCode=DEPEX_CHECK_SUCCESS):
+ if ReturnCode:
+ pass
+ Logger.Verbose(ST.MSG_CHECK_DP_START)
+ DpList = self.IpiDb.GetDp(Guid, Version)
+ if len(DpList) > 0:
+ return True
+ else:
+ return False
+
+ Logger.Verbose(ST.MSG_CHECK_DP_FINISH)
+
+ ## Check whether a DP depex satisfied by current workspace.
+ #
+ # @param DpObj: Depex object
+ # @param ReturnCode: ReturnCode
+ #
+ def CheckDpDepexSatisfied(self, DpObj, ReturnCode=DEPEX_CHECK_SUCCESS):
+
+ for PkgKey in DpObj.PackageSurfaceArea.keys():
+ PkgObj = DpObj.PackageSurfaceArea[PkgKey]
+ if self.CheckPackageDepexSatisfied(PkgObj, DpObj, ReturnCode):
+ continue
+ else:
+ return False
+
+ for ModKey in DpObj.ModuleSurfaceArea.keys():
+ ModObj = DpObj.ModuleSurfaceArea[ModKey]
+ if self.CheckModuleDepexSatisfied(ModObj, DpObj, ReturnCode):
+ continue
+ else:
+ return False
+
+ return True
+
+ ## Check whether a DP depex satisfied by current workspace. Return False
+ # if Can not remove (there is dependency), True else
+ #
+ # @param DpGuid: File's guid
+ # @param DpVersion: File's version
+ # @param ReturnCode: ReturnCode
+ #
+ def CheckDpDepexForRemove(self, DpGuid, DpVersion, \
+ ReturnCode=DEPEX_CHECK_SUCCESS):
+ if ReturnCode:
+ pass
+ Removable = True
+ DependModuleList = []
+ WsModuleList = self.WsModuleList
+ #
+ # remove modules that included in current DP
+ # List of item (FilePath)
+ DpModuleList = self.IpiDb.GetDpModuleList(DpGuid, DpVersion)
+ for Module in DpModuleList:
+ if Module in WsModuleList:
+ WsModuleList.remove(Module)
+ else:
+ Logger.Warn("UPT\n",
+ ST.ERR_MODULE_NOT_INSTALLED % Module)
+ #
+ # get packages in current Dp and find the install path
+ # List of item (PkgGuid, PkgVersion, InstallPath)
+ DpPackageList = self.IpiDb.GetPackageListFromDp(DpGuid, DpVersion)
+ DpPackagePathList = []
+ WorkSP = environ["WORKSPACE"]
+ for (PkgName, PkgGuid, PkgVersion, DecFile) in self.WsPkgList:
+ if PkgName:
+ pass
+ DecPath = dirname(DecFile)
+ if DecPath.find(WorkSP) > -1:
+ InstallPath = DecPath[DecPath.find(WorkSP) + len(WorkSP) + 1:]
+ DecFileRelaPath = \
+ DecFile[DecFile.find(WorkSP) + len(WorkSP) + 1:]
+ else:
+ InstallPath = DecPath
+ DecFileRelaPath = DecFile
+
+ if (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
+ DpPackagePathList.append(DecFileRelaPath)
+ DpPackageList.remove((PkgGuid, PkgVersion, InstallPath))
+
+ #
+ # the left items in DpPackageList are the packages that installed but not found anymore
+ #
+ for (PkgGuid, PkgVersion, InstallPath) in DpPackageList:
+ Logger.Warn("UPT",
+ ST.WARN_INSTALLED_PACKAGE_NOT_FOUND%(PkgGuid, PkgVersion, InstallPath))
+
+ #
+ # check modules to see if has dependency on package of current DP
+ #
+ for Module in WsModuleList:
+ if (CheckModuleDependFromInf(Module, DpPackagePathList)):
+ Removable = False
+ DependModuleList.append(Module)
+ return (Removable, DependModuleList)
+
+
+## check whether module depends on packages in DpPackagePathList, return True
+# if found, False else
+#
+# @param Path: a module path
+# @param DpPackagePathList: a list of Package Paths
+#
+def CheckModuleDependFromInf(Path, DpPackagePathList):
+
+ #
+ # use InfParser to parse inf, then get the information for now,
+ # later on, may consider only parse to get the package dependency info
+ # (Need to take care how to deal wit Macros)
+ #
+ WorkSP = getenv('WORKSPACE')
+
+ try:
+ PomAli = InfPomAlignment(Path, WorkSP, Skip=True)
+
+ for Item in PomAli.GetPackageDependencyList():
+ if Item.GetPackageFilePath() in DpPackagePathList:
+ Logger.Info(ST.MSG_MODULE_DEPEND_ON % (Path, Item.GetPackageFilePath()))
+ return True
+ else:
+ return False
+ except FatalError, ErrCode:
+ if ErrCode.message == EDK1_INF_ERROR:
+ Logger.Warn("UPT",
+ ST.WRN_EDK1_INF_FOUND%Path)
+ return False
+ else:
+ return False
+
+
+
diff --git a/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py b/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py
new file mode 100644
index 0000000000..0387237951
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py
@@ -0,0 +1,228 @@
+## @file
+# This file is used to define a class object to describe a distribution package
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+DistributionPackageClass
+'''
+
+##
+# Import Modules
+#
+import os.path
+
+from Library.Misc import Sdict
+from Library.Misc import GetNonMetaDataFiles
+from PomAdapter.InfPomAlignment import InfPomAlignment
+from PomAdapter.DecPomAlignment import DecPomAlignment
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import OPTION_VALUE_INVALID
+from Logger.ToolError import FatalError
+from Logger.ToolError import EDK1_INF_ERROR
+from Object.POM.CommonObject import IdentificationObject
+from Object.POM.CommonObject import CommonHeaderObject
+from Object.POM.CommonObject import MiscFileObject
+
+## DistributionPackageHeaderClass
+#
+# @param IdentificationObject: Identification Object
+# @param CommonHeaderObject: Common Header Object
+#
+class DistributionPackageHeaderObject(IdentificationObject, \
+ CommonHeaderObject):
+ def __init__(self):
+ IdentificationObject.__init__(self)
+ CommonHeaderObject.__init__(self)
+ self.ReadOnly = ''
+ self.RePackage = ''
+ self.Vendor = ''
+ self.Date = ''
+ self.Signature = 'Md5Sum'
+ self.XmlSpecification = ''
+
+ def GetReadOnly(self):
+ return self.ReadOnly
+
+ def SetReadOnly(self, ReadOnly):
+ self.ReadOnly = ReadOnly
+
+ def GetRePackage(self):
+ return self.RePackage
+
+ def SetRePackage(self, RePackage):
+ self.RePackage = RePackage
+
+ def GetVendor(self):
+ return self.Vendor
+
+ def SetDate(self, Date):
+ self.Date = Date
+
+ def GetDate(self):
+ return self.Date
+
+ def SetSignature(self, Signature):
+ self.Signature = Signature
+
+ def GetSignature(self):
+ return self.Signature
+
+ def SetXmlSpecification(self, XmlSpecification):
+ self.XmlSpecification = XmlSpecification
+
+ def GetXmlSpecification(self):
+ return self.XmlSpecification
+
+## DistributionPackageClass
+#
+# @param object: DistributionPackageClass
+#
+class DistributionPackageClass(object):
+ def __init__(self):
+ self.Header = DistributionPackageHeaderObject()
+ #
+ # {(Guid, Version, Path) : PackageObj}
+ #
+ self.PackageSurfaceArea = Sdict()
+ #
+ # {(Guid, Version, Path) : ModuleObj}
+ #
+ self.ModuleSurfaceArea = Sdict()
+ self.Tools = MiscFileObject()
+ self.MiscellaneousFiles = MiscFileObject()
+ self.UserExtensions = []
+ self.FileList = []
+
+ ## Get all included packages and modules for a distribution package
+ #
+ # @param WorkspaceDir: WorkspaceDir
+ # @param PackageList: A list of all packages
+ # @param ModuleList: A list of all modules
+ #
+ def GetDistributionPackage(self, WorkspaceDir, PackageList, ModuleList):
+ #
+ # Get Packages
+ #
+ if PackageList:
+ for PackageFile in PackageList:
+ PackageFileFullPath = \
+ os.path.normpath(os.path.join(WorkspaceDir, PackageFile))
+ DecObj = DecPomAlignment(PackageFileFullPath, WorkspaceDir, CheckMulDec = True)
+ PackageObj = DecObj
+ #
+ # Parser inf file one bye one
+ #
+ ModuleInfFileList = PackageObj.GetModuleFileList()
+ for File in ModuleInfFileList:
+ WsRelPath = os.path.join(PackageObj.GetPackagePath(), File)
+ WsRelPath = os.path.normpath(WsRelPath)
+ if ModuleList and WsRelPath in ModuleList:
+ Logger.Error("UPT",
+ OPTION_VALUE_INVALID,
+ ST.ERR_NOT_STANDALONE_MODULE_ERROR%\
+ (WsRelPath, PackageFile))
+ Filename = os.path.normpath\
+ (os.path.join(PackageObj.GetRelaPath(), File))
+ os.path.splitext(Filename)
+ #
+ # Call INF parser to generate Inf Object.
+ # Actually, this call is not directly call, but wrapped by
+ # Inf class in InfPomAlignment.
+ #
+ try:
+ ModuleObj = InfPomAlignment(Filename, WorkspaceDir, \
+ PackageObj.GetPackagePath())
+
+ #
+ # Add module to package
+ #
+ ModuleDict = PackageObj.GetModuleDict()
+ ModuleDict[(ModuleObj.GetGuid(), \
+ ModuleObj.GetVersion(), \
+ ModuleObj.GetCombinePath())] = ModuleObj
+ PackageObj.SetModuleDict(ModuleDict)
+ except FatalError, ErrCode:
+ if ErrCode.message == EDK1_INF_ERROR:
+ Logger.Warn("UPT",
+ ST.WRN_EDK1_INF_FOUND%Filename)
+ else:
+ raise
+
+ self.PackageSurfaceArea\
+ [(PackageObj.GetGuid(), PackageObj.GetVersion(), \
+ PackageObj.GetCombinePath())] = PackageObj
+
+ #
+ # Get Modules
+ #
+ if ModuleList:
+ for ModuleFile in ModuleList:
+ ModuleFileFullPath = \
+ os.path.normpath(os.path.join(WorkspaceDir, ModuleFile))
+ try:
+ ModuleObj = InfPomAlignment(ModuleFileFullPath,
+ WorkspaceDir)
+ self.ModuleSurfaceArea[(ModuleObj.GetGuid(), \
+ ModuleObj.GetVersion(), \
+ ModuleObj.GetCombinePath())] = \
+ ModuleObj
+ except FatalError, ErrCode:
+ if ErrCode.message == EDK1_INF_ERROR:
+ Logger.Error("UPT",
+ EDK1_INF_ERROR,
+ ST.WRN_EDK1_INF_FOUND%ModuleFileFullPath,
+ ExtraData=ST.ERR_NOT_SUPPORTED_SA_MODULE)
+ else:
+ raise
+
+ ## Get all files included for a distribution package, except tool/misc of
+ # distribution level
+ #
+ # @retval DistFileList A list of filepath for NonMetaDataFile, relative to workspace
+ # @retval MetaDataFileList A list of filepath for MetaDataFile, relative to workspace
+ #
+ def GetDistributionFileList(self):
+ MetaDataFileList = []
+
+ for Guid, Version, Path in self.PackageSurfaceArea:
+ Package = self.PackageSurfaceArea[Guid, Version, Path]
+ PackagePath = Package.GetPackagePath()
+ FullPath = Package.GetFullPath()
+ MetaDataFileList.append(Path)
+ IncludePathList = Package.GetIncludePathList()
+ for IncludePath in IncludePathList:
+ SearchPath = os.path.normpath(os.path.join(os.path.dirname(FullPath), IncludePath))
+ AddPath = os.path.normpath(os.path.join(PackagePath, IncludePath))
+ self.FileList += GetNonMetaDataFiles(SearchPath, ['CVS', '.svn'], False, AddPath)
+
+ Module = None
+ ModuleDict = Package.GetModuleDict()
+ for Guid, Version, Path in ModuleDict:
+ Module = ModuleDict[Guid, Version, Path]
+ ModulePath = Module.GetModulePath()
+ FullPath = Module.GetFullPath()
+ PkgRelPath = os.path.normpath(os.path.join(PackagePath, ModulePath))
+ MetaDataFileList.append(Path)
+ self.FileList += GetNonMetaDataFiles(os.path.dirname(FullPath), ['CVS', '.svn'], False, PkgRelPath)
+
+ for Guid, Version, Path in self.ModuleSurfaceArea:
+ Module = self.ModuleSurfaceArea[Guid, Version, Path]
+ ModulePath = Module.GetModulePath()
+ FullPath = Module.GetFullPath()
+ MetaDataFileList.append(Path)
+ self.FileList += GetNonMetaDataFiles(os.path.dirname(FullPath), ['CVS', '.svn'], False, ModulePath)
+
+ return self.FileList, MetaDataFileList
+
+
+
diff --git a/BaseTools/Source/Python/UPT/Core/IpiDb.py b/BaseTools/Source/Python/UPT/Core/IpiDb.py
new file mode 100644
index 0000000000..38f872c2ad
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Core/IpiDb.py
@@ -0,0 +1,867 @@
+## @file
+# This file is for installed package information database operations
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+IpiDb
+'''
+
+##
+# Import Modules
+#
+import sqlite3
+import os.path
+import time
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import UPT_ALREADY_RUNNING_ERROR
+
+## IpiDb
+#
+# This class represents the installed package information database
+# Add/Remove/Get installed distribution package information here.
+#
+#
+# @param object: Inherited from object class
+# @param DbPath: A string for the path of the database
+#
+#
+class IpiDatabase(object):
+ def __init__(self, DbPath):
+ Dir = os.path.dirname(DbPath)
+ if not os.path.isdir(Dir):
+ os.mkdir(Dir)
+ self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED')
+ self.Conn.execute("PRAGMA page_size=4096")
+ self.Conn.execute("PRAGMA synchronous=OFF")
+ self.Cur = self.Conn.cursor()
+ self.DpTable = 'DpInfo'
+ self.PkgTable = 'PkgInfo'
+ self.ModInPkgTable = 'ModInPkgInfo'
+ self.StandaloneModTable = 'StandaloneModInfo'
+ self.ModDepexTable = 'ModDepexInfo'
+ self.DpFileListTable = 'DpFileListInfo'
+ self.DummyTable = 'Dummy'
+
+ ## Initialize build database
+ #
+ #
+ def InitDatabase(self, SkipLock = False):
+ Logger.Verbose(ST.MSG_INIT_IPI_START)
+ if not SkipLock:
+ try:
+ #
+ # Create a dummy table, if already existed,
+ # then UPT is already running
+ #
+ SqlCommand = """
+ create table %s (
+ Dummy TEXT NOT NULL,
+ PRIMARY KEY (Dummy)
+ )""" % self.DummyTable
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+ except sqlite3.OperationalError:
+ Logger.Error("UPT",
+ UPT_ALREADY_RUNNING_ERROR,
+ ST.ERR_UPT_ALREADY_RUNNING_ERROR
+ )
+
+ #
+ # Create new table
+ #
+ SqlCommand = """
+ create table IF NOT EXISTS %s (
+ DpGuid TEXT NOT NULL,DpVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ NewPkgFileName TEXT NOT NULL,
+ PkgFileName TEXT NOT NULL,
+ RePackage TEXT NOT NULL,
+ PRIMARY KEY (DpGuid, DpVersion)
+ )""" % self.DpTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """
+ create table IF NOT EXISTS %s (
+ FilePath TEXT NOT NULL,
+ DpGuid TEXT,
+ DpVersion TEXT,
+ Md5Sum TEXT,
+ PRIMARY KEY (FilePath)
+ )""" % self.DpFileListTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """
+ create table IF NOT EXISTS %s (
+ PackageGuid TEXT NOT NULL,
+ PackageVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ DpGuid TEXT,
+ DpVersion TEXT,
+ InstallPath TEXT NOT NULL,
+ PRIMARY KEY (PackageGuid, PackageVersion, InstallPath)
+ )""" % self.PkgTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """
+ create table IF NOT EXISTS %s (
+ ModuleGuid TEXT NOT NULL,
+ ModuleVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ PackageGuid TEXT,
+ PackageVersion TEXT,
+ InstallPath TEXT NOT NULL,
+ PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
+ )""" % self.ModInPkgTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """
+ create table IF NOT EXISTS %s (
+ ModuleGuid TEXT NOT NULL,
+ ModuleVersion TEXT NOT NULL,
+ InstallTime REAL NOT NULL,
+ DpGuid TEXT,
+ DpVersion TEXT,
+ InstallPath TEXT NOT NULL,
+ PRIMARY KEY (ModuleGuid, ModuleVersion, InstallPath)
+ )""" % self.StandaloneModTable
+ self.Cur.execute(SqlCommand)
+
+ SqlCommand = """
+ create table IF NOT EXISTS %s (
+ ModuleGuid TEXT NOT NULL,
+ ModuleVersion TEXT NOT NULL,
+ InstallPath TEXT NOT NULL,
+ DepexGuid TEXT,
+ DepexVersion TEXT
+ )""" % self.ModDepexTable
+ self.Cur.execute(SqlCommand)
+
+ self.Conn.commit()
+
+ Logger.Verbose(ST.MSG_INIT_IPI_FINISH)
+
+ ## Add a distribution install information from DpObj
+ #
+ # @param DpObj:
+ # @param NewDpPkgFileName: New DpPkg File Name
+ # @param DpPkgFileName: DpPkg File Name
+ # @param RePackage: A RePackage
+ #
+ def AddDPObject(self, DpObj, NewDpPkgFileName, DpPkgFileName, RePackage):
+
+ for PkgKey in DpObj.PackageSurfaceArea.keys():
+ PkgGuid = PkgKey[0]
+ PkgVersion = PkgKey[1]
+ PkgInstallPath = PkgKey[2]
+ self._AddPackage(PkgGuid, PkgVersion, DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), PkgInstallPath)
+ PkgObj = DpObj.PackageSurfaceArea[PkgKey]
+ for ModKey in PkgObj.GetModuleDict().keys():
+ ModGuid = ModKey[0]
+ ModVersion = ModKey[1]
+ ModInstallPath = ModKey[2]
+ ModInstallPath = \
+ os.path.normpath(os.path.join(PkgInstallPath, ModInstallPath))
+ self._AddModuleInPackage(ModGuid, ModVersion, PkgGuid, \
+ PkgVersion, ModInstallPath)
+ ModObj = PkgObj.GetModuleDict()[ModKey]
+ for Dep in ModObj.GetPackageDependencyList():
+ DepexGuid = Dep.GetGuid()
+ DepexVersion = Dep.GetVersion()
+ self._AddModuleDepex(ModGuid, ModVersion, ModInstallPath, \
+ DepexGuid, DepexVersion)
+ for (FilePath, Md5Sum) in PkgObj.FileList:
+ self._AddDpFilePathList(DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), FilePath, \
+ Md5Sum)
+
+ for ModKey in DpObj.ModuleSurfaceArea.keys():
+ ModGuid = ModKey[0]
+ ModVersion = ModKey[1]
+ ModInstallPath = ModKey[2]
+ self._AddStandaloneModule(ModGuid, ModVersion, \
+ DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), \
+ ModInstallPath)
+ ModObj = DpObj.ModuleSurfaceArea[ModKey]
+ for Dep in ModObj.GetPackageDependencyList():
+ DepexGuid = Dep.GetGuid()
+ DepexVersion = Dep.GetVersion()
+ self._AddModuleDepex(ModGuid, ModVersion, ModInstallPath, \
+ DepexGuid, DepexVersion)
+ for (Path, Md5Sum) in ModObj.FileList:
+ self._AddDpFilePathList(DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), \
+ Path, Md5Sum)
+
+ #
+ # add tool/misc files
+ #
+ for (Path, Md5Sum) in DpObj.FileList:
+ self._AddDpFilePathList(DpObj.Header.GetGuid(), \
+ DpObj.Header.GetVersion(), Path, Md5Sum)
+
+ self._AddDp(DpObj.Header.GetGuid(), DpObj.Header.GetVersion(), \
+ NewDpPkgFileName, DpPkgFileName, RePackage)
+
+ self.Conn.commit()
+
+ ## Add a distribution install information
+ #
+ # @param Guid Guid of the distribution package
+ # @param Version Version of the distribution package
+ # @param NewDpFileName the saved filename of distribution package file
+ # @param DistributionFileName the filename of distribution package file
+ #
+ def _AddDp(self, Guid, Version, NewDpFileName, DistributionFileName, \
+ RePackage):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ #
+ # Add newly installed DP information to DB.
+ #
+ if NewDpFileName == None or len(NewDpFileName.strip()) == 0:
+ PkgFileName = 'N/A'
+ else:
+ PkgFileName = NewDpFileName
+ CurrentTime = time.time()
+ SqlCommand = \
+ """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
+ (self.DpTable, Guid, Version, CurrentTime, PkgFileName, \
+ DistributionFileName, str(RePackage).upper())
+ self.Cur.execute(SqlCommand)
+
+
+ ## Add a file list from DP
+ #
+ # @param DpGuid: A DpGuid
+ # @param DpVersion: A DpVersion
+ # @param Path: A Path
+ # @param Path: A Md5Sum
+ #
+ def _AddDpFilePathList(self, DpGuid, DpVersion, Path, Md5Sum):
+
+ SqlCommand = """insert into %s values('%s', '%s', '%s', '%s')""" % \
+ (self.DpFileListTable, Path, DpGuid, DpVersion, Md5Sum)
+
+ self.Cur.execute(SqlCommand)
+
+ ## Add a package install information
+ #
+ # @param Guid: A package guid
+ # @param Version: A package version
+ # @param DpGuid: A DpGuid
+ # @param DpVersion: A DpVersion
+ # @param Path: A Path
+ #
+ def _AddPackage(self, Guid, Version, DpGuid=None, DpVersion=None, Path=''):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ if DpGuid == None or len(DpGuid.strip()) == 0:
+ DpGuid = 'N/A'
+
+ if DpVersion == None or len(DpVersion.strip()) == 0:
+ DpVersion = 'N/A'
+
+ #
+ # Add newly installed package information to DB.
+ #
+ CurrentTime = time.time()
+ SqlCommand = \
+ """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
+ (self.PkgTable, Guid, Version, CurrentTime, DpGuid, DpVersion, Path)
+ self.Cur.execute(SqlCommand)
+
+ ## Add a module that from a package install information
+ #
+ # @param Guid: A package guid
+ # @param Version: A package version
+ # @param PkgGuid: A package guid
+ # @param PkgFileName: A package File Name
+ #
+ def _AddModuleInPackage(self, Guid, Version, PkgGuid=None, \
+ PkgVersion=None, Path=''):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ if PkgGuid == None or len(PkgGuid.strip()) == 0:
+ PkgGuid = 'N/A'
+
+ if PkgVersion == None or len(PkgVersion.strip()) == 0:
+ PkgVersion = 'N/A'
+
+ #
+ # Add module from package information to DB.
+ #
+ CurrentTime = time.time()
+ SqlCommand = \
+ """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
+ (self.ModInPkgTable, Guid, Version, CurrentTime, PkgGuid, PkgVersion, \
+ Path)
+ self.Cur.execute(SqlCommand)
+
+ ## Add a module that is standalone install information
+ #
+ # @param Guid: a module Guid
+ # @param Version: a module Version
+ # @param DpGuid: a DpGuid
+ # @param DpVersion: a DpVersion
+ # @param Path: path
+ #
+ def _AddStandaloneModule(self, Guid, Version, DpGuid=None, \
+ DpVersion=None, Path=''):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+
+ if DpGuid == None or len(DpGuid.strip()) == 0:
+ DpGuid = 'N/A'
+
+ if DpVersion == None or len(DpVersion.strip()) == 0:
+ DpVersion = 'N/A'
+
+ #
+ # Add module standalone information to DB.
+ #
+ CurrentTime = time.time()
+ SqlCommand = \
+ """insert into %s values('%s', '%s', %s, '%s', '%s', '%s')""" % \
+ (self.StandaloneModTable, Guid, Version, CurrentTime, DpGuid, \
+ DpVersion, Path)
+ self.Cur.execute(SqlCommand)
+
+ ## Add a module depex
+ #
+ # @param Guid: a module Guid
+ # @param Version: a module Version
+ # @param DepexGuid: a module DepexGuid
+ # @param DepexVersion: a module DepexVersion
+ #
+ def _AddModuleDepex(self, Guid, Version, Path, DepexGuid=None, \
+ DepexVersion=None):
+
+ if DepexGuid == None or len(DepexGuid.strip()) == 0:
+ DepexGuid = 'N/A'
+
+ if DepexVersion == None or len(DepexVersion.strip()) == 0:
+ DepexVersion = 'N/A'
+
+ #
+ # Add module depex information to DB.
+ #
+ SqlCommand = """insert into %s values('%s', '%s', '%s', '%s', '%s')"""\
+ % (self.ModDepexTable, Guid, Version, Path, DepexGuid, DepexVersion)
+ self.Cur.execute(SqlCommand)
+
+ ## Remove a distribution install information, if no version specified,
+ # remove all DPs with this Guid.
+ #
+ # @param DpGuid: guid of dpex
+ # @param DpVersion: version of dpex
+ #
+ def RemoveDpObj(self, DpGuid, DpVersion):
+
+ PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
+ #
+ # delete from ModDepex the standalone module's dependency
+ #
+ SqlCommand = \
+ """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
+ (select ModuleGuid from StandaloneModInfo as B where B.DpGuid = '%s'
+ and B.DpVersion = '%s')
+ and ModDepexInfo.ModuleVersion in
+ (select ModuleVersion from StandaloneModInfo as B
+ where B.DpGuid = '%s' and B.DpVersion = '%s')
+ and ModDepexInfo.InstallPath in
+ (select InstallPath from StandaloneModInfo as B
+ where B.DpGuid = '%s' and B.DpVersion = '%s') """ % \
+ (DpGuid, DpVersion, DpGuid, DpVersion, DpGuid, DpVersion)
+
+ self.Cur.execute(SqlCommand)
+ #
+ # delete from ModDepex the from pkg module's dependency
+ #
+ for Pkg in PkgList:
+
+ SqlCommand = \
+ """delete from ModDepexInfo where ModDepexInfo.ModuleGuid in
+ (select ModuleGuid from ModInPkgInfo
+ where ModInPkgInfo.PackageGuid ='%s' and
+ ModInPkgInfo.PackageVersion = '%s')
+ and ModDepexInfo.ModuleVersion in
+ (select ModuleVersion from ModInPkgInfo
+ where ModInPkgInfo.PackageGuid ='%s' and
+ ModInPkgInfo.PackageVersion = '%s')
+ and ModDepexInfo.InstallPath in
+ (select InstallPath from ModInPkgInfo where
+ ModInPkgInfo.PackageGuid ='%s'
+ and ModInPkgInfo.PackageVersion = '%s')""" \
+ % (Pkg[0], Pkg[1],Pkg[0], Pkg[1],Pkg[0], Pkg[1])
+
+ self.Cur.execute(SqlCommand)
+ #
+ # delete the standalone module
+ #
+ SqlCommand = \
+ """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
+ (self.StandaloneModTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ #
+ # delete the from pkg module
+ #
+ for Pkg in PkgList:
+ SqlCommand = \
+ """delete from %s where %s.PackageGuid ='%s'
+ and %s.PackageVersion = '%s'""" % \
+ (self.ModInPkgTable, self.ModInPkgTable, Pkg[0], \
+ self.ModInPkgTable, Pkg[1])
+ self.Cur.execute(SqlCommand)
+ #
+ # delete packages
+ #
+ SqlCommand = \
+ """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
+ (self.PkgTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ #
+ # delete file list from DP
+ #
+ SqlCommand = \
+ """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
+ (self.DpFileListTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ #
+ # delete DP
+ #
+ SqlCommand = \
+ """delete from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
+ (self.DpTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ self.Conn.commit()
+
+ ## Get a list of distribution install information.
+ #
+ # @param Guid: distribution package guid
+ # @param Version: distribution package version
+ #
+ def GetDp(self, Guid, Version):
+
+ if Version == None or len(Version.strip()) == 0:
+ Version = 'N/A'
+ Logger.Verbose(ST.MSG_GET_DP_INSTALL_LIST)
+ (DpGuid, DpVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where DpGuid ='%s'""" % \
+ (self.DpTable, DpGuid)
+ self.Cur.execute(SqlCommand)
+
+ else:
+ Logger.Verbose(ST.MSG_GET_DP_INSTALL_INFO_START)
+ (DpGuid, DpVersion) = (Guid, Version)
+ SqlCommand = \
+ """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
+ (self.DpTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ DpList = []
+ for DpInfo in self.Cur:
+ DpGuid = DpInfo[0]
+ DpVersion = DpInfo[1]
+ InstallTime = DpInfo[2]
+ PkgFileName = DpInfo[3]
+ DpList.append((DpGuid, DpVersion, InstallTime, PkgFileName))
+
+ Logger.Verbose(ST.MSG_GET_DP_INSTALL_INFO_FINISH)
+ return DpList
+
+ ## Get a list of distribution install dirs
+ #
+ # @param Guid: distribution package guid
+ # @param Version: distribution package version
+ #
+ def GetDpInstallDirList(self, Guid, Version):
+ SqlCommand = """select InstallPath from PkgInfo where DpGuid = '%s' and DpVersion = '%s'""" % (Guid, Version)
+ self.Cur.execute(SqlCommand)
+ DirList = []
+ for Result in self.Cur:
+ if Result[0] not in DirList:
+ DirList.append(Result[0])
+
+ SqlCommand = """select InstallPath from StandaloneModInfo where DpGuid = '%s' and DpVersion = '%s'""" % \
+ (Guid, Version)
+ self.Cur.execute(SqlCommand)
+ for Result in self.Cur:
+ if Result[0] not in DirList:
+ DirList.append(Result[0])
+
+ return DirList
+
+
+ ## Get a list of distribution install file path information.
+ #
+ # @param Guid: distribution package guid
+ # @param Version: distribution package version
+ #
+ def GetDpFileList(self, Guid, Version):
+
+ (DpGuid, DpVersion) = (Guid, Version)
+ SqlCommand = \
+ """select * from %s where DpGuid ='%s' and DpVersion = '%s'""" % \
+ (self.DpFileListTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ PathList = []
+ for Result in self.Cur:
+ Path = Result[0]
+ Md5Sum = Result[3]
+ PathList.append((Path, Md5Sum))
+
+ return PathList
+
+ ## Get files' repackage attribute if present that are installed into current workspace
+ #
+ # @retval FileDict: a Dict of file, key is file path, value is (DpGuid, DpVersion, NewDpFileName, RePackage)
+ #
+ def GetRePkgDict(self):
+ SqlCommand = """select * from %s """ % (self.DpTable)
+ self.Cur.execute(SqlCommand)
+
+ DpInfoList = []
+ for Result in self.Cur:
+ DpInfoList.append(Result)
+
+ FileDict = {}
+ for Result in DpInfoList:
+ DpGuid = Result[0]
+ DpVersion = Result[1]
+ NewDpFileName = Result[3]
+ RePackage = Result[5]
+ if RePackage == 'TRUE':
+ RePackage = True
+ else:
+ RePackage = False
+ for FileInfo in self.GetDpFileList(DpGuid, DpVersion):
+ PathInfo = FileInfo[0]
+ FileDict[PathInfo] = DpGuid, DpVersion, NewDpFileName, RePackage
+
+ return FileDict
+
+ ## Get (Guid, Version) from distribution file name information.
+ #
+ # @param DistributionFile: Distribution File
+ #
+ def GetDpByName(self, DistributionFile):
+ SqlCommand = """select * from %s where NewPkgFileName like '%s'""" % \
+ (self.DpTable, '%' + DistributionFile)
+ self.Cur.execute(SqlCommand)
+
+ for Result in self.Cur:
+ DpGuid = Result[0]
+ DpVersion = Result[1]
+ NewDpFileName = Result[3]
+
+ return (DpGuid, DpVersion, NewDpFileName)
+ else:
+ return (None, None, None)
+
+ ## Get a list of package information.
+ #
+ # @param Guid: package guid
+ # @param Version: package version
+ #
+ def GetPackage(self, Guid, Version, DpGuid='', DpVersion=''):
+
+ if DpVersion == '' or DpGuid == '':
+
+ (PackageGuid, PackageVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where PackageGuid ='%s'
+ and PackageVersion = '%s'""" % (self.PkgTable, PackageGuid, \
+ PackageVersion)
+ self.Cur.execute(SqlCommand)
+
+ elif Version == None or len(Version.strip()) == 0:
+
+ SqlCommand = """select * from %s where PackageGuid ='%s'""" % \
+ (self.PkgTable, Guid)
+ self.Cur.execute(SqlCommand)
+ else:
+ (PackageGuid, PackageVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where PackageGuid ='%s' and
+ PackageVersion = '%s'
+ and DpGuid = '%s' and DpVersion = '%s'""" % \
+ (self.PkgTable, PackageGuid, PackageVersion, \
+ DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ PkgList = []
+ for PkgInfo in self.Cur:
+ PkgGuid = PkgInfo[0]
+ PkgVersion = PkgInfo[1]
+ InstallTime = PkgInfo[2]
+ InstallPath = PkgInfo[5]
+ PkgList.append((PkgGuid, PkgVersion, InstallTime, DpGuid, \
+ DpVersion, InstallPath))
+
+ return PkgList
+
+
+ ## Get a list of module in package information.
+ #
+ # @param Guid: A module guid
+ # @param Version: A module version
+ #
+ def GetModInPackage(self, Guid, Version, PkgGuid='', PkgVersion=''):
+
+ if PkgVersion == '' or PkgGuid == '':
+
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and
+ ModuleVersion = '%s'""" % (self.ModInPkgTable, ModuleGuid, \
+ ModuleVersion)
+ self.Cur.execute(SqlCommand)
+
+ else:
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and
+ ModuleVersion = '%s' and PackageGuid ='%s'
+ and PackageVersion = '%s'
+ """ % (self.ModInPkgTable, ModuleGuid, \
+ ModuleVersion, PkgGuid, PkgVersion)
+ self.Cur.execute(SqlCommand)
+
+ ModList = []
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallTime = ModInfo[2]
+ InstallPath = ModInfo[5]
+ ModList.append((ModGuid, ModVersion, InstallTime, PkgGuid, \
+ PkgVersion, InstallPath))
+
+ return ModList
+
+ ## Get a list of module standalone.
+ #
+ # @param Guid: A module guid
+ # @param Version: A module version
+ #
+ def GetStandaloneModule(self, Guid, Version, DpGuid='', DpVersion=''):
+
+ if DpGuid == '':
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and
+ ModuleVersion = '%s'""" % (self.StandaloneModTable, ModuleGuid, \
+ ModuleVersion)
+ self.Cur.execute(SqlCommand)
+
+ else:
+ (ModuleGuid, ModuleVersion) = (Guid, Version)
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and
+ ModuleVersion = '%s' and DpGuid ='%s' and DpVersion = '%s'
+ """ % (self.StandaloneModTable, ModuleGuid, \
+ ModuleVersion, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ ModList = []
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallTime = ModInfo[2]
+ InstallPath = ModInfo[5]
+ ModList.append((ModGuid, ModVersion, InstallTime, DpGuid, \
+ DpVersion, InstallPath))
+
+ return ModList
+
+ ## Get a list of module information that comes from DP.
+ #
+ # @param DpGuid: A Distrabution Guid
+ # @param DpVersion: A Distrabution version
+ #
+ def GetSModInsPathListFromDp(self, DpGuid, DpVersion):
+
+ PathList = []
+ SqlCommand = """select InstallPath from %s where DpGuid ='%s'
+ and DpVersion = '%s'
+ """ % (self.StandaloneModTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ for Result in self.Cur:
+ InstallPath = Result[0]
+ PathList.append(InstallPath)
+
+ return PathList
+
+ ## Get a list of package information.
+ #
+ # @param DpGuid: A Distrabution Guid
+ # @param DpVersion: A Distrabution version
+ #
+ def GetPackageListFromDp(self, DpGuid, DpVersion):
+
+ SqlCommand = """select * from %s where DpGuid ='%s' and
+ DpVersion = '%s' """ % (self.PkgTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+
+ PkgList = []
+ for PkgInfo in self.Cur:
+ PkgGuid = PkgInfo[0]
+ PkgVersion = PkgInfo[1]
+ InstallPath = PkgInfo[5]
+ PkgList.append((PkgGuid, PkgVersion, InstallPath))
+
+ return PkgList
+
+ ## Get a list of modules that depends on package information from a DP.
+ #
+ # @param DpGuid: A Distrabution Guid
+ # @param DpVersion: A Distrabution version
+ #
+ def GetDpDependentModuleList(self, DpGuid, DpVersion):
+
+ ModList = []
+ PkgList = self.GetPackageListFromDp(DpGuid, DpVersion)
+ if len(PkgList) > 0:
+ return ModList
+
+ for Pkg in PkgList:
+ #
+ # get all in-package modules that depends on current
+ # Pkg (Guid match, Version match or NA) but not belong to
+ # current Pkg
+ #
+ SqlCommand = """select t1.ModuleGuid, t1.ModuleVersion,
+ t1.InstallPath from %s as t1, %s as t2 where
+ t1.ModuleGuid = t2.ModuleGuid and
+ t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s'
+ and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
+ t1.PackageGuid != '%s' and t1.PackageVersion != '%s'
+ """ % (self.ModInPkgTable, \
+ self.ModDepexTable, Pkg[0], Pkg[1], Pkg[0], \
+ Pkg[1])
+ self.Cur.execute(SqlCommand)
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallPath = ModInfo[2]
+ ModList.append((ModGuid, ModVersion, InstallPath))
+
+ #
+ # get all modules from standalone modules that depends on current
+ #Pkg (Guid match, Version match or NA) but not in current dp
+ #
+ SqlCommand = \
+ """select t1.ModuleGuid, t1.ModuleVersion, t1.InstallPath
+ from %s as t1, %s as t2 where t1.ModuleGuid = t2.ModuleGuid and
+ t1.ModuleVersion = t2.ModuleVersion and t2.DepexGuid ='%s'
+ and (t2.DepexVersion = '%s' or t2.DepexVersion = 'N/A') and
+ t1.DpGuid != '%s' and t1.DpVersion != '%s'
+ """ % \
+ (self.StandaloneModTable, self.ModDepexTable, Pkg[0], \
+ Pkg[1], DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ for ModInfo in self.Cur:
+ ModGuid = ModInfo[0]
+ ModVersion = ModInfo[1]
+ InstallPath = ModInfo[2]
+ ModList.append((ModGuid, ModVersion, InstallPath))
+
+
+ return ModList
+
+ ## Get Dp's list of modules.
+ #
+ # @param DpGuid: A Distrabution Guid
+ # @param DpVersion: A Distrabution version
+ #
+ def GetDpModuleList(self, DpGuid, DpVersion):
+ ModList = []
+ #
+ # get Dp module list from the DpFileList table
+ #
+ SqlCommand = """select FilePath
+ from %s
+ where DpGuid = '%s' and DpVersion = '%s' and
+ FilePath like '%%.inf'
+ """ % (self.DpFileListTable, DpGuid, DpVersion)
+ self.Cur.execute(SqlCommand)
+ for ModuleInfo in self.Cur:
+ FilePath = ModuleInfo[0]
+ ModList.append(FilePath)
+
+ return ModList
+
+
+ ## Get a module depex
+ #
+ # @param DpGuid: A module Guid
+ # @param DpVersion: A module version
+ # @param Path:
+ #
+ def GetModuleDepex(self, Guid, Version, Path):
+
+ #
+ # Get module depex information to DB.
+ #
+ SqlCommand = """select * from %s where ModuleGuid ='%s' and
+ ModuleVersion = '%s' and InstallPath ='%s'
+ """ % (self.ModDepexTable, Guid, Version, Path)
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ DepexList = []
+ for DepInfo in self.Cur:
+ DepexGuid = DepInfo[3]
+ DepexVersion = DepInfo[4]
+ DepexList.append((DepexGuid, DepexVersion))
+
+ return DepexList
+
+ ## Close entire database
+ #
+ # Close the connection and cursor
+ #
+ def CloseDb(self):
+ #
+ # drop the dummy table
+ #
+ SqlCommand = """
+ drop table IF EXISTS %s
+ """ % self.DummyTable
+ self.Cur.execute(SqlCommand)
+ self.Conn.commit()
+
+ self.Cur.close()
+ self.Conn.close()
+
+ ## Convert To Sql String
+ #
+ # 1. Replace "'" with "''" in each item of StringList
+ #
+ # @param StringList: A list for strings to be converted
+ #
+ def __ConvertToSqlString(self, StringList):
+ if self.DpTable:
+ pass
+ return map(lambda s: s.replace("'", "''") , StringList)
+
+
+
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Core/PackageFile.py b/BaseTools/Source/Python/UPT/Core/PackageFile.py
new file mode 100644
index 0000000000..04c5d4e8d0
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Core/PackageFile.py
@@ -0,0 +1,249 @@
+## @file
+#
+# PackageFile class represents the zip file of a distribution package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+PackageFile
+'''
+
+##
+# Import Modules
+#
+import os.path
+import zipfile
+import tempfile
+import platform
+
+from Logger.ToolError import FILE_OPEN_FAILURE
+from Logger.ToolError import FILE_CHECKSUM_FAILURE
+from Logger.ToolError import FILE_NOT_FOUND
+from Logger.ToolError import FILE_DECOMPRESS_FAILURE
+from Logger.ToolError import FILE_UNKNOWN_ERROR
+from Logger.ToolError import FILE_WRITE_FAILURE
+from Logger.ToolError import FILE_COMPRESS_FAILURE
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Library.Misc import CreateDirectory
+from Library.Misc import RemoveDirectory
+
+
+
+class PackageFile:
+ def __init__(self, FileName, Mode="r"):
+ self._FileName = FileName
+ if Mode not in ["r", "w", "a"]:
+ Mode = "r"
+ try:
+ self._ZipFile = zipfile.ZipFile(FileName, Mode, \
+ zipfile.ZIP_DEFLATED)
+ self._Files = {}
+ for Filename in self._ZipFile.namelist():
+ self._Files[os.path.normpath(Filename)] = Filename
+ except BaseException, Xstr:
+ Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
+ ExtraData="%s (%s)" % (FileName, str(Xstr)))
+
+ BadFile = self._ZipFile.testzip()
+ if BadFile != None:
+ Logger.Error("PackagingTool", FILE_CHECKSUM_FAILURE,
+ ExtraData="[%s] in %s" % (BadFile, FileName))
+
+ def GetZipFile(self):
+ return self._ZipFile
+
+ ## Get file name
+ #
+ def __str__(self):
+ return self._FileName
+
+ ## Extract the file
+ #
+ # @param To: the destination file
+ #
+ def Unpack(self, ToDest):
+ for FileN in self._ZipFile.namelist():
+ ToFile = os.path.normpath(os.path.join(ToDest, FileN))
+ Msg = "%s -> %s" % (FileN, ToFile)
+ Logger.Info(Msg)
+ self.Extract(FileN, ToFile)
+
+ ## Extract the file
+ #
+ # @param File: the extracted file
+ # @param ToFile: the destination file
+ #
+ def UnpackFile(self, File, ToFile):
+ File = File.replace('\\', '/')
+ if File in self._ZipFile.namelist():
+ Msg = "%s -> %s" % (File, ToFile)
+ Logger.Info(Msg)
+ self.Extract(File, ToFile)
+ return ToFile
+
+ return ''
+
+ ## Extract the file
+ #
+ # @param Which: the source path
+ # @param To: the destination path
+ #
+ def Extract(self, Which, ToDest):
+ Which = os.path.normpath(Which)
+ if Which not in self._Files:
+ Logger.Error("PackagingTool", FILE_NOT_FOUND,
+ ExtraData="[%s] in %s" % (Which, self._FileName))
+ try:
+ FileContent = self._ZipFile.read(self._Files[Which])
+ except BaseException, Xstr:
+ Logger.Error("PackagingTool", FILE_DECOMPRESS_FAILURE,
+ ExtraData="[%s] in %s (%s)" % (Which, \
+ self._FileName, \
+ str(Xstr)))
+ try:
+ CreateDirectory(os.path.dirname(ToDest))
+ if os.path.exists(ToDest) and not os.access(ToDest, os.W_OK):
+ Logger.Warn("PackagingTool", \
+ ST.WRN_FILE_NOT_OVERWRITTEN % ToDest)
+ return
+ ToFile = open(ToDest, "wb")
+ except BaseException, Xstr:
+ Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
+ ExtraData="%s (%s)" % (ToDest, str(Xstr)))
+
+ try:
+ ToFile.write(FileContent)
+ ToFile.close()
+ except BaseException, Xstr:
+ Logger.Error("PackagingTool", FILE_WRITE_FAILURE,
+ ExtraData="%s (%s)" % (ToDest, str(Xstr)))
+
+ ## Remove the file
+ #
+ # @param Files: the removed files
+ #
+ def Remove(self, Files):
+ TmpDir = os.path.join(tempfile.gettempdir(), ".packaging")
+ if os.path.exists(TmpDir):
+ RemoveDirectory(TmpDir, True)
+
+ os.mkdir(TmpDir)
+ self.Unpack(TmpDir)
+ for SinF in Files:
+ SinF = os.path.normpath(SinF)
+ if SinF not in self._Files:
+ Logger.Error("PackagingTool", FILE_NOT_FOUND,
+ ExtraData="%s is not in %s!" % \
+ (SinF, self._FileName))
+ self._Files.pop(SinF)
+ self._ZipFile.close()
+
+ self._ZipFile = zipfile.ZipFile(self._FileName, "w", \
+ zipfile.ZIP_DEFLATED)
+ Cwd = os.getcwd()
+ os.chdir(TmpDir)
+ self.PackFiles(self._Files)
+ os.chdir(Cwd)
+ RemoveDirectory(TmpDir, True)
+
+ ## Pack the files under Top directory, the directory shown in the zipFile start from BaseDir,
+ # BaseDir should be the parent directory of the Top directory, for example,
+ # Pack(Workspace\Dir1, Workspace) will pack files under Dir1, and the path in the zipfile will
+ # start from Workspace
+ #
+ # @param Top: the top directory
+ # @param BaseDir: the base directory
+ #
+ def Pack(self, Top, BaseDir):
+ if not os.path.isdir(Top):
+ Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR, \
+ "%s is not a directory!" %Top)
+
+ FilesToPack = []
+ Cwd = os.getcwd()
+ os.chdir(BaseDir)
+ RelaDir = Top[Top.upper().find(BaseDir.upper()).\
+ join(len(BaseDir).join(1)):]
+
+ for Root, Dirs, Files in os.walk(RelaDir):
+ if 'CVS' in Dirs:
+ Dirs.remove('CVS')
+ if '.svn' in Dirs:
+ Dirs.remove('.svn')
+
+ for Dir in Dirs:
+ if Dir.startswith('.'):
+ Dirs.remove(Dir)
+ for File1 in Files:
+ if File1.startswith('.'):
+ continue
+ ExtName = os.path.splitext(File1)[1]
+ #
+ # skip '.dec', '.inf', '.dsc', '.fdf' files
+ #
+ if ExtName.lower() in ['.dec', '.inf', '.dsc', '.fdf']:
+ continue
+ FilesToPack.append(os.path.join(Root, File1))
+ self.PackFiles(FilesToPack)
+ os.chdir(Cwd)
+
+ ## Pack the file
+ #
+ # @param Files: the files to pack
+ #
+ def PackFiles(self, Files):
+ for File1 in Files:
+ self.PackFile(File1)
+
+ ## Pack the file
+ #
+ # @param File: the files to pack
+ # @param ArcName: the Arc Name
+ #
+ def PackFile(self, File, ArcName=None):
+ try:
+ #
+ # avoid packing same file multiple times
+ #
+ if platform.system() != 'Windows':
+ File = File.replace('\\', '/')
+ ZipedFilesNameList = self._ZipFile.namelist()
+ for ZipedFile in ZipedFilesNameList:
+ if File == os.path.normpath(ZipedFile):
+ return
+ Logger.Info("packing ..." + File)
+ self._ZipFile.write(File, ArcName)
+ except BaseException, Xstr:
+ Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
+ ExtraData="%s (%s)" % (File, str(Xstr)))
+
+ ## Write data to the packed file
+ #
+ # @param Data: data to write
+ # @param ArcName: the Arc Name
+ #
+ def PackData(self, Data, ArcName):
+ try:
+ self._ZipFile.writestr(ArcName, Data)
+ except BaseException, Xstr:
+ Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
+ ExtraData="%s (%s)" % (ArcName, str(Xstr)))
+
+ ## Close file
+ #
+ #
+ def Close(self):
+ self._ZipFile.close()
+
+
+
diff --git a/BaseTools/Source/Python/UPT/Core/__init__.py b/BaseTools/Source/Python/UPT/Core/__init__.py
new file mode 100644
index 0000000000..39c78e8ecf
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Core/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Library' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Core init file
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Dll/sqlite3.dll b/BaseTools/Source/Python/UPT/Dll/sqlite3.dll
new file mode 100644
index 0000000000..c99ef993cf
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Dll/sqlite3.dll
Binary files differ
diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py
new file mode 100644
index 0000000000..575c216e58
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py
@@ -0,0 +1,367 @@
+## @file GenDecFile.py
+#
+# This file contained the logical of transfer package object to DEC files.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+GenDEC
+'''
+
+from Library.Parsing import GenSection
+from Library.CommentGenerating import GenHeaderCommentSection
+from Library.CommentGenerating import GenGenericCommentF
+from Library.CommentGenerating import GenDecTailComment
+from Library.CommentGenerating import _GetHelpStr
+from Library.Misc import GuidStringToGuidStructureString
+from Library.Misc import SaveFileOnChange
+from Library.Misc import ConvertPath
+from Library.DataType import TAB_SPACE_SPLIT
+from Library.DataType import TAB_COMMA_SPLIT
+from Library.DataType import TAB_ARCH_COMMON
+from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
+from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
+from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
+from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
+
+
+def GenPcd(Package, Content):
+ #
+ # generate [Pcd] section
+ # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
+ #
+ ValidUsageDict = {}
+ for Pcd in Package.GetPcdList():
+ #
+ # Generate generic comment
+ #
+ HelpTextList = Pcd.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr, 2)
+
+ PcdErrList = Pcd.GetPcdErrorsList()
+ if PcdErrList:
+ CommentStr += GenPcdErrComment(PcdErrList[0])
+ Statement = CommentStr
+
+ CName = Pcd.GetCName()
+ TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()
+ DefaultValue = Pcd.GetDefaultValue()
+ DatumType = Pcd.GetDatumType()
+ Token = Pcd.GetToken()
+ ValidUsage = Pcd.GetValidUsage()
+
+ if ValidUsage == 'FeaturePcd':
+ ValidUsage = 'PcdsFeatureFlag'
+ elif ValidUsage == 'PatchPcd':
+ ValidUsage = 'PcdsPatchableInModule'
+ elif ValidUsage == 'FixedPcd':
+ ValidUsage = 'PcdsFixedAtBuild'
+ elif ValidUsage == 'Pcd':
+ ValidUsage = 'PcdsDynamic'
+ elif ValidUsage == 'PcdEx':
+ ValidUsage = 'PcdsDynamicEx'
+
+ if ValidUsage in ValidUsageDict:
+ NewSectionDict = ValidUsageDict[ValidUsage]
+ else:
+ NewSectionDict = {}
+ ValidUsageDict[ValidUsage] = NewSectionDict
+ Statement += TokenSpaceGuidCName + '.' + CName
+ Statement += '|' + DefaultValue
+ Statement += '|' + DatumType
+ Statement += '|' + Token
+ #
+ # generate tail comment
+ #
+ if Pcd.GetSupModuleList():
+ Statement += GenDecTailComment(Pcd.GetSupModuleList())
+
+ ArchList = Pcd.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ for ValidUsage in ValidUsageDict:
+ Content += GenSection(ValidUsage, ValidUsageDict[ValidUsage])
+
+ return Content
+
+def GenGuidProtocolPpi(Package, Content):
+ #
+ # generate [Guids] section
+ #
+ NewSectionDict = {}
+ for Guid in Package.GetGuidList():
+ #
+ # Generate generic comment
+ #
+ HelpTextList = Guid.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr, 2)
+
+ Statement = CommentStr
+ CName = Guid.GetCName()
+ Value = GuidStringToGuidStructureString(Guid.GetGuid())
+ Statement += CName + ' = ' + Value
+ #
+ # generate tail comment
+ #
+ if Guid.GetSupModuleList():
+ Statement += GenDecTailComment(Guid.GetSupModuleList())
+ ArchList = Guid.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ Content += GenSection('Guids', NewSectionDict)
+
+ #
+ # generate [Protocols] section
+ #
+ NewSectionDict = {}
+ for Protocol in Package.GetProtocolList():
+ #
+ # Generate generic comment
+ #
+ HelpTextList = Protocol.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr, 2)
+
+ Statement = CommentStr
+ CName = Protocol.GetCName()
+ Value = GuidStringToGuidStructureString(Protocol.GetGuid())
+ Statement += CName + ' = ' + Value
+
+ #
+ # generate tail comment
+ #
+ if Protocol.GetSupModuleList():
+ Statement += GenDecTailComment(Protocol.GetSupModuleList())
+ ArchList = Protocol.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ Content += GenSection('Protocols', NewSectionDict)
+
+ #
+ # generate [Ppis] section
+ #
+ NewSectionDict = {}
+ for Ppi in Package.GetPpiList():
+ #
+ # Generate generic comment
+ #
+ HelpTextList = Ppi.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr, 2)
+
+ Statement = CommentStr
+ CName = Ppi.GetCName()
+ Value = GuidStringToGuidStructureString(Ppi.GetGuid())
+ Statement += CName + ' = ' + Value
+
+ #
+ # generate tail comment
+ #
+ if Ppi.GetSupModuleList():
+ Statement += GenDecTailComment(Ppi.GetSupModuleList())
+ ArchList = Ppi.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ Content += GenSection('Ppis', NewSectionDict)
+
+ return Content
+
+## Transfer Package Object to Dec files
+#
+# Transfer all contents of a standard Package Object to a Dec file
+#
+# @param Package: A Package
+#
+def PackageToDec(Package):
+ #
+ # Init global information for the file
+ #
+ ContainerFile = Package.GetFullPath()
+
+ Content = ''
+ #
+ # generate header comment section
+ #
+ Content += GenHeaderCommentSection(Package.GetAbstract(), \
+ Package.GetDescription(), \
+ Package.GetCopyright(), \
+ Package.GetLicense())
+
+ #
+ # for each section, maintain a dict, sorted arch will be its key,
+ #statement list will be its data
+ # { 'Arch1 Arch2 Arch3': [statement1, statement2],
+ # 'Arch1' : [statement1, statement3]
+ # }
+ #
+
+ #
+ # generate [Defines] section
+ #
+ NewSectionDict = {TAB_ARCH_COMMON : []}
+ SpecialItemList = []
+
+ Statement = '%s = %s' % (TAB_DEC_DEFINES_DEC_SPECIFICATION, '0x00010017')
+ SpecialItemList.append(Statement)
+
+ BaseName = Package.GetBaseName()
+ if BaseName.startswith('.') or BaseName.startswith('-'):
+ BaseName = '_' + BaseName
+ Statement = '%s = %s' % (TAB_DEC_DEFINES_PACKAGE_NAME, BaseName)
+ SpecialItemList.append(Statement)
+ Statement = '%s = %s' % (TAB_DEC_DEFINES_PACKAGE_VERSION, Package.GetVersion())
+ SpecialItemList.append(Statement)
+ Statement = '%s = %s' % (TAB_DEC_DEFINES_PACKAGE_GUID, Package.GetGuid())
+ SpecialItemList.append(Statement)
+ for SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + SpecialItemList
+ Content += GenSection('Defines', NewSectionDict)
+
+ #
+ # generate [Includes] section
+ #
+ NewSectionDict = {}
+ IncludeArchList = Package.GetIncludeArchList()
+ if IncludeArchList:
+ for Path, ArchList in IncludeArchList:
+ Statement = Path
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + [ConvertPath(Statement)]
+ else:
+ NewSectionDict[SortedArch] = [ConvertPath(Statement)]
+
+ Content += GenSection('Includes', NewSectionDict)
+
+ Content = GenGuidProtocolPpi(Package, Content)
+
+ #
+ # generate [LibraryClasses] section
+ #
+ NewSectionDict = {}
+ for LibraryClass in Package.GetLibraryClassList():
+ #
+ # Generate generic comment
+ #
+ HelpTextList = LibraryClass.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ if HelpStr:
+ HelpStr = '@libraryclass ' + HelpStr
+ CommentStr = GenGenericCommentF(HelpStr, 2)
+
+ Statement = CommentStr
+ Name = LibraryClass.GetLibraryClass()
+ IncludeHeader = LibraryClass.GetIncludeHeader()
+ Statement += Name + '|' + ConvertPath(IncludeHeader)
+ #
+ # generate tail comment
+ #
+ if LibraryClass.GetSupModuleList():
+ Statement += \
+ GenDecTailComment(LibraryClass.GetSupModuleList())
+ ArchList = LibraryClass.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = \
+ NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ Content += GenSection('LibraryClasses', NewSectionDict)
+
+ Content = GenPcd(Package, Content)
+
+ #
+ # generate [UserExtensions] section
+ #
+ NewSectionDict = {}
+ for UserExtension in Package.GetUserExtensionList():
+ Statement = UserExtension.GetStatement()
+ if not Statement:
+ continue
+
+ SectionList = []
+ SectionName = 'UserExtensions'
+ UserId = UserExtension.GetUserID()
+ if UserId:
+ if '.' in UserId:
+ UserId = '"' + UserId + '"'
+ SectionName += '.' + UserId
+ if UserExtension.GetIdentifier():
+ SectionName += '.' + '"' + UserExtension.GetIdentifier() + '"'
+ if not UserExtension.GetSupArchList():
+ SectionList.append(SectionName)
+ else:
+ for Arch in UserExtension.GetSupArchList():
+ SectionList.append(SectionName + '.' + Arch)
+ SectionName = ', '.join(SectionList)
+ SectionName = ''.join(['[', SectionName, ']\n'])
+ Content += '\n\n' + SectionName + Statement
+
+ SaveFileOnChange(ContainerFile, Content, False)
+ return ContainerFile
+
+## GenPcdErrComment
+#
+# @param PcdErrObject: PcdErrorObject
+#
+# @retval CommentStr: Generated comment lines, with prefix "#"
+#
+def GenPcdErrComment (PcdErrObject):
+ EndOfLine = "\n"
+ ValidValueRange = PcdErrObject.GetValidValueRange()
+ if ValidValueRange:
+ CommentStr = "# @ValidRange " + ValidValueRange + EndOfLine
+
+ ValidValue = PcdErrObject.GetValidValue()
+ if ValidValue:
+ ValidValueList = \
+ [Value for Value in ValidValue.split(TAB_SPACE_SPLIT) if Value]
+ CommentStr = \
+ "# @ValidList " + TAB_COMMA_SPLIT.join(ValidValueList) + EndOfLine
+
+ Expression = PcdErrObject.GetExpression()
+ if Expression:
+ CommentStr = "# @Expression " + Expression + EndOfLine
+
+ return CommentStr
+
diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
new file mode 100644
index 0000000000..78bb6ea4f1
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
@@ -0,0 +1,988 @@
+## @file GenInfFile.py
+#
+# This file contained the logical of transfer package object to INF files.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+GenInf
+'''
+from os import getenv
+from Library.String import GetSplitValueList
+from Library.Parsing import GenSection
+from Library.Parsing import GetWorkspacePackage
+from Library.Parsing import ConvertArchForInstall
+from Library.Misc import SaveFileOnChange
+from Library.Misc import IsAllModuleList
+from Library.Misc import Sdict
+from Library.Misc import ConvertPath
+from Library.Misc import ConvertSpec
+from Library.CommentGenerating import GenHeaderCommentSection
+from Library.CommentGenerating import GenGenericCommentF
+from Library.CommentGenerating import _GetHelpStr
+from Library import GlobalData
+from Logger import StringTable as ST
+from Logger import ToolError
+import Logger.Log as Logger
+from Library import DataType as DT
+from GenMetaFile import GenMetaFileMisc
+
+## Transfer Module Object to Inf files
+#
+# Transfer all contents of a standard Module Object to an Inf file
+# @param ModuleObject: A Module Object
+#
+def ModuleToInf(ModuleObject):
+ if not GlobalData.gWSPKG_LIST:
+ GlobalData.gWSPKG_LIST = GetWorkspacePackage()
+
+ #
+ # Init global information for the file
+ #
+ ContainerFile = ModuleObject.GetFullPath()
+ Content = ''
+ #
+ # generate header comment section
+ #
+ Content += GenHeaderCommentSection(ModuleObject.GetAbstract(),
+ ModuleObject.GetDescription(),
+ ModuleObject.GetCopyright(),
+ ModuleObject.GetLicense())
+
+ #
+ # Judge whether the INF file is an AsBuild INF.
+ #
+ if ModuleObject.BinaryModule:
+ GlobalData.gIS_BINARY_INF = True
+ else:
+ GlobalData.gIS_BINARY_INF = False
+
+ #
+ # for each section, maintain a dict, sorted arch will be its key,
+ # statement list will be its data
+ # { 'Arch1 Arch2 Arch3': [statement1, statement2],
+ # 'Arch1' : [statement1, statement3]
+ # }
+ #
+
+ #
+ # Gen section contents
+ #
+ Content += GenDefines(ModuleObject)
+ Content += GenBuildOptions(ModuleObject)
+ Content += GenLibraryClasses(ModuleObject)
+ Content += GenPackages(ModuleObject)
+ Content += GenPcdSections(ModuleObject)
+ Content += GenSources(ModuleObject)
+ Content += GenProtocolPPiSections(ModuleObject.GetProtocolList(), True)
+ Content += GenProtocolPPiSections(ModuleObject.GetPpiList(), False)
+ Content += GenGuidSections(ModuleObject.GetGuidList())
+ Content += GenBinaries(ModuleObject)
+ Content += GenDepex(ModuleObject)
+ Content += GenUserExtensions(ModuleObject)
+
+ if ModuleObject.GetEventList() or ModuleObject.GetBootModeList() or ModuleObject.GetHobList():
+ Content += '\n\n'
+ #
+ # generate [Event], [BootMode], [Hob] section
+ #
+ Content += GenSpecialSections(ModuleObject.GetEventList(), 'Event')
+ Content += GenSpecialSections(ModuleObject.GetBootModeList(), 'BootMode')
+ Content += GenSpecialSections(ModuleObject.GetHobList(), 'Hob')
+
+ SaveFileOnChange(ContainerFile, Content, False)
+ return ContainerFile
+
+def GenDefines(ModuleObject):
+ #
+ # generate [Defines] section
+ #
+ Content = ''
+ NewSectionDict = {}
+ for UserExtension in ModuleObject.GetUserExtensionList():
+ DefinesDict = UserExtension.GetDefinesDict()
+ if not DefinesDict:
+ continue
+
+ for Statement in DefinesDict:
+ SortedArch = DT.TAB_ARCH_COMMON
+ if Statement.strip().startswith(DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE):
+ pos = Statement.find(DT.TAB_VALUE_SPLIT)
+ if pos == -1:
+ pos = Statement.find(DT.TAB_EQUAL_SPLIT)
+ Makefile = ConvertPath(Statement[pos + 1:].strip())
+ Statement = Statement[:pos + 1] + ' ' + Makefile
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ SpecialStatementList = []
+
+ #
+ # Add INF_VERSION statement firstly
+ #
+ Statement = 'INF_VERSION = 0x00010017'
+ SpecialStatementList.append(Statement)
+
+ BaseName = ModuleObject.GetBaseName()
+ if BaseName.startswith('.') or BaseName.startswith('-'):
+ BaseName = '_' + BaseName
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_BASE_NAME, BaseName)
+ SpecialStatementList.append(Statement)
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_FILE_GUID, ModuleObject.GetGuid())
+ SpecialStatementList.append(Statement)
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_VERSION_STRING, ModuleObject.GetVersion())
+ SpecialStatementList.append(Statement)
+
+ if ModuleObject.GetModuleType():
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_MODULE_TYPE, ModuleObject.GetModuleType())
+ SpecialStatementList.append(Statement)
+ if ModuleObject.GetPcdIsDriver():
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_PCD_IS_DRIVER, ModuleObject.GetPcdIsDriver())
+ SpecialStatementList.append(Statement)
+ if ModuleObject.GetUefiSpecificationVersion():
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION, \
+ ModuleObject.GetUefiSpecificationVersion())
+ SpecialStatementList.append(Statement)
+ if ModuleObject.GetPiSpecificationVersion():
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION, ModuleObject.GetPiSpecificationVersion())
+ SpecialStatementList.append(Statement)
+ for LibraryClass in ModuleObject.GetLibraryClassList():
+ if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES or \
+ LibraryClass.GetUsage() == DT.USAGE_ITEM_SOMETIMES_PRODUCES:
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_LIBRARY_CLASS, LibraryClass.GetLibraryClass())
+ if LibraryClass.GetSupModuleList():
+ Statement += '|' + DT.TAB_SPACE_SPLIT.join(l for l in LibraryClass.GetSupModuleList())
+ SpecialStatementList.append(Statement)
+ for SpecItem in ModuleObject.GetSpecList():
+ Spec, Version = SpecItem
+ Spec = ConvertSpec(Spec)
+ Statement = '%s %s = %s' % (DT.TAB_INF_DEFINES_SPEC, Spec, Version)
+ SpecialStatementList.append(Statement)
+
+ ExternList = []
+ for Extern in ModuleObject.GetExternList():
+ ArchList = Extern.GetSupArchList()
+ EntryPoint = Extern.GetEntryPoint()
+ UnloadImage = Extern.GetUnloadImage()
+ Constructor = Extern.GetConstructor()
+ Destructor = Extern.GetDestructor()
+ HelpStringList = Extern.GetHelpTextList()
+ FFE = Extern.GetFeatureFlag()
+ ExternList.append([ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList])
+
+ #
+ # Add VALID_ARCHITECTURES information
+ #
+ ValidArchStatement = None
+ if ModuleObject.SupArchList:
+ ValidArchStatement = '# ' + '\n'
+ ValidArchStatement += '# The following information is for reference only and not required by the build tools.\n'
+ ValidArchStatement += '# ' + '\n'
+ ValidArchStatement += '# VALID_ARCHITECTURES = %s' % (' '.join(ModuleObject.SupArchList)) + '\n'
+ ValidArchStatement += '# ' + '\n'
+
+ if DT.TAB_ARCH_COMMON not in NewSectionDict:
+ NewSectionDict[DT.TAB_ARCH_COMMON] = []
+ NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + SpecialStatementList
+ GenMetaFileMisc.AddExternToDefineSec(NewSectionDict, DT.TAB_ARCH_COMMON, ExternList)
+ if ValidArchStatement is not None:
+ NewSectionDict[DT.TAB_ARCH_COMMON] = NewSectionDict[DT.TAB_ARCH_COMMON] + [ValidArchStatement]
+
+ Content += GenSection('Defines', NewSectionDict)
+
+ return Content
+
+def GenLibraryClasses(ModuleObject):
+ #
+ # generate [LibraryClasses] section
+ #
+ Content = ''
+ NewSectionDict = {}
+ if not GlobalData.gIS_BINARY_INF:
+ for LibraryClass in ModuleObject.GetLibraryClassList():
+ if LibraryClass.GetUsage() == DT.USAGE_ITEM_PRODUCES:
+ continue
+ #
+ # Generate generic comment
+ #
+ HelpTextList = LibraryClass.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr)
+ Statement = CommentStr
+ Name = LibraryClass.GetLibraryClass()
+ FFE = LibraryClass.GetFeatureFlag()
+ Statement += Name
+ if FFE:
+ Statement += '|' + FFE
+ ModuleList = LibraryClass.GetSupModuleList()
+ ArchList = LibraryClass.GetSupArchList()
+ for Index in xrange(0, len(ArchList)):
+ ArchList[Index] = ConvertArchForInstall(ArchList[Index])
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+
+ KeyList = []
+ if not ModuleList or IsAllModuleList(ModuleList):
+ KeyList = [SortedArch]
+ else:
+ ModuleString = DT.TAB_VALUE_SPLIT.join(l for l in ModuleList)
+ if not ArchList:
+ SortedArch = DT.TAB_ARCH_COMMON
+ KeyList = [SortedArch + '.' + ModuleString]
+ else:
+ KeyList = [Arch + '.' + ModuleString for Arch in ArchList]
+
+ for Key in KeyList:
+ if Key in NewSectionDict:
+ NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
+ else:
+ NewSectionDict[Key] = [Statement]
+ Content += GenSection('LibraryClasses', NewSectionDict)
+ else:
+ LibraryClassDict = {}
+ for BinaryFile in ModuleObject.GetBinaryFileList():
+ if not BinaryFile.AsBuiltList:
+ continue
+ for LibraryItem in BinaryFile.AsBuiltList[0].LibraryInstancesList:
+ Statement = '# Guid: ' + LibraryItem.Guid + ' Version: ' + LibraryItem.Version
+ if len(BinaryFile.SupArchList) == 0:
+ if LibraryClassDict.has_key('COMMON'):
+ LibraryClassDict['COMMON'].append(Statement)
+ else:
+ LibraryClassDict['COMMON'] = ['## @LIB_INSTANCES']
+ LibraryClassDict['COMMON'].append(Statement)
+ else:
+ for Arch in BinaryFile.SupArchList:
+ if LibraryClassDict.has_key(Arch):
+ LibraryClassDict[Arch].append(Statement)
+ else:
+ LibraryClassDict[Arch] = ['## @LIB_INSTANCES']
+ LibraryClassDict[Arch].append(Statement)
+
+ Content += GenSection('LibraryClasses', LibraryClassDict)
+
+ return Content
+
+def GenPackages(ModuleObject):
+ Content = ''
+ #
+ # generate [Packages] section
+ #
+ NewSectionDict = Sdict()
+ WorkspaceDir = getenv('WORKSPACE')
+ for PackageDependency in ModuleObject.GetPackageDependencyList():
+ #
+ # Generate generic comment
+ #
+ CommentStr = ''
+ HelpText = PackageDependency.GetHelpText()
+ if HelpText:
+ HelpStr = HelpText.GetString()
+ CommentStr = GenGenericCommentF(HelpStr)
+ Statement = CommentStr
+ Guid = PackageDependency.GetGuid()
+ Version = PackageDependency.GetVersion()
+ FFE = PackageDependency.GetFeatureFlag()
+ #
+ # find package path/name
+ #
+ for PkgInfo in GlobalData.gWSPKG_LIST:
+ if Guid == PkgInfo[1]:
+ if (not Version) or (Version == PkgInfo[2]):
+ Path = PkgInfo[3]
+ break
+ #
+ # get relative path
+ #
+ RelaPath = Path[Path.upper().find(WorkspaceDir.upper()) + len(WorkspaceDir) + 1:]
+ Statement += RelaPath.replace('\\', '/')
+ if FFE:
+ Statement += '|' + FFE
+ ArchList = PackageDependency.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ Content += GenSection('Packages', NewSectionDict)
+
+ return Content
+
+def GenSources(ModuleObject):
+ #
+ # generate [Sources] section
+ #
+ Content = ''
+ NewSectionDict = {}
+
+ for Source in ModuleObject.GetSourceFileList():
+ SourceFile = Source.GetSourceFile()
+ Family = Source.GetFamily()
+ FeatureFlag = Source.GetFeatureFlag()
+ SupArchList = Source.GetSupArchList()
+ SupArchList.sort()
+ SortedArch = ' '.join(SupArchList)
+
+ Statement = GenSourceStatement(ConvertPath(SourceFile), Family, FeatureFlag)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ Content += GenSection('Sources', NewSectionDict)
+
+ return Content
+
+def GenDepex(ModuleObject):
+ #
+ # generate [Depex] section
+ #
+ NewSectionDict = Sdict()
+ Content = ''
+ for Depex in ModuleObject.GetPeiDepex() + ModuleObject.GetDxeDepex() + ModuleObject.GetSmmDepex():
+ HelpTextList = Depex.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr)
+ SupArchList = Depex.GetSupArchList()
+ SupModList = Depex.GetModuleType()
+ Expression = Depex.GetDepex()
+ Statement = CommentStr + Expression
+
+ SupArchList.sort()
+ KeyList = []
+ if not SupArchList:
+ SupArchList.append(DT.TAB_ARCH_COMMON.lower())
+ if not SupModList:
+ KeyList = SupArchList
+ else:
+ for ModuleType in SupModList:
+ for Arch in SupArchList:
+ KeyList.append(ConvertArchForInstall(Arch) + '.' + ModuleType)
+
+ for Key in KeyList:
+ if Key in NewSectionDict:
+ NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
+ else:
+ NewSectionDict[Key] = [Statement]
+
+ Content += GenSection('Depex', NewSectionDict, False)
+
+ return Content
+
+## GenUserExtensions
+#
+# GenUserExtensions
+#
+def GenUserExtensions(ModuleObject):
+ NewSectionDict = {}
+ for UserExtension in ModuleObject.GetUserExtensionList():
+ if UserExtension.GetIdentifier() == 'Depex':
+ continue
+ Statement = UserExtension.GetStatement()
+ if not Statement:
+ continue
+
+ ArchList = UserExtension.GetSupArchList()
+ for Index in xrange(0, len(ArchList)):
+ ArchList[Index] = ConvertArchForInstall(ArchList[Index])
+ ArchList.sort()
+
+ KeyList = []
+ CommonPreFix = ''
+ if UserExtension.GetUserID():
+ CommonPreFix = UserExtension.GetUserID()
+ if CommonPreFix.find('.') > -1:
+ CommonPreFix = '"' + CommonPreFix + '"'
+ if UserExtension.GetIdentifier():
+ CommonPreFix += '.' + '"' + UserExtension.GetIdentifier() + '"'
+ if ArchList:
+ KeyList = [CommonPreFix + '.' + Arch for Arch in ArchList]
+ else:
+ KeyList = [CommonPreFix]
+
+ for Key in KeyList:
+ if Key in NewSectionDict:
+ NewSectionDict[Key] = NewSectionDict[Key] + [Statement]
+ else:
+ NewSectionDict[Key] = [Statement]
+ Content = GenSection('UserExtensions', NewSectionDict, False)
+
+ return Content
+
+# GenSourceStatement
+#
+# @param SourceFile: string of source file path/name
+# @param Family: string of source file family field
+# @param FeatureFlag: string of source file FeatureFlag field
+# @param TagName: string of source file TagName field
+# @param ToolCode: string of source file ToolCode field
+# @param HelpStr: string of source file HelpStr field
+#
+# @retval Statement: The generated statement for source
+#
+def GenSourceStatement(SourceFile, Family, FeatureFlag, TagName=None,
+ ToolCode=None, HelpStr=None):
+ Statement = ''
+ if HelpStr:
+ Statement += GenGenericCommentF(HelpStr)
+ #
+ # format of SourceFile|Family|TagName|ToolCode|FeatureFlag
+ #
+ Statement += SourceFile
+
+ if TagName == None:
+ TagName = ''
+ if ToolCode == None:
+ ToolCode = ''
+ if HelpStr == None:
+ HelpStr = ''
+
+ if FeatureFlag:
+ Statement += '|' + Family + '|' + TagName + '|' + ToolCode + '|' + FeatureFlag
+ elif ToolCode:
+ Statement += '|' + Family + '|' + TagName + '|' + ToolCode
+ elif TagName:
+ Statement += '|' + Family + '|' + TagName
+ elif Family:
+ Statement += '|' + Family
+
+ return Statement
+
+# GenBinaryStatement
+#
+# @param Key: (FileName, FileType, FFE, SortedArch)
+# @param Value: (Target, Family, TagName, Comment)
+#
+#
+def GenBinaryStatement(Key, Value):
+ (FileName, FileType, FFE, SortedArch) = Key
+ if SortedArch:
+ pass
+ if Value:
+ (Target, Family, TagName, Comment) = Value
+ else:
+ Target = ''
+ Family = ''
+ TagName = ''
+ Comment = ''
+
+ if Comment:
+ Statement = GenGenericCommentF(Comment)
+ else:
+ Statement = ''
+
+ Statement += FileType + '|' + FileName
+
+ if FileType in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:
+ if FFE:
+ Statement += '|' + Target + '|' + FFE
+ elif Target:
+ Statement += '|' + Target
+ else:
+ if FFE:
+ Statement += '|' + Target + '|' + Family + '|' + TagName + '|' + FFE
+ elif TagName:
+ Statement += '|' + Target + '|' + Family + '|' + TagName
+ elif Family:
+ Statement += '|' + Target + '|' + Family
+ elif Target:
+ Statement += '|' + Target
+
+ return Statement
+
+## GenGuidSections
+#
+# @param GuidObjList: List of GuidObject
+# @retVal Content: The generated section contents
+#
+def GenGuidSections(GuidObjList):
+ #
+ # generate [Guids] section
+ #
+ Content = ''
+ GuidDict = Sdict()
+
+ for Guid in GuidObjList:
+ HelpTextList = Guid.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+
+ CName = Guid.GetCName()
+ FFE = Guid.GetFeatureFlag()
+ Statement = CName
+ if FFE:
+ Statement += '|' + FFE
+
+ Usage = Guid.GetUsage()
+ GuidType = Guid.GetGuidTypeList()[0]
+ VariableName = Guid.GetVariableName()
+
+ #
+ # we need to differentiate the generic comment and usage comment
+ # as multiple generic comment need to be put at first
+ #
+ if Usage == DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
+ # generate list of generic comment
+ Comment = GenGenericCommentF(HelpStr)
+ else:
+ # generate list of other comment
+ Comment = HelpStr.replace('\n', ' ')
+ Comment = Comment.strip()
+ if Comment:
+ Comment = ' # ' + Comment
+ else:
+ Comment = ''
+
+ if Usage != DT.ITEM_UNDEFINED and GuidType == DT.ITEM_UNDEFINED:
+ Comment = '## ' + Usage + Comment
+ elif GuidType == 'Variable':
+ Comment = '## ' + Usage + ' ## ' + GuidType + ':' + VariableName + Comment
+ else:
+ Comment = '## ' + Usage + ' ## ' + GuidType + Comment
+
+ if Comment:
+ Comment += '\n'
+
+ #
+ # merge duplicate items
+ #
+ ArchList = Guid.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if (Statement, SortedArch) in GuidDict:
+ PreviousComment = GuidDict[Statement, SortedArch]
+ Comment = PreviousComment + Comment
+ GuidDict[Statement, SortedArch] = Comment
+
+
+ NewSectionDict = GenMetaFileMisc.TransferDict(GuidDict)
+
+ #
+ # generate the section contents
+ #
+ if NewSectionDict:
+ Content = GenSection('Guids', NewSectionDict)
+
+ return Content
+
+## GenProtocolPPiSections
+#
+# @param ObjList: List of ProtocolObject or Ppi Object
+# @retVal Content: The generated section contents
+#
+def GenProtocolPPiSections(ObjList, IsProtocol):
+ Content = ''
+ Dict = Sdict()
+ for Object in ObjList:
+ HelpTextList = Object.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+
+ CName = Object.GetCName()
+ FFE = Object.GetFeatureFlag()
+ Statement = CName
+ if FFE:
+ Statement += '|' + FFE
+
+ Usage = Object.GetUsage()
+ Notify = Object.GetNotify()
+
+ #
+ # we need to differentiate the generic comment and usage comment
+ # as consecutive generic comment need to be put together
+ #
+ if Usage == DT.ITEM_UNDEFINED and Notify == '':
+ # generate list of generic comment
+ Comment = GenGenericCommentF(HelpStr)
+ else:
+ # generate list of other comment
+ Comment = HelpStr.replace('\n', ' ')
+ Comment = Comment.strip()
+ if Comment:
+ Comment = ' # ' + Comment
+ else:
+ Comment = ''
+
+ if Usage == DT.ITEM_UNDEFINED and not Comment and Notify == '':
+ Comment = ''
+ else:
+ if Notify:
+ Comment = '## ' + Usage + ' ## ' + 'NOTIFY' + Comment
+ else:
+ Comment = '## ' + Usage + Comment
+
+ if Comment:
+ Comment += '\n'
+
+ #
+ # merge duplicate items
+ #
+ ArchList = Object.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if (Statement, SortedArch) in Dict:
+ PreviousComment = Dict[Statement, SortedArch]
+ Comment = PreviousComment + Comment
+ Dict[Statement, SortedArch] = Comment
+
+ NewSectionDict = GenMetaFileMisc.TransferDict(Dict)
+
+ #
+ # generate the section contents
+ #
+ if NewSectionDict:
+ if IsProtocol:
+ Content = GenSection('Protocols', NewSectionDict)
+ else:
+ Content = GenSection('Ppis', NewSectionDict)
+
+ return Content
+
+## GenPcdSections
+#
+#
+def GenPcdSections(ModuleObject):
+ Content = ''
+ if not GlobalData.gIS_BINARY_INF:
+ #
+ # for each Pcd Itemtype, maintain a dict so the same type will be grouped
+ # together
+ #
+ ItemTypeDict = {}
+ for Pcd in ModuleObject.GetPcdList():
+ HelpTextList = Pcd.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+
+ Statement = ''
+ CName = Pcd.GetCName()
+ TokenSpaceGuidCName = Pcd.GetTokenSpaceGuidCName()
+ DefaultValue = Pcd.GetDefaultValue()
+ ItemType = Pcd.GetItemType()
+ if ItemType in ItemTypeDict:
+ Dict = ItemTypeDict[ItemType]
+ else:
+ Dict = Sdict()
+ ItemTypeDict[ItemType] = Dict
+
+ FFE = Pcd.GetFeatureFlag()
+ Statement += TokenSpaceGuidCName + '.' + CName
+ if DefaultValue:
+ Statement += '|' + DefaultValue
+ if FFE:
+ Statement += '|' + FFE
+ elif FFE:
+ Statement += '||' + FFE
+
+ #
+ # Generate comment
+ #
+ Usage = Pcd.GetValidUsage()
+
+ #
+ # if FeatureFlag Pcd, then assume all Usage is CONSUMES
+ #
+ if ItemType == DT.TAB_INF_FEATURE_PCD:
+ Usage = DT.USAGE_ITEM_CONSUMES
+ if Usage == DT.ITEM_UNDEFINED or (ItemType == DT.TAB_INF_FEATURE_PCD):
+ # generate list of generic comment
+ Comment = GenGenericCommentF(HelpStr)
+ else:
+ # generate list of other comment
+ Comment = HelpStr.replace('\n', ' ')
+ Comment = Comment.strip()
+ if Comment:
+ Comment = ' # ' + Comment
+ else:
+ Comment = ''
+
+ Comment = '## ' + Usage + Comment
+
+ if Comment:
+ Comment += '\n'
+
+ #
+ # Merge duplicate entries
+ #
+ ArchList = Pcd.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+ if (Statement, SortedArch) in Dict:
+ PreviousComment = Dict[Statement, SortedArch]
+ Comment = PreviousComment + Comment
+ Dict[Statement, SortedArch] = Comment
+
+ for ItemType in ItemTypeDict:
+ #
+ # First we need to transfer the Dict to use SortedArch as key
+ #
+ Dict = ItemTypeDict[ItemType]
+ NewSectionDict = GenMetaFileMisc.TransferDict(Dict)
+
+ if NewSectionDict:
+ Content += GenSection(ItemType, NewSectionDict)
+ #
+ # For AsBuild INF files
+ #
+ else:
+ Content += GenAsBuiltPacthPcdSections(ModuleObject)
+ Content += GenAsBuiltPcdExSections(ModuleObject)
+
+ return Content
+
+## GenPcdSections
+#
+#
+def GenAsBuiltPacthPcdSections(ModuleObject):
+ PatchPcdDict = {}
+ for BinaryFile in ModuleObject.GetBinaryFileList():
+ if not BinaryFile.AsBuiltList:
+ continue
+ for PatchPcd in BinaryFile.AsBuiltList[0].PatchPcdList:
+ TokenSpaceName = ''
+ PcdCName = PatchPcd.CName
+ PcdValue = PatchPcd.DefaultValue
+ PcdOffset = PatchPcd.Offset
+ TokenSpaceGuidValue = PatchPcd.TokenSpaceGuidValue
+ Token = PatchPcd.Token
+ HelpTextList = PatchPcd.HelpTextList
+ HelpString = ''
+ for HelpStringItem in HelpTextList:
+ for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
+ HelpString += '# ' + HelpLine + '\n'
+
+ TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
+ TokenSpaceGuidValue,
+ Token)
+ if TokenSpaceName == '' or PcdCName == '':
+ Logger.Error("Upt",
+ ToolError.RESOURCE_NOT_AVAILABLE,
+ ST.ERR_INSTALL_FILE_DEC_FILE_ERROR%(TokenSpaceGuidValue, Token),
+ File=ModuleObject.GetFullPath())
+ Statement = HelpString[:-3] + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue + ' | ' + PcdOffset
+
+ if len(BinaryFile.SupArchList) == 0:
+ if PatchPcdDict.has_key('COMMON'):
+ PatchPcdDict['COMMON'].append(Statement)
+ else:
+ PatchPcdDict['COMMON'] = [Statement]
+ else:
+ for Arch in BinaryFile.SupArchList:
+ if PatchPcdDict.has_key(Arch):
+ PatchPcdDict[Arch].append(Statement)
+ else:
+ PatchPcdDict[Arch] = [Statement]
+ return GenSection('PatchPcd', PatchPcdDict)
+
+## GenPcdSections
+#
+#
+def GenAsBuiltPcdExSections(ModuleObject):
+ PcdExDict = {}
+ for BinaryFile in ModuleObject.GetBinaryFileList():
+ if not BinaryFile.AsBuiltList:
+ continue
+ for PcdExItem in BinaryFile.AsBuiltList[0].PcdExValueList:
+ TokenSpaceName = ''
+ PcdCName = PcdExItem.CName
+ PcdValue = PcdExItem.DefaultValue
+ TokenSpaceGuidValue = PcdExItem.TokenSpaceGuidValue
+ Token = PcdExItem.Token
+ HelpTextList = PcdExItem.HelpTextList
+ HelpString = ''
+ for HelpStringItem in HelpTextList:
+ for HelpLine in GetSplitValueList(HelpStringItem.String, '\n'):
+ HelpString += '# ' + HelpLine + '\n'
+ TokenSpaceName, PcdCName = GenMetaFileMisc.ObtainPcdName(ModuleObject.PackageDependencyList,
+ TokenSpaceGuidValue, Token)
+
+ if TokenSpaceName == '' or PcdCName == '':
+ Logger.Error("Upt",
+ ToolError.RESOURCE_NOT_AVAILABLE,
+ ST.ERR_INSTALL_FILE_DEC_FILE_ERROR%(TokenSpaceGuidValue, Token),
+ File=ModuleObject.GetFullPath())
+
+ Statement = HelpString[:-3] + TokenSpaceName + '.' + PcdCName + ' | ' + PcdValue
+
+ if len(BinaryFile.SupArchList) == 0:
+ if PcdExDict.has_key('COMMON'):
+ PcdExDict['COMMON'].append(Statement)
+ else:
+ PcdExDict['COMMON'] = [Statement]
+ else:
+ for Arch in BinaryFile.SupArchList:
+ if PcdExDict.has_key(Arch):
+ PcdExDict[Arch].append(Statement)
+ else:
+ PcdExDict[Arch] = [Statement]
+ return GenSection('PcdEx', PcdExDict)
+
+## GenSpecialSections
+# generate special sections for Event/BootMode/Hob
+#
+def GenSpecialSections(ObjectList, SectionName):
+ #
+ # generate section
+ #
+ Content = ''
+ NewSectionDict = {}
+ for Obj in ObjectList:
+ #
+ # Generate comment
+ #
+ CommentStr = ''
+ HelpTextList = Obj.GetHelpTextList()
+ HelpStr = _GetHelpStr(HelpTextList)
+ CommentStr = GenGenericCommentF(HelpStr)
+
+ if SectionName == 'Hob':
+ Type = Obj.GetHobType()
+ elif SectionName == 'Event':
+ Type = Obj.GetEventType()
+ elif SectionName == 'BootMode':
+ Type = Obj.GetSupportedBootModes()
+ else:
+ assert(SectionName)
+
+ Usage = Obj.GetUsage()
+ Statement = ' ' + Type + ' ## ' + Usage
+
+ if CommentStr in ['#\n', '#\n#\n']:
+ CommentStr = '#\n#\n#\n'
+ #
+ # the first head comment line should start with '##\n',
+ # if it starts with '#\n', then add one '#'
+ # else add '##\n' to meet the format defined in INF spec
+ #
+ if CommentStr.startswith('#\n'):
+ CommentStr = '#' + CommentStr
+ elif CommentStr:
+ CommentStr = '##\n' + CommentStr
+
+ if CommentStr and not CommentStr.endswith('\n#\n'):
+ CommentStr = CommentStr + '#\n'
+
+ NewStateMent = CommentStr + Statement
+ SupArch = Obj.GetSupArchList()
+ SupArch.sort()
+ SortedArch = ' '.join(SupArch)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [NewStateMent]
+ else:
+ NewSectionDict[SortedArch] = [NewStateMent]
+
+ SectionContent = GenSection(SectionName, NewSectionDict)
+ SectionContent = SectionContent.strip()
+ if SectionContent:
+ Content = '# ' + ('\n' + '# ').join(GetSplitValueList(SectionContent, '\n'))
+ Content = Content.lstrip()
+ #
+ # add two empty line after the generated section content to differentiate
+ # it between other possible sections
+ #
+ if Content:
+ Content += '\n#\n#\n'
+ return Content
+
+## GenBuildOptions
+#
+#
+def GenBuildOptions(ModuleObject):
+ Content = ''
+ if not ModuleObject.BinaryModule:
+ #
+ # generate [BuildOptions] section
+ #
+ NewSectionDict = {}
+ for UserExtension in ModuleObject.GetUserExtensionList():
+ BuildOptionDict = UserExtension.GetBuildOptionDict()
+ if not BuildOptionDict:
+ continue
+ for Arch in BuildOptionDict:
+ if Arch in NewSectionDict:
+ NewSectionDict[Arch] = NewSectionDict[Arch] + [BuildOptionDict[Arch]]
+ else:
+ NewSectionDict[Arch] = [BuildOptionDict[Arch]]
+
+ Content = GenSection('BuildOptions', NewSectionDict)
+ else:
+ BuildOptionDict = {}
+ for BinaryFile in ModuleObject.GetBinaryFileList():
+ if not BinaryFile.AsBuiltList:
+ continue
+ for BuilOptionItem in BinaryFile.AsBuiltList[0].BinaryBuildFlagList:
+ Statement = '#' + BuilOptionItem.AsBuiltOptionFlags
+ if len(BinaryFile.SupArchList) == 0:
+ if BuildOptionDict.has_key('COMMON'):
+ if Statement not in BuildOptionDict['COMMON']:
+ BuildOptionDict['COMMON'].append(Statement)
+ else:
+ BuildOptionDict['COMMON'] = ['## @AsBuilt']
+ BuildOptionDict['COMMON'].append(Statement)
+ else:
+ for Arch in BinaryFile.SupArchList:
+ if BuildOptionDict.has_key(Arch):
+ if Statement not in BuildOptionDict[Arch]:
+ BuildOptionDict[Arch].append(Statement)
+ else:
+ BuildOptionDict[Arch] = ['## @AsBuilt']
+ BuildOptionDict[Arch].append(Statement)
+
+ Content = GenSection('BuildOptions', BuildOptionDict)
+
+ return Content
+
+## GenBinaries
+#
+#
+def GenBinaries(ModuleObject):
+ NewSectionDict = {}
+ BinariesDict = []
+ for UserExtension in ModuleObject.GetUserExtensionList():
+ BinariesDict = UserExtension.GetBinariesDict()
+ if BinariesDict:
+ break
+
+ for BinaryFile in ModuleObject.GetBinaryFileList():
+ FileNameObjList = BinaryFile.GetFileNameList()
+ for FileNameObj in FileNameObjList:
+ FileName = ConvertPath(FileNameObj.GetFilename())
+ FileType = FileNameObj.GetFileType()
+ FFE = FileNameObj.GetFeatureFlag()
+ ArchList = FileNameObj.GetSupArchList()
+ ArchList.sort()
+ SortedArch = ' '.join(ArchList)
+
+ Key = (FileName, FileType, FFE, SortedArch)
+
+ if Key in BinariesDict:
+ ValueList = BinariesDict[Key]
+ for ValueItem in ValueList:
+ Statement = GenBinaryStatement(Key, ValueItem)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+ #
+ # as we already generated statement for this DictKey
+ # here set the Valuelist to be empty to avoid generate duplicate entries
+ # as the DictKey may have multiple entries
+ #
+ BinariesDict[Key] = []
+ else:
+ Statement = GenBinaryStatement(Key, None)
+ if SortedArch in NewSectionDict:
+ NewSectionDict[SortedArch] = NewSectionDict[SortedArch] + [Statement]
+ else:
+ NewSectionDict[SortedArch] = [Statement]
+
+ return GenSection('Binaries', NewSectionDict) \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
new file mode 100644
index 0000000000..54c113a9d0
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
@@ -0,0 +1,155 @@
+## @file GenMetaFileMisc.py
+#
+# This file contained the miscellaneous routines for GenMetaFile usage.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+GenMetaFileMisc
+'''
+
+from Library import DataType as DT
+from Library import GlobalData
+from Parser.DecParser import Dec
+
+# AddExternToDefineSec
+#
+# @param SectionDict: string of source file path/name
+# @param Arch: string of source file family field
+# @param ExternList: string of source file FeatureFlag field
+#
+def AddExternToDefineSec(SectionDict, Arch, ExternList):
+ for ArchList, EntryPoint, UnloadImage, Constructor, Destructor, FFE, HelpStringList in ExternList:
+ if Arch or ArchList:
+ if EntryPoint:
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_ENTRY_POINT, EntryPoint)
+ if FFE:
+ Statement += ' | %s' % FFE
+ if len(HelpStringList) > 0:
+ Statement = HelpStringList[0].GetString() + '\n' + Statement
+ if len(HelpStringList) > 1:
+ Statement = Statement + HelpStringList[1].GetString()
+ SectionDict[Arch] = SectionDict[Arch] + [Statement]
+ if UnloadImage:
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_UNLOAD_IMAGE, UnloadImage)
+ if FFE:
+ Statement += ' | %s' % FFE
+
+ if len(HelpStringList) > 0:
+ Statement = HelpStringList[0].GetString() + '\n' + Statement
+ if len(HelpStringList) > 1:
+ Statement = Statement + HelpStringList[1].GetString()
+ SectionDict[Arch] = SectionDict[Arch] + [Statement]
+ if Constructor:
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_CONSTRUCTOR, Constructor)
+ if FFE:
+ Statement += ' | %s' % FFE
+
+ if len(HelpStringList) > 0:
+ Statement = HelpStringList[0].GetString() + '\n' + Statement
+ if len(HelpStringList) > 1:
+ Statement = Statement + HelpStringList[1].GetString()
+ SectionDict[Arch] = SectionDict[Arch] + [Statement]
+ if Destructor:
+ Statement = '%s = %s' % (DT.TAB_INF_DEFINES_DESTRUCTOR, Destructor)
+ if FFE:
+ Statement += ' | %s' % FFE
+
+ if len(HelpStringList) > 0:
+ Statement = HelpStringList[0].GetString() + '\n' + Statement
+ if len(HelpStringList) > 1:
+ Statement = Statement + HelpStringList[1].GetString()
+ SectionDict[Arch] = SectionDict[Arch] + [Statement]
+
+## ObtainPcdName
+#
+# Using TokenSpaceGuidValue and Token to obtain PcdName from DEC file
+#
+def ObtainPcdName(Packages, TokenSpaceGuidValue, Token):
+ for PackageDependency in Packages:
+ #
+ # Generate generic comment
+ #
+ Guid = PackageDependency.GetGuid()
+ Version = PackageDependency.GetVersion()
+
+ #
+ # find package path/name
+ #
+ for PkgInfo in GlobalData.gWSPKG_LIST:
+ if Guid == PkgInfo[1]:
+ if (not Version) or (Version == PkgInfo[2]):
+ Path = PkgInfo[3]
+ break
+
+ DecFile = Dec(Path)
+ DecGuidsDict = DecFile.GetGuidSectionObject().ValueDict
+ DecPcdsDict = DecFile.GetPcdSectionObject().ValueDict
+
+ TokenSpaceGuidName = ''
+ PcdCName = ''
+ TokenSpaceGuidNameFound = False
+ PcdCNameFound = False
+
+ #
+ # Get TokenSpaceGuidCName from Guids section
+ #
+ for GuidKey in DecGuidsDict:
+ GuidList = DecGuidsDict[GuidKey]
+ if TokenSpaceGuidNameFound:
+ break
+ for GuidItem in GuidList:
+ if TokenSpaceGuidValue == GuidItem.GuidString:
+ TokenSpaceGuidName = GuidItem.GuidCName
+ TokenSpaceGuidNameFound = True
+ break
+
+ #
+ # Retrieve PcdCName from Pcds Section
+ #
+ for PcdKey in DecPcdsDict:
+ PcdList = DecPcdsDict[PcdKey]
+ if PcdCNameFound:
+ break
+ for PcdItem in PcdList:
+ if TokenSpaceGuidName == PcdItem.TokenSpaceGuidCName and Token == PcdItem.TokenValue:
+ PcdCName = PcdItem.TokenCName
+ PcdCNameFound = True
+ break
+
+ return TokenSpaceGuidName, PcdCName
+
+## _TransferDict
+# transfer dict that using (Statement, SortedArch) as key,
+# (GenericComment, UsageComment) as value into a dict that using SortedArch as
+# key and NewStatement as value
+#
+def TransferDict(OrigDict):
+ NewDict = {}
+
+ for Statement, SortedArch in OrigDict:
+ Comment = OrigDict[Statement, SortedArch]
+ #
+ # apply the NComment/1Comment rule
+ #
+ if Comment.find('\n') != len(Comment) - 1:
+ NewStateMent = Comment + Statement
+ else:
+ NewStateMent = Statement + ' ' + Comment.rstrip('\n')
+
+ if SortedArch in NewDict:
+ NewDict[SortedArch] = NewDict[SortedArch] + [NewStateMent]
+ else:
+ NewDict[SortedArch] = [NewStateMent]
+
+ return NewDict
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py b/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py
new file mode 100644
index 0000000000..b1f427723c
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py
@@ -0,0 +1,18 @@
+## @file GenXmlFile.py
+#
+# This file contained the logical of generate XML files.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+GenXmlFile
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py b/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py
new file mode 100644
index 0000000000..0f6ce81579
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/GenMetaFile/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Library' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+GenMetaFile
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/InstallPkg.py b/BaseTools/Source/Python/UPT/InstallPkg.py
new file mode 100644
index 0000000000..c258222d6d
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/InstallPkg.py
@@ -0,0 +1,770 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+"""
+Install a distribution package
+"""
+##
+# Import Modules
+#
+import os.path
+from os import chmod
+from os import SEEK_SET
+from os import SEEK_END
+import stat
+import md5
+from sys import stdin
+from sys import platform
+from shutil import rmtree
+from shutil import copyfile
+from traceback import format_exc
+from platform import python_version
+
+from Logger import StringTable as ST
+from Logger.ToolError import UNKNOWN_ERROR
+from Logger.ToolError import FILE_UNKNOWN_ERROR
+from Logger.ToolError import OPTION_MISSING
+from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR
+from Logger.ToolError import FatalError
+from Logger.ToolError import ABORT_ERROR
+from Logger.ToolError import CODE_ERROR
+from Logger.ToolError import FORMAT_INVALID
+from Logger.ToolError import FILE_TYPE_MISMATCH
+import Logger.Log as Logger
+
+from Library.Misc import CheckEnvVariable
+from Library.Misc import Sdict
+from Library.Misc import ConvertPath
+from Library.ParserValidate import IsValidInstallPath
+from Xml.XmlParser import DistributionPackageXml
+from GenMetaFile.GenDecFile import PackageToDec
+from GenMetaFile.GenInfFile import ModuleToInf
+from Core.PackageFile import PackageFile
+from Core.PackageFile import FILE_NOT_FOUND
+from Core.PackageFile import FILE_CHECKSUM_FAILURE
+from Core.PackageFile import CreateDirectory
+from Core.DependencyRules import DependencyRules
+from Library import GlobalData
+
+## InstallNewPackage
+#
+# @param WorkspaceDir: Workspace Directory
+# @param Path: Package Path
+# @param CustomPath: whether need to customize path at first
+#
+def InstallNewPackage(WorkspaceDir, Path, CustomPath = False):
+ if os.path.isabs(Path):
+ Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%Path)
+ elif CustomPath:
+ Logger.Info(ST.MSG_NEW_PKG_PATH)
+ else:
+ Path = ConvertPath(Path)
+ Path = os.path.normpath(Path)
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
+ if os.path.exists(FullPath):
+ Logger.Info(ST.ERR_DIR_ALREADY_EXIST%FullPath)
+ else:
+ return Path
+
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewPackage(WorkspaceDir, Input, False)
+
+
+## InstallNewModule
+#
+# @param WorkspaceDir: Workspace Directory
+# @param Path: Standalone Module Path
+# @param PathList: The already installed standalone module Path list
+#
+def InstallNewModule(WorkspaceDir, Path, PathList = None):
+ if PathList == None:
+ PathList = []
+ Path = ConvertPath(Path)
+ Path = os.path.normpath(Path)
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
+ if os.path.exists(FullPath) and FullPath not in PathList:
+ Logger.Info(ST.ERR_DIR_ALREADY_EXIST%Path)
+ elif Path == FullPath:
+ Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%FullPath)
+ else:
+ return Path
+
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewModule(WorkspaceDir, Input, PathList)
+
+
+## InstallNewFile
+#
+# @param WorkspaceDir: Workspace Direction
+# @param File: File
+#
+def InstallNewFile(WorkspaceDir, File):
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
+ if os.path.exists(FullPath):
+ Logger.Info(ST.ERR_FILE_ALREADY_EXIST %File)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewFile(WorkspaceDir, Input)
+ else:
+ return File
+
+## UnZipDp
+#
+# UnZipDp
+#
+def UnZipDp(WorkspaceDir, Options, DataBase):
+ ContentZipFile = None
+ Logger.Quiet(ST.MSG_UZIP_PARSE_XML)
+ DpPkgFileName = Options.PackageFile
+ DistFile = PackageFile(DpPkgFileName)
+
+ DpDescFileName, ContentFileName = GetDPFile(DistFile.GetZipFile())
+
+ GlobalData.gUNPACK_DIR = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))
+ DistPkgFile = DistFile.UnpackFile(DpDescFileName,
+ os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, DpDescFileName)))
+ if not DistPkgFile:
+ Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_FILE_BROKEN %DpDescFileName)
+
+ #
+ # Generate distpkg
+ #
+ DistPkgObj = DistributionPackageXml()
+ DistPkg = DistPkgObj.FromXml(DistPkgFile)
+ if DistPkg.Header.RePackage == '':
+ DistPkg.Header.RePackage = False
+ if DistPkg.Header.ReadOnly == '':
+ DistPkg.Header.ReadOnly = False
+
+ #
+ # prepare check dependency
+ #
+ Dep = DependencyRules(DataBase)
+ #
+ # Check distribution package installed or not
+ #
+ if Dep.CheckDpExists(DistPkg.Header.GetGuid(),
+ DistPkg.Header.GetVersion()):
+ Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR,
+ ST.WRN_DIST_PKG_INSTALLED)
+ #
+ # Check distribution dependency (all module dependency should be
+ # satisfied)
+ #
+ if not Dep.CheckDpDepexSatisfied(DistPkg):
+ Logger.Error("InstallPkg", UNKNOWN_ERROR,
+ ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY,
+ ExtraData=DistPkg.Header.Name)
+ #
+ # unzip contents.zip file
+ #
+ ContentFile = DistFile.UnpackFile(ContentFileName,
+ os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, ContentFileName)))
+ if not ContentFile:
+ Logger.Error("InstallPkg", FILE_NOT_FOUND,
+ ST.ERR_FILE_BROKEN % ContentFileName)
+
+ FilePointer = open(ContentFile, "rb")
+ #
+ # Assume no archive comment.
+ #
+ FilePointer.seek(0, SEEK_SET)
+ FilePointer.seek(0, SEEK_END)
+ #
+ # Get file size
+ #
+ FileSize = FilePointer.tell()
+ FilePointer.close()
+
+ if FileSize != 0:
+ ContentZipFile = PackageFile(ContentFile)
+
+ #
+ # verify MD5 signature when existed
+ #
+ if DistPkg.Header.Signature != '':
+ Md5Sigature = md5.new(open(ContentFile, 'rb').read())
+ if DistPkg.Header.Signature != Md5Sigature.hexdigest():
+ ContentZipFile.Close()
+ Logger.Error("InstallPkg", FILE_CHECKSUM_FAILURE,
+ ExtraData=ContentFile)
+
+ return DistPkg, Dep, ContentZipFile, DpPkgFileName
+
+## GetPackageList
+#
+# GetPackageList
+#
+def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, ContentZipFile, ModuleList, PackageList):
+ NewDict = Sdict()
+ for Guid, Version, Path in DistPkg.PackageSurfaceArea:
+ PackagePath = Path
+ Package = DistPkg.PackageSurfaceArea[Guid, Version, Path]
+ Logger.Info(ST.MSG_INSTALL_PACKAGE % Package.GetName())
+ if Dep.CheckPackageExists(Guid, Version):
+ Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))
+ NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath, Options.CustomPath)
+ InstallPackageContent(PackagePath, NewPackagePath, Package, ContentZipFile, Dep, WorkspaceDir, ModuleList,
+ DistPkg.Header.ReadOnly)
+ PackageList.append(Package)
+
+ NewDict[Guid, Version, Package.GetPackagePath()] = Package
+
+ #
+ # Now generate meta-data files, first generate all dec for package
+ # dec should be generated before inf, and inf should be generated after
+ # all packages installed, else hard to resolve modules' package
+ # dependency (Hard to get the location of the newly installed package)
+ #
+ for Package in PackageList:
+ FilePath = PackageToDec(Package)
+ Md5Sigature = md5.new(open(str(FilePath), 'rb').read())
+ Md5Sum = Md5Sigature.hexdigest()
+ if (FilePath, Md5Sum) not in Package.FileList:
+ Package.FileList.append((FilePath, Md5Sum))
+
+ return NewDict
+
+## GetModuleList
+#
+# GetModuleList
+#
+def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList):
+ #
+ # ModulePathList will keep track of the standalone module path that
+ # we just installed. If a new module's path in that list
+ # (only multiple INF in one directory will be so), we will
+ # install them directly. If not, we will try to create a new directory
+ # for it.
+ #
+ ModulePathList = []
+
+ #
+ # Check module exist and install
+ #
+ Module = None
+ NewDict = Sdict()
+ for Guid, Version, Path in DistPkg.ModuleSurfaceArea:
+ ModulePath = Path
+ Module = DistPkg.ModuleSurfaceArea[Guid, Version, Path]
+ Logger.Info(ST.MSG_INSTALL_MODULE % Module.GetName())
+ if Dep.CheckModuleExists(Guid, Version):
+ Logger.Quiet(ST.WRN_MODULE_EXISTED %Path)
+ #
+ # here check for the multiple inf share the same module path cases:
+ # they should be installed into the same directory
+ #
+ ModuleFullPath = \
+ os.path.normpath(os.path.join(WorkspaceDir, ModulePath))
+ if ModuleFullPath not in ModulePathList:
+ NewModulePath = InstallNewModule(WorkspaceDir, ModulePath, ModulePathList)
+ NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath))
+ ModulePathList.append(NewModuleFullPath)
+ else:
+ NewModulePath = ModulePath
+
+ InstallModuleContent(ModulePath, NewModulePath, '', Module, ContentZipFile, WorkspaceDir, ModuleList, None,
+ DistPkg.Header.ReadOnly)
+ #
+ # Update module
+ #
+ Module.SetModulePath(Module.GetModulePath().replace(Path, NewModulePath, 1))
+
+ NewDict[Guid, Version, Module.GetModulePath()] = Module
+
+ #
+ # generate all inf for modules
+ #
+ for (Module, Package) in ModuleList:
+ FilePath = ModuleToInf(Module)
+ Md5Sigature = md5.new(open(str(FilePath), 'rb').read())
+ Md5Sum = Md5Sigature.hexdigest()
+ if Package:
+ if (FilePath, Md5Sum) not in Package.FileList:
+ Package.FileList.append((FilePath, Md5Sum))
+ else:
+ if (FilePath, Md5Sum) not in Module.FileList:
+ Module.FileList.append((FilePath, Md5Sum))
+
+ return NewDict
+
+## GenToolMisc
+#
+# GenToolMisc
+#
+#
+def GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile):
+ ToolObject = DistPkg.Tools
+ MiscObject = DistPkg.MiscellaneousFiles
+ DistPkg.FileList = []
+ FileList = []
+ ToolFileNum = 0
+ FileNum = 0
+ RootDir = WorkspaceDir
+
+ #
+ # FileList stores both tools files and misc files
+ # Misc file list must be appended to FileList *AFTER* Tools file list
+ #
+ if ToolObject:
+ FileList += ToolObject.GetFileList()
+ ToolFileNum = len(ToolObject.GetFileList())
+ if 'EDK_TOOLS_PATH' in os.environ:
+ RootDir = os.environ['EDK_TOOLS_PATH']
+ if MiscObject:
+ FileList += MiscObject.GetFileList()
+ for FileObject in FileList:
+ FileNum += 1
+ if FileNum > ToolFileNum:
+ #
+ # Misc files, root should be changed to WORKSPACE
+ #
+ RootDir = WorkspaceDir
+ File = ConvertPath(FileObject.GetURI())
+ ToFile = os.path.normpath(os.path.join(RootDir, File))
+ if os.path.exists(ToFile):
+ Logger.Info( ST.WRN_FILE_EXISTED % ToFile )
+ #
+ # ask for user input the new file name
+ #
+ Logger.Info( ST.MSG_NEW_FILE_NAME)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ OrigPath = os.path.split(ToFile)[0]
+ ToFile = os.path.normpath(os.path.join(OrigPath, Input))
+ FromFile = os.path.join(FileObject.GetURI())
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, DistPkg.Header.ReadOnly, FileObject.GetExecutable())
+ DistPkg.FileList.append((ToFile, Md5Sum))
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+# @param Options: command Options
+#
+def Main(Options = None):
+ ContentZipFile, DistFile = None, None
+
+ try:
+ DataBase = GlobalData.gDB
+ CheckEnvVariable()
+ WorkspaceDir = GlobalData.gWORKSPACE
+ if not Options.PackageFile:
+ Logger.Error("InstallPkg", OPTION_MISSING, ExtraData=ST.ERR_SPECIFY_PACKAGE)
+
+ #
+ # unzip dist.pkg file
+ #
+ DistPkg, Dep, ContentZipFile, DpPkgFileName = UnZipDp(WorkspaceDir, Options, DataBase)
+
+ #
+ # PackageList, ModuleList record the information for the meta-data
+ # files that need to be generated later
+ #
+ PackageList = []
+ ModuleList = []
+ DistPkg.PackageSurfaceArea = GetPackageList(DistPkg, Dep, WorkspaceDir, Options,
+ ContentZipFile, ModuleList, PackageList)
+
+ DistPkg.ModuleSurfaceArea = GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList)
+
+
+ GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile)
+
+ #
+ # copy "Distribution File" to directory $(WORKSPACE)/conf/upt
+ #
+ DistFileName = os.path.split(DpPkgFileName)[1]
+ DestDir = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR))
+ CreateDirectory(DestDir)
+ DestFile = os.path.normpath(os.path.join(DestDir, DistFileName))
+ if os.path.exists(DestFile):
+ FileName, Ext = os.path.splitext(DistFileName)
+ NewFileName = FileName + '_' + DistPkg.Header.GetGuid() + '_' + DistPkg.Header.GetVersion() + '.' + Ext
+ DestFile = os.path.normpath(os.path.join(DestDir, NewFileName))
+ if os.path.exists(DestFile):
+ #
+ # ask for user input the new file name
+ #
+ Logger.Info( ST.MSG_NEW_FILE_NAME_FOR_DIST)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ DestFile = os.path.normpath(os.path.join(DestDir, Input))
+ copyfile(DpPkgFileName, DestFile)
+ NewDpPkgFileName = DestFile[DestFile.find(DestDir) + len(DestDir) + 1:]
+
+ #
+ # update database
+ #
+ Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)
+ DataBase.AddDPObject(DistPkg, NewDpPkgFileName, DistFileName,
+ DistPkg.Header.RePackage)
+
+ ReturnCode = 0
+
+ except FatalError, XExcept:
+ ReturnCode = XExcept.args[0]
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
+ platform) + format_exc())
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
+ platform) + format_exc())
+ except:
+ ReturnCode = CODE_ERROR
+ Logger.Error(
+ "\nInstallPkg",
+ CODE_ERROR,
+ ST.ERR_UNKNOWN_FATAL_INSTALL_ERR % Options.PackageFile,
+ ExtraData=ST.MSG_SEARCH_FOR_HELP,
+ RaiseError=False
+ )
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
+ platform) + format_exc())
+
+ finally:
+ Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED)
+ if DistFile:
+ DistFile.Close()
+ if ContentZipFile:
+ ContentZipFile.Close()
+ if GlobalData.gUNPACK_DIR:
+ rmtree(GlobalData.gUNPACK_DIR)
+ GlobalData.gUNPACK_DIR = None
+ Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)
+
+ if ReturnCode == 0:
+ Logger.Quiet(ST.MSG_FINISH)
+
+ return ReturnCode
+
+## InstallModuleContent method
+#
+# If this is standalone module, then Package should be none,
+# ModulePath should be ''
+# @param FromPath: FromPath
+# @param NewPath: NewPath
+# @param ModulePath: ModulePath
+# @param Module: Module
+# @param ContentZipFile: ContentZipFile
+# @param WorkspaceDir: WorkspaceDir
+# @param ModuleList: ModuleList
+# @param Package: Package
+#
+def InstallModuleContent(FromPath, NewPath, ModulePath, Module, ContentZipFile,
+ WorkspaceDir, ModuleList, Package = None, ReadOnly = False):
+
+ if NewPath.startswith("\\") or NewPath.startswith("/"):
+ NewPath = NewPath[1:]
+
+ if not IsValidInstallPath(NewPath):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%NewPath)
+
+ NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewPath,
+ ConvertPath(ModulePath)))
+ Module.SetFullPath(os.path.normpath(os.path.join(NewModuleFullPath,
+ ConvertPath(Module.GetName()) + '.inf')))
+ Module.FileList = []
+
+ for MiscFile in Module.GetMiscFileList():
+ if not MiscFile:
+ continue
+ for Item in MiscFile.GetFileList():
+ File = Item.GetURI()
+ if File.startswith("\\") or File.startswith("/"):
+ File = File[1:]
+
+ if not IsValidInstallPath(File):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)
+
+ FromFile = os.path.join(FromPath, ModulePath, File)
+ Executable = Item.GetExecutable()
+ ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)
+ if Package and ((ToFile, Md5Sum) not in Package.FileList):
+ Package.FileList.append((ToFile, Md5Sum))
+ elif Package:
+ continue
+ elif (ToFile, Md5Sum) not in Module.FileList:
+ Module.FileList.append((ToFile, Md5Sum))
+ for Item in Module.GetSourceFileList():
+ File = Item.GetSourceFile()
+ if File.startswith("\\") or File.startswith("/"):
+ File = File[1:]
+
+ if not IsValidInstallPath(File):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)
+
+ FromFile = os.path.join(FromPath, ModulePath, File)
+ ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
+ if Package and ((ToFile, Md5Sum) not in Package.FileList):
+ Package.FileList.append((ToFile, Md5Sum))
+ elif Package:
+ continue
+ elif (ToFile, Md5Sum) not in Module.FileList:
+ Module.FileList.append((ToFile, Md5Sum))
+ for Item in Module.GetBinaryFileList():
+ FileNameList = Item.GetFileNameList()
+ for FileName in FileNameList:
+ File = FileName.GetFilename()
+ if File.startswith("\\") or File.startswith("/"):
+ File = File[1:]
+
+ if not IsValidInstallPath(File):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)
+
+ FromFile = os.path.join(FromPath, ModulePath, File)
+ ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
+ if Package and ((ToFile, Md5Sum) not in Package.FileList):
+ Package.FileList.append((ToFile, Md5Sum))
+ elif Package:
+ continue
+ elif (ToFile, Md5Sum) not in Module.FileList:
+ Module.FileList.append((ToFile, Md5Sum))
+
+ InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,
+ ModuleList)
+
+## InstallModuleContentZipFile
+#
+# InstallModuleContentZipFile
+#
+def InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,
+ ModuleList):
+ #
+ # Extract other files under current module path in content Zip file but not listed in the description
+ #
+ if ContentZipFile:
+ for FileName in ContentZipFile.GetZipFile().namelist():
+ FileName = os.path.normpath(FileName)
+ CheckPath = os.path.normpath(os.path.join(FromPath, ModulePath))
+ if FileUnderPath(FileName, CheckPath):
+ if FileName.startswith("\\") or FileName.startswith("/"):
+ FileName = FileName[1:]
+
+ if not IsValidInstallPath(FileName):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)
+
+ FromFile = FileName
+ ToFile = os.path.normpath(os.path.join(WorkspaceDir,
+ ConvertPath(FileName.replace(FromPath, NewPath, 1))))
+ CheckList = Module.FileList
+ if Package:
+ CheckList += Package.FileList
+ for Item in CheckList:
+ if Item[0] == ToFile:
+ break
+ else:
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
+ if Package and ((ToFile, Md5Sum) not in Package.FileList):
+ Package.FileList.append((ToFile, Md5Sum))
+ elif Package:
+ continue
+ elif (ToFile, Md5Sum) not in Module.FileList:
+ Module.FileList.append((ToFile, Md5Sum))
+
+ ModuleList.append((Module, Package))
+
+## FileUnderPath
+# Check whether FileName started with directory specified by CheckPath
+#
+# @param FileName: the FileName need to be checked
+# @param CheckPath: the path need to be checked against
+# @return: True or False
+#
+def FileUnderPath(FileName, CheckPath):
+ FileName = FileName.replace('\\', '/')
+ FileName = os.path.normpath(FileName)
+ CheckPath = CheckPath.replace('\\', '/')
+ CheckPath = os.path.normpath(CheckPath)
+ if FileName.startswith(CheckPath):
+ RemainingPath = os.path.normpath(FileName.replace(CheckPath, '', 1))
+ while RemainingPath.startswith('\\') or RemainingPath.startswith('/'):
+ RemainingPath = RemainingPath[1:]
+ if FileName == os.path.normpath(os.path.join(CheckPath, RemainingPath)):
+ return True
+
+ return False
+
+## InstallFile
+# Extract File from Zipfile, set file attribute, and return the Md5Sum
+#
+# @return: True or False
+#
+def InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable=False):
+ if not ContentZipFile or not ContentZipFile.UnpackFile(FromFile, ToFile):
+ Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT%FromFile)
+
+ if ReadOnly:
+ if not Executable:
+ chmod(ToFile, stat.S_IREAD)
+ else:
+ chmod(ToFile, stat.S_IREAD|stat.S_IEXEC)
+ elif Executable:
+ chmod(ToFile, stat.S_IREAD|stat.S_IWRITE|stat.S_IEXEC)
+ else:
+ chmod(ToFile, stat.S_IREAD|stat.S_IWRITE)
+
+ Md5Sigature = md5.new(open(str(ToFile), 'rb').read())
+ Md5Sum = Md5Sigature.hexdigest()
+ return Md5Sum
+
+## InstallPackageContent method
+#
+# @param FromPath: FromPath
+# @param ToPath: ToPath
+# @param Package: Package
+# @param ContentZipFile: ContentZipFile
+# @param Dep: Dep
+# @param WorkspaceDir: WorkspaceDir
+# @param ModuleList: ModuleList
+#
+def InstallPackageContent(FromPath, ToPath, Package, ContentZipFile, Dep,
+ WorkspaceDir, ModuleList, ReadOnly = False):
+ if Dep:
+ pass
+ Package.FileList = []
+
+ if ToPath.startswith("\\") or ToPath.startswith("/"):
+ ToPath = ToPath[1:]
+
+ if not IsValidInstallPath(ToPath):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%ToPath)
+
+ if FromPath.startswith("\\") or FromPath.startswith("/"):
+ FromPath = FromPath[1:]
+
+ if not IsValidInstallPath(FromPath):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FromPath)
+
+ PackageFullPath = os.path.normpath(os.path.join(WorkspaceDir, ToPath))
+ for MiscFile in Package.GetMiscFileList():
+ for Item in MiscFile.GetFileList():
+ FileName = Item.GetURI()
+ if FileName.startswith("\\") or FileName.startswith("/"):
+ FileName = FileName[1:]
+
+ if not IsValidInstallPath(FileName):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)
+
+ FromFile = os.path.join(FromPath, FileName)
+ Executable = Item.GetExecutable()
+ ToFile = (os.path.join(PackageFullPath, ConvertPath(FileName)))
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)
+ if (ToFile, Md5Sum) not in Package.FileList:
+ Package.FileList.append((ToFile, Md5Sum))
+ PackageIncludeArchList = []
+ for Item in Package.GetPackageIncludeFileList():
+ FileName = Item.GetFilePath()
+ if FileName.startswith("\\") or FileName.startswith("/"):
+ FileName = FileName[1:]
+
+ if not IsValidInstallPath(FileName):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)
+
+ FromFile = os.path.join(FromPath, FileName)
+ ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))
+ RetFile = ContentZipFile.UnpackFile(FromFile, ToFile)
+ if RetFile == '':
+ #
+ # a non-exist path in Zipfile will return '', which means an include directory in our case
+ # save the information for later DEC creation usage and also create the directory
+ #
+ PackageIncludeArchList.append([Item.GetFilePath(), Item.GetSupArchList()])
+ CreateDirectory(ToFile)
+ continue
+ if ReadOnly:
+ chmod(ToFile, stat.S_IREAD)
+ else:
+ chmod(ToFile, stat.S_IREAD|stat.S_IWRITE)
+ Md5Sigature = md5.new(open(str(ToFile), 'rb').read())
+ Md5Sum = Md5Sigature.hexdigest()
+ if (ToFile, Md5Sum) not in Package.FileList:
+ Package.FileList.append((ToFile, Md5Sum))
+ Package.SetIncludeArchList(PackageIncludeArchList)
+
+ for Item in Package.GetStandardIncludeFileList():
+ FileName = Item.GetFilePath()
+ if FileName.startswith("\\") or FileName.startswith("/"):
+ FileName = FileName[1:]
+
+ if not IsValidInstallPath(FileName):
+ Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)
+
+ FromFile = os.path.join(FromPath, FileName)
+ ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))
+ Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
+ if (ToFile, Md5Sum) not in Package.FileList:
+ Package.FileList.append((ToFile, Md5Sum))
+
+ #
+ # Update package
+ #
+ Package.SetPackagePath(Package.GetPackagePath().replace(FromPath,
+ ToPath, 1))
+ Package.SetFullPath(os.path.normpath(os.path.join(PackageFullPath,
+ ConvertPath(Package.GetName()) + '.dec')))
+
+ #
+ # Install files in module
+ #
+ Module = None
+ ModuleDict = Package.GetModuleDict()
+ for ModuleGuid, ModuleVersion, ModulePath in ModuleDict:
+ Module = ModuleDict[ModuleGuid, ModuleVersion, ModulePath]
+ InstallModuleContent(FromPath, ToPath, ModulePath, Module,
+ ContentZipFile, WorkspaceDir, ModuleList, Package, ReadOnly)
+
+## GetDPFile method
+#
+# @param ZipFile: A ZipFile
+#
+def GetDPFile(ZipFile):
+ ContentFile = ''
+ DescFile = ''
+ for FileName in ZipFile.namelist():
+ if FileName.endswith('.content'):
+ if not ContentFile:
+ ContentFile = FileName
+ continue
+ elif FileName.endswith('.pkg'):
+ if not DescFile:
+ DescFile = FileName
+ continue
+ else:
+ continue
+
+ Logger.Error("PackagingTool", FILE_TYPE_MISMATCH,
+ ExtraData=ST.ERR_DIST_FILE_TOOMANY)
+ if not DescFile or not ContentFile:
+ Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR,
+ ExtraData=ST.ERR_DIST_FILE_TOOFEW)
+ return DescFile, ContentFile
+
diff --git a/BaseTools/Source/Python/UPT/Library/CommentGenerating.py b/BaseTools/Source/Python/UPT/Library/CommentGenerating.py
new file mode 100644
index 0000000000..06da61b3e9
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/CommentGenerating.py
@@ -0,0 +1,217 @@
+## @file
+# This file is used to define comment generating interface
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+CommentGenerating
+'''
+
+##
+# Import Modules
+#
+from Library.String import GetSplitValueList
+from Library.DataType import TAB_SPACE_SPLIT
+from Library.DataType import TAB_INF_GUIDTYPE_VAR
+from Library.DataType import USAGE_ITEM_NOTIFY
+from Library.DataType import ITEM_UNDEFINED
+from Library.DataType import LANGUAGE_EN_US
+
+## GenTailCommentLines
+#
+# @param TailCommentLines: the tail comment lines that need to be generated
+# @param LeadingSpaceNum: the number of leading space needed for non-first
+# line tail comment
+#
+def GenTailCommentLines (TailCommentLines, LeadingSpaceNum = 0):
+ EndOfLine = "\n"
+ TailCommentLines = TailCommentLines.rstrip(EndOfLine)
+ CommentStr = " ## " + (EndOfLine + LeadingSpaceNum * TAB_SPACE_SPLIT + \
+ " ## ").join(GetSplitValueList(TailCommentLines, \
+ EndOfLine))
+ return CommentStr
+
+## GenGenericComment
+#
+# @param CommentLines: Generic comment Text, maybe Multiple Lines
+#
+def GenGenericComment (CommentLines):
+ if not CommentLines:
+ return ''
+ EndOfLine = "\n"
+ CommentLines = CommentLines.rstrip(EndOfLine)
+ CommentStr = '## ' + (EndOfLine + '# ').join\
+ (GetSplitValueList(CommentLines, EndOfLine)) + EndOfLine
+ return CommentStr
+
+## GenGenericCommentF
+#
+# similar to GenGenericComment but will remove <EOL> at end of comment once,
+# and for line with only <EOL>, '#\n' will be generated instead of '# \n'
+#
+# @param CommentLines: Generic comment Text, maybe Multiple Lines
+# @return CommentStr: Generated comment line
+#
+def GenGenericCommentF (CommentLines, NumOfPound=1):
+ if not CommentLines:
+ return ''
+ EndOfLine = "\n"
+ #
+ # if comment end with '\n', then remove it to prevent one extra line
+ # generate later on
+ #
+ if CommentLines.endswith(EndOfLine):
+ CommentLines = CommentLines[:-1]
+ CommentLineList = GetSplitValueList(CommentLines, EndOfLine)
+ CommentStr = ''
+ for Line in CommentLineList:
+ if Line == '':
+ CommentStr += '#' * NumOfPound + '\n'
+ else:
+ CommentStr += '#' * NumOfPound + ' ' + Line + '\n'
+
+ return CommentStr
+
+
+## GenHeaderCommentSection
+#
+# Generate Header comment sections
+#
+# @param Abstract One line of abstract
+# @param Description multiple lines of Description
+# @param Copyright possible multiple copyright lines
+# @param License possible multiple license lines
+#
+def GenHeaderCommentSection(Abstract, Description, Copyright, License):
+ EndOfLine = '\n'
+ Content = ''
+
+ Content += '## @file' + EndOfLine
+ if Abstract:
+ Abstract = Abstract.rstrip(EndOfLine)
+ Content += '# ' + Abstract + EndOfLine
+ Content += '#' + EndOfLine
+ else:
+ Content += '#' + EndOfLine
+
+ if Description:
+ Description = Description.rstrip(EndOfLine)
+ Content += '# ' + (EndOfLine + '# ').join(GetSplitValueList\
+ (Description, '\n'))
+ Content += EndOfLine + '#' + EndOfLine
+
+ #
+ # There is no '#\n' line to separate multiple copyright lines in code base
+ #
+ if Copyright:
+ Copyright = Copyright.rstrip(EndOfLine)
+ Content += '# ' + (EndOfLine + '# ').join\
+ (GetSplitValueList(Copyright, '\n'))
+ Content += EndOfLine + '#' + EndOfLine
+
+ if License:
+ License = License.rstrip(EndOfLine)
+ Content += '# ' + (EndOfLine + '# ').join(GetSplitValueList\
+ (License, '\n'))
+ Content += EndOfLine + '#' + EndOfLine
+
+ Content += '##' + EndOfLine
+
+ return Content
+
+
+## GenInfPcdTailComment
+# Generate Pcd tail comment for Inf, this would be one line comment
+#
+# @param Usage: Usage type
+# @param TailCommentText: Comment text for tail comment
+#
+def GenInfPcdTailComment (Usage, TailCommentText):
+ if (Usage == ITEM_UNDEFINED) and (not TailCommentText):
+ return ''
+
+ CommentLine = TAB_SPACE_SPLIT.join([Usage, TailCommentText])
+ return GenTailCommentLines(CommentLine)
+
+## GenInfProtocolPPITailComment
+# Generate Protocol/PPI tail comment for Inf
+#
+# @param Usage: Usage type
+# @param TailCommentText: Comment text for tail comment
+#
+def GenInfProtocolPPITailComment (Usage, Notify, TailCommentText):
+ if (not Notify) and (Usage == ITEM_UNDEFINED) and (not TailCommentText):
+ return ''
+
+ if Notify:
+ CommentLine = USAGE_ITEM_NOTIFY + " ## "
+ else:
+ CommentLine = ''
+
+ CommentLine += TAB_SPACE_SPLIT.join([Usage, TailCommentText])
+ return GenTailCommentLines(CommentLine)
+
+## GenInfGuidTailComment
+# Generate Guid tail comment for Inf
+#
+# @param Usage: Usage type
+# @param TailCommentText: Comment text for tail comment
+#
+def GenInfGuidTailComment (Usage, GuidTypeList, VariableName, TailCommentText):
+ GuidType = GuidTypeList[0]
+ if (Usage == ITEM_UNDEFINED) and (GuidType == ITEM_UNDEFINED) and \
+ (not TailCommentText):
+ return ''
+
+ FirstLine = Usage + " ## " + GuidType
+ if GuidType == TAB_INF_GUIDTYPE_VAR:
+ FirstLine += ":" + VariableName
+
+ CommentLine = TAB_SPACE_SPLIT.join([FirstLine, TailCommentText])
+ return GenTailCommentLines(CommentLine)
+
+## GenDecGuidTailComment
+#
+# @param SupModuleList: Supported module type list
+#
+def GenDecTailComment (SupModuleList):
+ CommentLine = TAB_SPACE_SPLIT.join(SupModuleList)
+ return GenTailCommentLines(CommentLine)
+
+
+## _GetHelpStr
+# get HelpString from a list of HelpTextObject, the priority refer to
+# related HLD
+#
+# @param HelpTextObjList: List of HelpTextObject
+#
+# @return HelpStr: the help text string found, '' means no help text found
+#
+def _GetHelpStr(HelpTextObjList):
+ HelpStr = ''
+
+ for HelpObj in HelpTextObjList:
+ if HelpObj and HelpObj.GetLang() == LANGUAGE_EN_US:
+ HelpStr = HelpObj.GetString()
+ return HelpStr
+
+ for HelpObj in HelpTextObjList:
+ if HelpObj and HelpObj.GetLang().startswith('en'):
+ HelpStr = HelpObj.GetString()
+ return HelpStr
+
+ for HelpObj in HelpTextObjList:
+ if HelpObj and not HelpObj.GetLang():
+ HelpStr = HelpObj.GetString()
+ return HelpStr
+
+ return HelpStr \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Library/CommentParsing.py b/BaseTools/Source/Python/UPT/Library/CommentParsing.py
new file mode 100644
index 0000000000..5c07f34a74
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/CommentParsing.py
@@ -0,0 +1,451 @@
+## @file
+# This file is used to define comment parsing interface
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+CommentParsing
+'''
+
+##
+# Import Modules
+#
+import re
+
+from Library.String import GetSplitValueList
+from Library.String import CleanString2
+from Library.DataType import HEADER_COMMENT_NOT_STARTED
+from Library.DataType import TAB_COMMENT_SPLIT
+from Library.DataType import HEADER_COMMENT_LICENSE
+from Library.DataType import HEADER_COMMENT_ABSTRACT
+from Library.DataType import HEADER_COMMENT_COPYRIGHT
+from Library.DataType import HEADER_COMMENT_DESCRIPTION
+from Library.DataType import TAB_SPACE_SPLIT
+from Library.DataType import TAB_COMMA_SPLIT
+from Library.DataType import SUP_MODULE_LIST
+from Object.POM.CommonObject import TextObject
+from Object.POM.CommonObject import PcdErrorObject
+import Logger.Log as Logger
+from Logger.ToolError import FORMAT_INVALID
+from Logger.ToolError import FORMAT_NOT_SUPPORTED
+from Logger import StringTable as ST
+
+## ParseHeaderCommentSection
+#
+# Parse Header comment section lines, extract Abstract, Description, Copyright
+# , License lines
+#
+# @param CommentList: List of (Comment, LineNumber)
+# @param FileName: FileName of the comment
+#
+def ParseHeaderCommentSection(CommentList, FileName = None):
+ Abstract = ''
+ Description = ''
+ Copyright = ''
+ License = ''
+ EndOfLine = "\n"
+ STR_HEADER_COMMENT_START = "@file"
+ HeaderCommentStage = HEADER_COMMENT_NOT_STARTED
+
+ #
+ # first find the last copyright line
+ #
+ Last = 0
+ for Index in xrange(len(CommentList)-1, 0, -1):
+ Line = CommentList[Index][0]
+ if _IsCopyrightLine(Line):
+ Last = Index
+ break
+
+ for Item in CommentList:
+ Line = Item[0]
+ LineNo = Item[1]
+
+ if not Line.startswith(TAB_COMMENT_SPLIT) and Line:
+ Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_INVALID_COMMENT_FORMAT, FileName, Item[1])
+ Comment = CleanString2(Line)[1]
+ Comment = Comment.strip()
+ #
+ # if there are blank lines between License or Description, keep them as they would be
+ # indication of different block; or in the position that Abstract should be, also keep it
+ # as it indicates that no abstract
+ #
+ if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \
+ HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:
+ continue
+
+ if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:
+ if Comment.startswith(STR_HEADER_COMMENT_START):
+ HeaderCommentStage = HEADER_COMMENT_ABSTRACT
+ else:
+ License += Comment + EndOfLine
+ else:
+ if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:
+ #
+ # in case there is no abstract and description
+ #
+ if not Comment:
+ Abstract = ''
+ HeaderCommentStage = HEADER_COMMENT_DESCRIPTION
+ elif _IsCopyrightLine(Comment):
+ Result, ErrMsg = _ValidateCopyright(Comment)
+ ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)
+ Copyright += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_COPYRIGHT
+ else:
+ Abstract += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_DESCRIPTION
+ elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:
+ #
+ # in case there is no description
+ #
+ if _IsCopyrightLine(Comment):
+ Result, ErrMsg = _ValidateCopyright(Comment)
+ ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)
+ Copyright += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_COPYRIGHT
+ else:
+ Description += Comment + EndOfLine
+ elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:
+ if _IsCopyrightLine(Comment):
+ Result, ErrMsg = _ValidateCopyright(Comment)
+ ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)
+ Copyright += Comment + EndOfLine
+ else:
+ #
+ # Contents after copyright line are license, those non-copyright lines in between
+ # copyright line will be discarded
+ #
+ if LineNo > Last:
+ if License:
+ License += EndOfLine
+ License += Comment + EndOfLine
+ HeaderCommentStage = HEADER_COMMENT_LICENSE
+ else:
+ if not Comment and not License:
+ continue
+ License += Comment + EndOfLine
+
+ if not Copyright:
+ Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_COPYRIGHT_MISSING, \
+ FileName)
+
+ if not License:
+ Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_LICENSE_MISSING, FileName)
+
+ return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()
+
+## _IsCopyrightLine
+# check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"
+# followed by zero or more white space characters followed by a "(" character
+#
+# @param LineContent: the line need to be checked
+# @return: True if current line is copyright line, False else
+#
+def _IsCopyrightLine (LineContent):
+ LineContent = LineContent.upper()
+ Result = False
+
+ ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)
+ if ReIsCopyrightRe.search(LineContent):
+ Result = True
+
+ return Result
+
+## ParseGenericComment
+#
+# @param GenericComment: Generic comment list, element of
+# (CommentLine, LineNum)
+# @param ContainerFile: Input value for filename of Dec file
+#
+def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None):
+ if ContainerFile:
+ pass
+ HelpTxt = None
+ HelpStr = ''
+
+ for Item in GenericComment:
+ CommentLine = Item[0]
+ Comment = CleanString2(CommentLine)[1]
+ if SkipTag is not None and Comment.startswith(SkipTag):
+ Comment = Comment.replace(SkipTag, '', 1)
+ HelpStr += Comment + '\n'
+
+ if HelpStr:
+ HelpTxt = TextObject()
+ if HelpStr.endswith('\n') and not HelpStr.endswith('\n\n') and HelpStr != '\n':
+ HelpStr = HelpStr[:-1]
+ HelpTxt.SetString(HelpStr)
+
+ return HelpTxt
+
+
+## ParseDecPcdGenericComment
+#
+# @param GenericComment: Generic comment list, element of (CommentLine,
+# LineNum)
+# @param ContainerFile: Input value for filename of Dec file
+#
+def ParseDecPcdGenericComment (GenericComment, ContainerFile):
+ HelpStr = ''
+ PcdErr = None
+
+ for (CommentLine, LineNum) in GenericComment:
+ Comment = CleanString2(CommentLine)[1]
+ if Comment.startswith("@ValidRange"):
+ if PcdErr:
+ Logger.Error('Parser',
+ FORMAT_NOT_SUPPORTED,
+ ST.WRN_MULTI_PCD_RANGES,
+ File = ContainerFile,
+ Line = LineNum)
+ ValidRange = Comment.replace("@ValidRange", "", 1)
+ if _CheckRangeExpression(ValidRange):
+ PcdErr = PcdErrorObject()
+ PcdErr.SetValidValueRange(ValidRange)
+ elif Comment.startswith("@ValidList"):
+ if PcdErr:
+ Logger.Error('Parser',
+ FORMAT_NOT_SUPPORTED,
+ ST.WRN_MULTI_PCD_RANGES,
+ File = ContainerFile,
+ Line = LineNum)
+ ValidValue = Comment.replace("@ValidList", "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT)
+ PcdErr = PcdErrorObject()
+ PcdErr.SetValidValue(ValidValue)
+ elif Comment.startswith("@Expression"):
+ if PcdErr:
+ Logger.Error('Parser',
+ FORMAT_NOT_SUPPORTED,
+ ST.WRN_MULTI_PCD_RANGES,
+ File = ContainerFile,
+ Line = LineNum)
+ Expression = Comment.replace("@Expression", "", 1)
+ if _CheckRangeExpression(Expression):
+ PcdErr = PcdErrorObject()
+ PcdErr.SetExpression(Expression)
+ else:
+ HelpStr += Comment + '\n'
+
+ #
+ # remove the last EOL if the comment is of format 'FOO\n'
+ #
+ if HelpStr.endswith('\n'):
+ if HelpStr != '\n' and not HelpStr.endswith('\n\n'):
+ HelpStr = HelpStr[:-1]
+
+ return HelpStr, PcdErr
+
+## ParseDecPcdTailComment
+#
+# @param TailCommentList: Tail comment list of Pcd, item of format (Comment, LineNum)
+# @param ContainerFile: Input value for filename of Dec file
+# @retVal SupModuleList: The supported module type list detected
+# @retVal HelpStr: The generic help text string detected
+#
+def ParseDecPcdTailComment (TailCommentList, ContainerFile):
+ assert(len(TailCommentList) == 1)
+ TailComment = TailCommentList[0][0]
+ LineNum = TailCommentList[0][1]
+
+ Comment = TailComment.lstrip(" #")
+
+ ReFindFirstWordRe = re.compile(r"""^([^ #]*)""", re.DOTALL)
+
+ #
+ # get first word and compare with SUP_MODULE_LIST
+ #
+ MatchObject = ReFindFirstWordRe.match(Comment)
+ if not (MatchObject and MatchObject.group(1) in SUP_MODULE_LIST):
+ return None, Comment
+
+ #
+ # parse line, it must have supported module type specified
+ #
+ if Comment.find(TAB_COMMENT_SPLIT) == -1:
+ Comment += TAB_COMMENT_SPLIT
+ SupMode, HelpStr = GetSplitValueList(Comment, TAB_COMMENT_SPLIT, 1)
+ SupModuleList = []
+ for Mod in GetSplitValueList(SupMode, TAB_SPACE_SPLIT):
+ if not Mod:
+ continue
+ elif Mod not in SUP_MODULE_LIST:
+ Logger.Error("UPT",
+ FORMAT_INVALID,
+ ST.WRN_INVALID_MODULE_TYPE%Mod,
+ ContainerFile,
+ LineNum)
+ else:
+ SupModuleList.append(Mod)
+
+ return SupModuleList, HelpStr
+
+
+## _CheckRangeExpression
+#
+# @param Expression: Pcd range expression
+#
+def _CheckRangeExpression(Expression):
+ #
+ # check grammar for Pcd range expression is not required yet
+ #
+ if Expression:
+ pass
+ return True
+
+## ValidateCopyright
+#
+#
+#
+def ValidateCopyright(Result, ErrType, FileName, LineNo, ErrMsg):
+ if not Result:
+ Logger.Warn("\nUPT", ErrType, FileName, LineNo, ErrMsg)
+
+## _ValidateCopyright
+#
+# @param Line: Line that contains copyright information, # stripped
+#
+# @retval Result: True if line is conformed to Spec format, False else
+# @retval ErrMsg: the detailed error description
+#
+def _ValidateCopyright(Line):
+ if Line:
+ pass
+ Result = True
+ ErrMsg = ''
+
+ return Result, ErrMsg
+
+def GenerateTokenList (Comment):
+ #
+ # Tokenize Comment using '#' and ' ' as token seperators
+ #
+ RelplacedComment = None
+ while Comment != RelplacedComment:
+ RelplacedComment = Comment
+ Comment = Comment.replace('##', '#').replace(' ', ' ').replace(' ', '#').strip('# ')
+ return Comment.split('#')
+
+
+#
+# Comment - Comment to parse
+# TypeTokens - A dictionary of type token synonyms
+# RemoveTokens - A list of tokens to remove from help text
+# ParseVariable - True for parsing [Guids]. Otherwise False
+#
+def ParseComment (Comment, UsageTokens, TypeTokens, RemoveTokens, ParseVariable):
+ #
+ # Initialize return values
+ #
+ Usage = None
+ Type = None
+ String = None
+ HelpText = None
+
+ Comment = Comment[0]
+
+ NumTokens = 2
+ if ParseVariable:
+ #
+ # Remove white space around first instance of ':' from Comment if 'Variable'
+ # is in front of ':' and Variable is the 1st or 2nd token in Comment.
+ #
+ List = Comment.split(':', 1)
+ if len(List) > 1:
+ SubList = GenerateTokenList (List[0].strip())
+ if len(SubList) in [1, 2] and SubList[-1] == 'Variable':
+ if List[1].strip().find('L"') == 0:
+ Comment = List[0].strip() + ':' + List[1].strip()
+
+ #
+ # Remove first instance of L"<VariableName> from Comment and put into String
+ # if and only if L"<VariableName>" is the 1st token, the 2nd token. Or
+ # L"<VariableName>" is the third token immediately following 'Variable:'.
+ #
+ End = -1
+ Start = Comment.find('Variable:L"')
+ if Start >= 0:
+ String = Comment[Start + 9:]
+ End = String[2:].find('"')
+ else:
+ Start = Comment.find('L"')
+ if Start >= 0:
+ String = Comment[Start:]
+ End = String[2:].find('"')
+ if End >= 0:
+ SubList = GenerateTokenList (Comment[:Start])
+ if len(SubList) < 2:
+ Comment = Comment[:Start] + String[End + 3:]
+ String = String[:End + 3]
+ Type = 'Variable'
+ NumTokens = 1
+
+ #
+ # Initialze HelpText to Comment.
+ # Content will be remove from HelpText as matching tokens are found
+ #
+ HelpText = Comment
+
+ #
+ # Tokenize Comment using '#' and ' ' as token seperators
+ #
+ List = GenerateTokenList (Comment)
+
+ #
+ # Search first two tokens for Usage and Type and remove any matching tokens
+ # from HelpText
+ #
+ for Token in List[0:NumTokens]:
+ if Usage == None and Token in UsageTokens:
+ Usage = UsageTokens[Token]
+ HelpText = HelpText.replace(Token, '')
+ if Usage != None or not ParseVariable:
+ for Token in List[0:NumTokens]:
+ if Type == None and Token in TypeTokens:
+ Type = TypeTokens[Token]
+ HelpText = HelpText.replace(Token, '')
+ if Usage != None:
+ for Token in List[0:NumTokens]:
+ if Token in RemoveTokens:
+ HelpText = HelpText.replace(Token, '')
+
+ #
+ # If no Usage token is present and set Usage to UNDEFINED
+ #
+ if Usage == None:
+ Usage = 'UNDEFINED'
+
+ #
+ # If no Type token is present and set Type to UNDEFINED
+ #
+ if Type == None:
+ Type = 'UNDEFINED'
+
+ #
+ # If Type is not 'Variable:', then set String to None
+ #
+ if Type != 'Variable':
+ String = None
+
+ #
+ # Strip ' ' and '#' from the beginning of HelpText
+ # If HelpText is an empty string after all parsing is
+ # complete then set HelpText to None
+ #
+ HelpText = HelpText.lstrip('# ')
+ if HelpText == '':
+ HelpText = None
+
+ #
+ # Return parsing results
+ #
+ return Usage, Type, String, HelpText
diff --git a/BaseTools/Source/Python/UPT/Library/DataType.py b/BaseTools/Source/Python/UPT/Library/DataType.py
new file mode 100644
index 0000000000..da6b69d82b
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/DataType.py
@@ -0,0 +1,919 @@
+## @file
+# This file is used to define class for data type structure
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+DataType
+'''
+
+##
+# Module List Items
+#
+MODULE_LIST = ["BASE",
+ "SEC",
+ "PEI_CORE",
+ "PEIM",
+ "DXE_CORE",
+ "DXE_DRIVER",
+ "SMM_CORE",
+ "DXE_RUNTIME_DRIVER",
+ "DXE_SAL_DRIVER",
+ "DXE_SMM_DRIVER",
+ "UEFI_DRIVER",
+ "UEFI_APPLICATION",
+ "USER_DEFINED"]
+
+VALID_DEPEX_MODULE_TYPE_LIST = ["PEIM",
+ "DXE_DRIVER",
+ "DXE_SMM_DRIVER",
+ "DXE_RUNTIME_DRIVER",
+ "DXE_SAL_DRIVER",
+ "UEFI_DRIVER",
+ ]
+##
+# Usage List Items
+#
+USAGE_LIST = ["CONSUMES",
+ "SOMETIMES_CONSUMES",
+ "PRODUCES",
+ "SOMETIMES_PRODUCES"]
+
+LANGUAGE_EN_US = 'en-US'
+
+USAGE_ITEM_PRODUCES = 'PRODUCES'
+USAGE_ITEM_SOMETIMES_PRODUCES = 'SOMETIMES_PRODUCES'
+USAGE_ITEM_CONSUMES = 'CONSUMES'
+USAGE_ITEM_SOMETIMES_CONSUMES = 'SOMETIMES_CONSUMES'
+USAGE_ITEM_TO_START = 'TO_START'
+USAGE_ITEM_BY_START = 'BY_START'
+USAGE_ITEM_NOTIFY = 'NOTIFY'
+USAGE_ITEM_UNDEFINED = 'UNDEFINED'
+
+USAGE_CONSUMES_LIST = [USAGE_ITEM_CONSUMES,
+ 'CONSUMED',
+ 'ALWAYS_CONSUMED',
+ 'ALWAYS_CONSUMES'
+ ]
+
+USAGE_PRODUCES_LIST = [USAGE_ITEM_PRODUCES,
+ 'PRODUCED',
+ 'ALWAYS_PRODUCED',
+ 'ALWAYS_PRODUCES'
+ ]
+
+USAGE_SOMETIMES_PRODUCES_LIST = [USAGE_ITEM_SOMETIMES_PRODUCES,
+ 'SOMETIMES_PRODUCED'
+ ]
+
+USAGE_SOMETIMES_CONSUMES_LIST = [USAGE_ITEM_SOMETIMES_CONSUMES,
+ 'SOMETIMES_CONSUMED'
+ ]
+
+ITEM_UNDEFINED = 'UNDEFINED'
+
+
+#
+# Dictionary of usage tokens and their synonmys
+#
+ALL_USAGE_TOKENS = {
+ "PRODUCES" : "PRODUCES",
+ "PRODUCED" : "PRODUCES",
+ "ALWAYS_PRODUCES" : "PRODUCES",
+ "ALWAYS_PRODUCED" : "PRODUCES",
+ "SOMETIMES_PRODUCES" : "SOMETIMES_PRODUCES",
+ "SOMETIMES_PRODUCED" : "SOMETIMES_PRODUCES",
+ "CONSUMES" : "CONSUMES",
+ "CONSUMED" : "CONSUMES",
+ "ALWAYS_CONSUMES" : "CONSUMES",
+ "ALWAYS_CONSUMED" : "CONSUMES",
+ "SOMETIMES_CONSUMES" : "SOMETIMES_CONSUMES",
+ "SOMETIMES_CONSUMED" : "SOMETIMES_CONSUMES",
+ "SOMETIME_CONSUMES" : "SOMETIMES_CONSUMES",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+PROTOCOL_USAGE_TOKENS = {
+ "TO_START" : "TO_START",
+ "BY_START" : "BY_START"
+ }
+
+PROTOCOL_USAGE_TOKENS.update (ALL_USAGE_TOKENS)
+
+#
+# Dictionary of GUID type tokens
+#
+GUID_TYPE_TOKENS = {
+ "Event" : "Event",
+ "File" : "File",
+ "FV" : "FV",
+ "GUID" : "GUID",
+ "Guid" : "GUID",
+ "HII" : "HII",
+ "HOB" : "HOB",
+ "Hob" : "HOB",
+ "Hob:" : "HOB",
+ "SystemTable" : "SystemTable",
+ "TokenSpaceGuid" : "TokenSpaceGuid",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+#
+# Dictionary of Protocol Notify tokens and their synonyms
+#
+PROTOCOL_NOTIFY_TOKENS = {
+ "NOTIFY" : "NOTIFY",
+ "PROTOCOL_NOTIFY" : "NOTIFY",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+#
+# Dictionary of PPI Notify tokens and their synonyms
+#
+PPI_NOTIFY_TOKENS = {
+ "NOTIFY" : "NOTIFY",
+ "PPI_NOTIFY" : "NOTIFY",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+EVENT_TOKENS = {
+ "EVENT_TYPE_PERIODIC_TIMER" : "EVENT_TYPE_PERIODIC_TIMER",
+ "EVENT_TYPE_RELATIVE_TIMER" : "EVENT_TYPE_RELATIVE_TIMER",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+BOOTMODE_TOKENS = {
+ "FULL" : "FULL",
+ "MINIMAL" : "MINIMAL",
+ "NO_CHANGE" : "NO_CHANGE",
+ "DIAGNOSTICS" : "DIAGNOSTICS",
+ "DEFAULT" : "DEFAULT",
+ "S2_RESUME" : "S2_RESUME",
+ "S3_RESUME" : "S3_RESUME",
+ "S4_RESUME" : "S4_RESUME",
+ "S5_RESUME" : "S5_RESUME",
+ "FLASH_UPDATE" : "FLASH_UPDATE",
+ "RECOVERY_FULL" : "RECOVERY_FULL",
+ "RECOVERY_MINIMAL" : "RECOVERY_MINIMAL",
+ "RECOVERY_NO_CHANGE" : "RECOVERY_NO_CHANGE",
+ "RECOVERY_DIAGNOSTICS" : "RECOVERY_DIAGNOSTICS",
+ "RECOVERY_DEFAULT" : "RECOVERY_DEFAULT",
+ "RECOVERY_S2_RESUME" : "RECOVERY_S2_RESUME",
+ "RECOVERY_S3_RESUME" : "RECOVERY_S3_RESUME",
+ "RECOVERY_S4_RESUME" : "RECOVERY_S4_RESUME",
+ "RECOVERY_S5_RESUME" : "RECOVERY_S5_RESUME",
+ "RECOVERY_FLASH_UPDATE" : "RECOVERY_FLASH_UPDATE",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+HOB_TOKENS = {
+ "PHIT" : "PHIT",
+ "MEMORY_ALLOCATION" : "MEMORY_ALLOCATION",
+ "LOAD_PEIM" : "LOAD_PEIM",
+ "RESOURCE_DESCRIPTOR" : "RESOURCE_DESCRIPTOR",
+ "FIRMWARE_VOLUME" : "FIRMWARE_VOLUME",
+ "UNDEFINED" : "UNDEFINED"
+ }
+
+##
+# Usage List Items for Protocol
+#
+PROTOCOL_USAGE_LIST = USAGE_LIST + ["TO_START", "BY_START"]
+
+##
+# End of Line
+# Use this but not os.linesep for os.linesep has bug in it.
+#
+END_OF_LINE = '\n'
+
+##
+# Arch List Items
+#
+ARCH_LIST = ["IA32",
+ "X64",
+ "IPF",
+ "EBC",
+ "COMMON"]
+##
+# PCD driver type list items
+#
+PCD_DIRVER_TYPE_LIST = ["PEI_PCD_DRIVER", "DXE_PCD_DRIVER"]
+
+##
+# Boot Mode List Items
+#
+BOOT_MODE_LIST = ["FULL",
+ "MINIMAL",
+ "NO_CHANGE",
+ "DIAGNOSTICS",
+ "DEFAULT",
+ "S2_RESUME",
+ "S3_RESUME",
+ "S4_RESUME",
+ "S5_RESUME",
+ "FLASH_UPDATE",
+ "RECOVERY_FULL",
+ "RECOVERY_MINIMAL",
+ "RECOVERY_NO_CHANGE",
+ "RECOVERY_DIAGNOSTICS",
+ "RECOVERY_DEFAULT",
+ "RECOVERY_S2_RESUME",
+ "RECOVERY_S3_RESUME",
+ "RECOVERY_S4_RESUME",
+ "RECOVERY_S5_RESUME",
+ "RECOVERY_FLASH_UPDATE"]
+
+##
+# Event Type List Items
+#
+EVENT_TYPE_LIST = ["EVENT_TYPE_PERIODIC_TIMER",
+ "EVENT_TYPE_RELATIVE_TIMER"]
+
+##
+# Hob Type List Items
+#
+HOB_TYPE_LIST = ["PHIT",
+ "MEMORY_ALLOCATION",
+ "RESOURCE_DESCRIPTOR",
+ "FIRMWARE_VOLUME",
+ "LOAD_PEIM"]
+
+##
+# GUID_TYPE_LIST
+#
+GUID_TYPE_LIST = ["Event", "File", "FV", "GUID", "HII", "HOB",
+ "SystemTable", "TokenSpaceGuid", "Variable"]
+##
+# PCD Usage Type List of Package
+#
+PCD_USAGE_TYPE_LIST_OF_PACKAGE = ["FeatureFlag", "PatchableInModule",
+ "FixedAtBuild", "Dynamic", "DynamicEx"]
+
+##
+# PCD Usage Type List of Module
+#
+PCD_USAGE_TYPE_LIST_OF_MODULE = ["FEATUREPCD", "PATCHPCD", "FIXEDPCD", "PCD", "PCDEX"]
+##
+# PCD Usage Type List of UPT
+#
+PCD_USAGE_TYPE_LIST_OF_UPT = PCD_USAGE_TYPE_LIST_OF_MODULE
+
+##
+# Binary File Type List
+#
+BINARY_FILE_TYPE_LIST = ["GUID", "PE32", "PIC", "TE", "DXE_DEPEX", "VER", "UI", "COMPAT16", "FV", "BIN", "RAW",
+ "ACPI", "ASL",
+ "PEI_DEPEX",
+ "SMM_DEPEX",
+ "SUBTYPE_GUID"
+ ]
+BINARY_FILE_TYPE_LIST_IN_UDP = \
+ ["GUID", "FREEFORM",
+ "UEFI_IMAGE", "PE32", "PIC",
+ "PEI_DEPEX",
+ "DXE_DEPEX",
+ "SMM_DEPEX",
+ "FV", "TE",
+ "BIN", "VER", "UI"
+ ]
+
+##
+# Possible values for COMPONENT_TYPE, and their descriptions, are listed in
+# the table,
+# "Component (module) Types." For each component, the BASE_NAME and
+# COMPONENT_TYPE
+# are required. The COMPONENT_TYPE definition is case sensitive.
+#
+COMPONENT_TYPE_LIST = [
+ "APPLICATION",
+ "ACPITABLE",
+ "APRIORI",
+ "BINARY",
+ "BS_DRIVER",
+ "CONFIG",
+ "FILE",
+ "FVIMAGEFILE",
+ "LIBRARY",
+ "LOGO",
+ "LEGACY16",
+ "MICROCODE",
+ "PE32_PEIM",
+ "PEI_CORE",
+ "RAWFILE",
+ "RT_DRIVER",
+ "SAL_RT_DRIVER",
+ "SECURITY_CORE",
+ "COMBINED_PEIM_DRIVER",
+ "PIC_PEIM",
+ "RELOCATABLE_PEIM"
+ ]
+
+##
+# Common Definitions
+#
+TAB_SPLIT = '.'
+TAB_COMMENT_EDK1_START = '/*'
+TAB_COMMENT_EDK1_END = '*/'
+TAB_COMMENT_EDK1_SPLIT = '//'
+TAB_COMMENT_SPLIT = '#'
+TAB_EQUAL_SPLIT = '='
+TAB_DEQUAL_SPLIT = '=='
+TAB_VALUE_SPLIT = '|'
+TAB_COMMA_SPLIT = ','
+TAB_SPACE_SPLIT = ' '
+TAB_UNDERLINE_SPLIT = '_'
+TAB_SEMI_COLON_SPLIT = ';'
+TAB_COLON_SPLIT = ':'
+TAB_SECTION_START = '['
+TAB_SECTION_END = ']'
+TAB_OPTION_START = '<'
+TAB_OPTION_END = '>'
+TAB_SLASH = '\\'
+TAB_BACK_SLASH = '/'
+TAB_SPECIAL_COMMENT = '##'
+TAB_HEADER_COMMENT = '@file'
+TAB_STAR = "*"
+
+TAB_EDK_SOURCE = '$(EDK_SOURCE)'
+TAB_EFI_SOURCE = '$(EFI_SOURCE)'
+TAB_WORKSPACE = '$(WORKSPACE)'
+
+TAB_ARCH_NULL = ''
+TAB_ARCH_COMMON = 'COMMON'
+TAB_ARCH_IA32 = 'IA32'
+TAB_ARCH_X64 = 'X64'
+TAB_ARCH_IPF = 'IPF'
+TAB_ARCH_ARM = 'ARM'
+TAB_ARCH_EBC = 'EBC'
+
+ARCH_LIST = \
+[TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_EBC]
+
+SUP_MODULE_BASE = 'BASE'
+SUP_MODULE_SEC = 'SEC'
+SUP_MODULE_PEI_CORE = 'PEI_CORE'
+SUP_MODULE_PEIM = 'PEIM'
+SUP_MODULE_DXE_CORE = 'DXE_CORE'
+SUP_MODULE_DXE_DRIVER = 'DXE_DRIVER'
+SUP_MODULE_DXE_RUNTIME_DRIVER = 'DXE_RUNTIME_DRIVER'
+SUP_MODULE_DXE_SAL_DRIVER = 'DXE_SAL_DRIVER'
+SUP_MODULE_DXE_SMM_DRIVER = 'DXE_SMM_DRIVER'
+SUP_MODULE_UEFI_DRIVER = 'UEFI_DRIVER'
+SUP_MODULE_UEFI_APPLICATION = 'UEFI_APPLICATION'
+SUP_MODULE_USER_DEFINED = 'USER_DEFINED'
+SUP_MODULE_SMM_CORE = 'SMM_CORE'
+
+SUP_MODULE_LIST = \
+[SUP_MODULE_BASE, SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, \
+SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, \
+ SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, \
+ SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_UEFI_DRIVER, \
+ SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, \
+ SUP_MODULE_SMM_CORE]
+SUP_MODULE_LIST_STRING = TAB_VALUE_SPLIT.join(l for l in SUP_MODULE_LIST)
+
+EDK_COMPONENT_TYPE_LIBRARY = 'LIBRARY'
+EDK_COMPONENT_TYPE_SECUARITY_CORE = 'SECUARITY_CORE'
+EDK_COMPONENT_TYPE_PEI_CORE = 'PEI_CORE'
+EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER = 'COMBINED_PEIM_DRIVER'
+EDK_COMPONENT_TYPE_PIC_PEIM = 'PIC_PEIM'
+EDK_COMPONENT_TYPE_RELOCATABLE_PEIM = 'RELOCATABLE_PEIM'
+EDK_COMPONENT_TYPE_BS_DRIVER = 'BS_DRIVER'
+EDK_COMPONENT_TYPE_RT_DRIVER = 'RT_DRIVER'
+EDK_COMPONENT_TYPE_SAL_RT_DRIVER = 'SAL_RT_DRIVER'
+EDK_COMPONENT_TYPE_APPLICATION = 'APPLICATION'
+EDK_NAME = 'EDK'
+EDKII_NAME = 'EDKII'
+
+BINARY_FILE_TYPE_FW = 'FW'
+BINARY_FILE_TYPE_GUID = 'GUID'
+BINARY_FILE_TYPE_PREEFORM = 'PREEFORM'
+BINARY_FILE_TYPE_UEFI_APP = 'UEFI_APP'
+BINARY_FILE_TYPE_UNI_UI = 'UNI_UI'
+BINARY_FILE_TYPE_SEC_UI = 'SEC_UI'
+BINARY_FILE_TYPE_UNI_VER = 'UNI_VER'
+BINARY_FILE_TYPE_SEC_VER = 'SEC_VER'
+BINARY_FILE_TYPE_LIB = 'LIB'
+BINARY_FILE_TYPE_PE32 = 'PE32'
+BINARY_FILE_TYPE_PIC = 'PIC'
+BINARY_FILE_TYPE_PEI_DEPEX = 'PEI_DEPEX'
+BINARY_FILE_TYPE_DXE_DEPEX = 'DXE_DEPEX'
+BINARY_FILE_TYPE_SMM_DEPEX = 'SMM_DEPEX'
+BINARY_FILE_TYPE_TE = 'TE'
+BINARY_FILE_TYPE_VER = 'VER'
+BINARY_FILE_TYPE_UI = 'UI'
+BINARY_FILE_TYPE_BIN = 'BIN'
+BINARY_FILE_TYPE_FV = 'FV'
+BINARY_FILE_TYPE_UI_LIST = [BINARY_FILE_TYPE_UNI_UI,
+ BINARY_FILE_TYPE_SEC_UI,
+ BINARY_FILE_TYPE_UI
+ ]
+BINARY_FILE_TYPE_VER_LIST = [BINARY_FILE_TYPE_UNI_VER,
+ BINARY_FILE_TYPE_SEC_VER,
+ BINARY_FILE_TYPE_VER
+ ]
+
+DEPEX_SECTION_LIST = ['<PEI_DEPEX>',
+ '<DXE_DEPEX>',
+ '<SMM_DEPEX>'
+ ]
+
+PLATFORM_COMPONENT_TYPE_LIBRARY = 'LIBRARY'
+PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS = 'LIBRARY_CLASS'
+PLATFORM_COMPONENT_TYPE_MODULE = 'MODULE'
+
+TAB_LIBRARIES = 'Libraries'
+
+TAB_SOURCE = 'Source'
+TAB_SOURCES = 'Sources'
+TAB_SOURCES_COMMON = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_SOURCES_IA32 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_SOURCES_X64 = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_X64
+TAB_SOURCES_IPF = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_IPF
+TAB_SOURCES_ARM = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_SOURCES_EBC = TAB_SOURCES + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_BINARIES = 'Binaries'
+TAB_BINARIES_COMMON = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_BINARIES_IA32 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_BINARIES_X64 = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_X64
+TAB_BINARIES_IPF = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_IPF
+TAB_BINARIES_ARM = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_BINARIES_EBC = TAB_BINARIES + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_INCLUDES = 'Includes'
+TAB_INCLUDES_COMMON = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_INCLUDES_IA32 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_INCLUDES_X64 = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_X64
+TAB_INCLUDES_IPF = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_IPF
+TAB_INCLUDES_ARM = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_INCLUDES_EBC = TAB_INCLUDES + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_GUIDS = 'Guids'
+TAB_GUIDS_COMMON = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_GUIDS_IA32 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_GUIDS_X64 = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_X64
+TAB_GUIDS_IPF = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_IPF
+TAB_GUIDS_ARM = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_GUIDS_EBC = TAB_GUIDS + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PROTOCOLS = 'Protocols'
+TAB_PROTOCOLS_COMMON = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PROTOCOLS_IA32 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PROTOCOLS_X64 = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_X64
+TAB_PROTOCOLS_IPF = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_IPF
+TAB_PROTOCOLS_ARM = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PROTOCOLS_EBC = TAB_PROTOCOLS + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PPIS = 'Ppis'
+TAB_PPIS_COMMON = TAB_PPIS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PPIS_IA32 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PPIS_X64 = TAB_PPIS + TAB_SPLIT + TAB_ARCH_X64
+TAB_PPIS_IPF = TAB_PPIS + TAB_SPLIT + TAB_ARCH_IPF
+TAB_PPIS_ARM = TAB_PPIS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PPIS_EBC = TAB_PPIS + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_LIBRARY_CLASSES = 'LibraryClasses'
+TAB_LIBRARY_CLASSES_COMMON = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_LIBRARY_CLASSES_IA32 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_LIBRARY_CLASSES_X64 = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_X64
+TAB_LIBRARY_CLASSES_IPF = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_IPF
+TAB_LIBRARY_CLASSES_ARM = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_LIBRARY_CLASSES_EBC = TAB_LIBRARY_CLASSES + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PACKAGES = 'Packages'
+TAB_PACKAGES_COMMON = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PACKAGES_IA32 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PACKAGES_X64 = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_X64
+TAB_PACKAGES_IPF = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_IPF
+TAB_PACKAGES_ARM = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PACKAGES_EBC = TAB_PACKAGES + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PCDS = 'Pcds'
+TAB_PCDS_FIXED_AT_BUILD = 'FixedAtBuild'
+TAB_PCDS_PATCHABLE_IN_MODULE = 'PatchableInModule'
+TAB_PCDS_FEATURE_FLAG = 'FeatureFlag'
+TAB_PCDS_DYNAMIC_EX = 'DynamicEx'
+TAB_PCDS_DYNAMIC_EX_DEFAULT = 'DynamicExDefault'
+TAB_PCDS_DYNAMIC_EX_VPD = 'DynamicExVpd'
+TAB_PCDS_DYNAMIC_EX_HII = 'DynamicExHii'
+TAB_PCDS_DYNAMIC = 'Dynamic'
+TAB_PCDS_DYNAMIC_DEFAULT = 'DynamicDefault'
+TAB_PCDS_DYNAMIC_VPD = 'DynamicVpd'
+TAB_PCDS_DYNAMIC_HII = 'DynamicHii'
+
+TAB_PTR_TYPE_PCD = 'VOID*'
+
+PCD_DYNAMIC_TYPE_LIST = [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, \
+ TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_HII]
+PCD_DYNAMIC_EX_TYPE_LIST = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, \
+ TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
+
+## Dynamic-ex PCD types
+#
+gDYNAMIC_EX_PCD = [TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, \
+ TAB_PCDS_DYNAMIC_EX_VPD, TAB_PCDS_DYNAMIC_EX_HII]
+
+TAB_PCDS_FIXED_AT_BUILD_NULL = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD
+TAB_PCDS_FIXED_AT_BUILD_COMMON = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \
+TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_FIXED_AT_BUILD_IA32 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \
+TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_FIXED_AT_BUILD_X64 = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \
+TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_FIXED_AT_BUILD_IPF = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \
+TAB_SPLIT + TAB_ARCH_IPF
+TAB_PCDS_FIXED_AT_BUILD_ARM = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \
+TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_FIXED_AT_BUILD_EBC = TAB_PCDS + TAB_PCDS_FIXED_AT_BUILD + \
+TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PCDS_PATCHABLE_IN_MODULE_NULL = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE
+TAB_PCDS_PATCHABLE_IN_MODULE_COMMON = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE \
++ TAB_SPLIT + TAB_ARCH_COMMON
+TAB_PCDS_PATCHABLE_IN_MODULE_IA32 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \
+TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_PATCHABLE_IN_MODULE_X64 = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \
+TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_PATCHABLE_IN_MODULE_IPF = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \
+TAB_SPLIT + TAB_ARCH_IPF
+TAB_PCDS_PATCHABLE_IN_MODULE_ARM = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \
+TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_PATCHABLE_IN_MODULE_EBC = TAB_PCDS + TAB_PCDS_PATCHABLE_IN_MODULE + \
+TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PCDS_FEATURE_FLAG_NULL = TAB_PCDS + TAB_PCDS_FEATURE_FLAG
+TAB_PCDS_FEATURE_FLAG_COMMON = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT \
++ TAB_ARCH_COMMON
+TAB_PCDS_FEATURE_FLAG_IA32 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \
+TAB_ARCH_IA32
+TAB_PCDS_FEATURE_FLAG_X64 = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \
+TAB_ARCH_X64
+TAB_PCDS_FEATURE_FLAG_IPF = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \
+TAB_ARCH_IPF
+TAB_PCDS_FEATURE_FLAG_ARM = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \
+TAB_ARCH_ARM
+TAB_PCDS_FEATURE_FLAG_EBC = TAB_PCDS + TAB_PCDS_FEATURE_FLAG + TAB_SPLIT + \
+TAB_ARCH_EBC
+
+TAB_PCDS_DYNAMIC_EX_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX
+TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_DEFAULT
+TAB_PCDS_DYNAMIC_EX_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_HII
+TAB_PCDS_DYNAMIC_EX_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_EX_VPD
+TAB_PCDS_DYNAMIC_EX_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \
+TAB_ARCH_COMMON
+TAB_PCDS_DYNAMIC_EX_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \
+TAB_ARCH_IA32
+TAB_PCDS_DYNAMIC_EX_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \
+TAB_ARCH_X64
+TAB_PCDS_DYNAMIC_EX_IPF = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \
+TAB_ARCH_IPF
+TAB_PCDS_DYNAMIC_EX_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \
+TAB_ARCH_ARM
+TAB_PCDS_DYNAMIC_EX_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC_EX + TAB_SPLIT + \
+TAB_ARCH_EBC
+
+TAB_PCDS_DYNAMIC_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC
+TAB_PCDS_DYNAMIC_DEFAULT_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_DEFAULT
+TAB_PCDS_DYNAMIC_HII_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_HII
+TAB_PCDS_DYNAMIC_VPD_NULL = TAB_PCDS + TAB_PCDS_DYNAMIC_VPD
+TAB_PCDS_DYNAMIC_COMMON = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + \
+TAB_ARCH_COMMON
+TAB_PCDS_DYNAMIC_IA32 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IA32
+TAB_PCDS_DYNAMIC_X64 = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_X64
+TAB_PCDS_DYNAMIC_IPF = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_IPF
+TAB_PCDS_DYNAMIC_ARM = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_ARM
+TAB_PCDS_DYNAMIC_EBC = TAB_PCDS + TAB_PCDS_DYNAMIC + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_PCD_DYNAMIC_TYPE_LIST = [TAB_PCDS_DYNAMIC_DEFAULT_NULL, \
+ TAB_PCDS_DYNAMIC_VPD_NULL, \
+ TAB_PCDS_DYNAMIC_HII_NULL]
+TAB_PCD_DYNAMIC_EX_TYPE_LIST = [TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, \
+ TAB_PCDS_DYNAMIC_EX_VPD_NULL, \
+ TAB_PCDS_DYNAMIC_EX_HII_NULL]
+
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE = \
+'PcdLoadFixAddressPeiCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE = \
+'PcdLoadFixAddressBootTimeCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE = \
+'PcdLoadFixAddressRuntimeCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE = \
+'PcdLoadFixAddressSmmCodePageNumber'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE_DATA_TYPE = 'UINT32'
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_LIST = \
+[TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_PEI_PAGE_SIZE, \
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_DXE_PAGE_SIZE, \
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_RUNTIME_PAGE_SIZE, \
+TAB_PCDS_PATCHABLE_LOAD_FIX_ADDRESS_SMM_PAGE_SIZE]
+PCD_SECTION_LIST = [TAB_PCDS_FIXED_AT_BUILD_NULL.upper(), \
+ TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper(), \
+ TAB_PCDS_FEATURE_FLAG_NULL.upper(), \
+ TAB_PCDS_DYNAMIC_EX_NULL.upper(), \
+ TAB_PCDS_DYNAMIC_NULL.upper()]
+INF_PCD_SECTION_LIST = ["FixedPcd".upper(), "FeaturePcd".upper(), \
+ "PatchPcd".upper(), "Pcd".upper(), "PcdEx".upper()]
+
+TAB_DEPEX = 'Depex'
+TAB_DEPEX_COMMON = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_DEPEX_IA32 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IA32
+TAB_DEPEX_X64 = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_X64
+TAB_DEPEX_IPF = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_IPF
+TAB_DEPEX_ARM = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_ARM
+TAB_DEPEX_EBC = TAB_DEPEX + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_SKUIDS = 'SkuIds'
+
+TAB_LIBRARIES = 'Libraries'
+TAB_LIBRARIES_COMMON = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_LIBRARIES_IA32 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IA32
+TAB_LIBRARIES_X64 = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_X64
+TAB_LIBRARIES_IPF = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_IPF
+TAB_LIBRARIES_ARM = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_ARM
+TAB_LIBRARIES_EBC = TAB_LIBRARIES + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_COMPONENTS = 'Components'
+TAB_COMPONENTS_COMMON = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_COMMON
+TAB_COMPONENTS_IA32 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IA32
+TAB_COMPONENTS_X64 = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_X64
+TAB_COMPONENTS_IPF = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_IPF
+TAB_COMPONENTS_ARM = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_ARM
+TAB_COMPONENTS_EBC = TAB_COMPONENTS + TAB_SPLIT + TAB_ARCH_EBC
+
+TAB_COMPONENTS_SOURCE_OVERRIDE_PATH = 'SOURCE_OVERRIDE_PATH'
+
+TAB_BUILD_OPTIONS = 'BuildOptions'
+
+TAB_DEFINE = 'DEFINE'
+TAB_NMAKE = 'Nmake'
+TAB_USER_EXTENSIONS = 'UserExtensions'
+TAB_INCLUDE = '!include'
+
+#
+# Common Define
+#
+TAB_COMMON_DEFINES = 'Defines'
+
+#
+# Inf Definitions
+#
+TAB_INF_DEFINES = TAB_COMMON_DEFINES
+TAB_INF_DEFINES_INF_VERSION = 'INF_VERSION'
+TAB_INF_DEFINES_BASE_NAME = 'BASE_NAME'
+TAB_INF_DEFINES_FILE_GUID = 'FILE_GUID'
+TAB_INF_DEFINES_MODULE_TYPE = 'MODULE_TYPE'
+TAB_INF_DEFINES_EFI_SPECIFICATION_VERSION = 'EFI_SPECIFICATION_VERSION'
+TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION = 'UEFI_SPECIFICATION_VERSION'
+TAB_INF_DEFINES_PI_SPECIFICATION_VERSION = 'PI_SPECIFICATION_VERSION'
+TAB_INF_DEFINES_EDK_RELEASE_VERSION = 'EDK_RELEASE_VERSION'
+TAB_INF_DEFINES_BINARY_MODULE = 'BINARY_MODULE'
+TAB_INF_DEFINES_LIBRARY_CLASS = 'LIBRARY_CLASS'
+TAB_INF_DEFINES_COMPONENT_TYPE = 'COMPONENT_TYPE'
+TAB_INF_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
+TAB_INF_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
+TAB_INF_DEFINES_BUILD_TYPE = 'BUILD_TYPE'
+TAB_INF_DEFINES_FFS_EXT = 'FFS_EXT'
+TAB_INF_DEFINES_FV_EXT = 'FV_EXT'
+TAB_INF_DEFINES_SOURCE_FV = 'SOURCE_FV'
+TAB_INF_DEFINES_PACKAGE = 'PACKAGE'
+TAB_INF_DEFINES_VERSION_NUMBER = 'VERSION_NUMBER'
+TAB_INF_DEFINES_VERSION = 'VERSION'
+TAB_INF_DEFINES_VERSION_STRING = 'VERSION_STRING'
+TAB_INF_DEFINES_PCD_IS_DRIVER = 'PCD_IS_DRIVER'
+TAB_INF_DEFINES_TIANO_EDK1_FLASHMAP_H = 'TIANO_EDK1_FLASHMAP_H'
+TAB_INF_DEFINES_ENTRY_POINT = 'ENTRY_POINT'
+TAB_INF_DEFINES_UNLOAD_IMAGE = 'UNLOAD_IMAGE'
+TAB_INF_DEFINES_CONSTRUCTOR = 'CONSTRUCTOR'
+TAB_INF_DEFINES_DESTRUCTOR = 'DESTRUCTOR'
+TAB_INF_DEFINES_PCI_VENDOR_ID = 'PCI_VENDOR_ID'
+TAB_INF_DEFINES_PCI_DEVICE_ID = 'PCI_DEVICE_ID'
+TAB_INF_DEFINES_PCI_CLASS_CODE = 'PCI_CLASS_CODE'
+TAB_INF_DEFINES_PCI_REVISION = 'PCI_REVISION'
+TAB_INF_DEFINES_PCI_COMPRESS = 'PCI_COMPRESS'
+TAB_INF_DEFINES_DEFINE = 'DEFINE'
+TAB_INF_DEFINES_SPEC = 'SPEC'
+TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION = 'UEFI_HII_RESOURCE_SECTION'
+TAB_INF_DEFINES_CUSTOM_MAKEFILE = 'CUSTOM_MAKEFILE'
+TAB_INF_DEFINES_MACRO = '__MACROS__'
+TAB_INF_DEFINES_SHADOW = 'SHADOW'
+TAB_INF_DEFINES_DPX_SOURCE = 'DPX_SOURCE'
+TAB_INF_FIXED_PCD = 'FixedPcd'
+TAB_INF_FEATURE_PCD = 'FeaturePcd'
+TAB_INF_PATCH_PCD = 'PatchPcd'
+TAB_INF_PCD = 'Pcd'
+TAB_INF_PCD_EX = 'PcdEx'
+TAB_INF_GUIDTYPE_VAR = 'Variable'
+
+#
+# Dec Definitions
+#
+TAB_DEC_DEFINES = TAB_COMMON_DEFINES
+TAB_DEC_DEFINES_DEC_SPECIFICATION = 'DEC_SPECIFICATION'
+TAB_DEC_DEFINES_PACKAGE_NAME = 'PACKAGE_NAME'
+TAB_DEC_DEFINES_PACKAGE_GUID = 'PACKAGE_GUID'
+TAB_DEC_DEFINES_PACKAGE_VERSION = 'PACKAGE_VERSION'
+TAB_DEC_DEFINES_PKG_UNI_FILE = 'PKG_UNI_FILE'
+
+#
+# Dsc Definitions
+#
+TAB_DSC_DEFINES = TAB_COMMON_DEFINES
+TAB_DSC_DEFINES_PLATFORM_NAME = 'PLATFORM_NAME'
+TAB_DSC_DEFINES_PLATFORM_GUID = 'PLATFORM_GUID'
+TAB_DSC_DEFINES_PLATFORM_VERSION = 'PLATFORM_VERSION'
+TAB_DSC_DEFINES_DSC_SPECIFICATION = 'DSC_SPECIFICATION'
+TAB_DSC_DEFINES_OUTPUT_DIRECTORY = 'OUTPUT_DIRECTORY'
+TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES = 'SUPPORTED_ARCHITECTURES'
+TAB_DSC_DEFINES_BUILD_TARGETS = 'BUILD_TARGETS'
+TAB_DSC_DEFINES_SKUID_IDENTIFIER = 'SKUID_IDENTIFIER'
+TAB_DSC_DEFINES_FLASH_DEFINITION = 'FLASH_DEFINITION'
+TAB_DSC_DEFINES_BUILD_NUMBER = 'BUILD_NUMBER'
+TAB_DSC_DEFINES_MAKEFILE_NAME = 'MAKEFILE_NAME'
+TAB_DSC_DEFINES_BS_BASE_ADDRESS = 'BsBaseAddress'
+TAB_DSC_DEFINES_RT_BASE_ADDRESS = 'RtBaseAddress'
+TAB_DSC_DEFINES_DEFINE = 'DEFINE'
+TAB_FIX_LOAD_TOP_MEMORY_ADDRESS = 'FIX_LOAD_TOP_MEMORY_ADDRESS'
+
+#
+# TargetTxt Definitions
+#
+TAB_TAT_DEFINES_ACTIVE_PLATFORM = 'ACTIVE_PLATFORM'
+TAB_TAT_DEFINES_ACTIVE_MODULE = 'ACTIVE_MODULE'
+TAB_TAT_DEFINES_TOOL_CHAIN_CONF = 'TOOL_CHAIN_CONF'
+TAB_TAT_DEFINES_MULTIPLE_THREAD = 'MULTIPLE_THREAD'
+TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER = 'MAX_CONCURRENT_THREAD_NUMBER'
+TAB_TAT_DEFINES_TARGET = 'TARGET'
+TAB_TAT_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
+TAB_TAT_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
+TAB_TAT_DEFINES_BUILD_RULE_CONF = "BUILD_RULE_CONF"
+
+#
+# ToolDef Definitions
+#
+TAB_TOD_DEFINES_TARGET = 'TARGET'
+TAB_TOD_DEFINES_TOOL_CHAIN_TAG = 'TOOL_CHAIN_TAG'
+TAB_TOD_DEFINES_TARGET_ARCH = 'TARGET_ARCH'
+TAB_TOD_DEFINES_COMMAND_TYPE = 'COMMAND_TYPE'
+TAB_TOD_DEFINES_FAMILY = 'FAMILY'
+TAB_TOD_DEFINES_BUILDRULEFAMILY = 'BUILDRULEFAMILY'
+
+#
+# Conditional Statements
+#
+TAB_IF = '!if'
+TAB_END_IF = '!endif'
+TAB_ELSE_IF = '!elseif'
+TAB_ELSE = '!else'
+TAB_IF_DEF = '!ifdef'
+TAB_IF_N_DEF = '!ifndef'
+TAB_IF_EXIST = '!if exist'
+
+#
+# Unknown section
+#
+TAB_UNKNOWN = 'UNKNOWN'
+
+#
+# Header section (virtual section for abstract, description, copyright,
+# license)
+#
+TAB_HEADER = 'Header'
+TAB_HEADER_ABSTRACT = 'Abstract'
+TAB_HEADER_DESCRIPTION = 'Description'
+TAB_HEADER_COPYRIGHT = 'Copyright'
+TAB_HEADER_LICENSE = 'License'
+#
+# Build database path
+#
+DATABASE_PATH = ":memory:"
+#
+# used by ECC
+#
+MODIFIER_LIST = ['IN', 'OUT', 'OPTIONAL', 'UNALIGNED', 'EFI_RUNTIMESERVICE', \
+ 'EFI_BOOTSERVICE', 'EFIAPI']
+#
+# Dependency Expression
+#
+DEPEX_SUPPORTED_OPCODE = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", \
+ "END", "SOR", "TRUE", "FALSE", '(', ')']
+
+TAB_STATIC_LIBRARY = "STATIC-LIBRARY-FILE"
+TAB_DYNAMIC_LIBRARY = "DYNAMIC-LIBRARY-FILE"
+TAB_FRAMEWORK_IMAGE = "EFI-IMAGE-FILE"
+TAB_C_CODE_FILE = "C-CODE-FILE"
+TAB_C_HEADER_FILE = "C-HEADER-FILE"
+TAB_UNICODE_FILE = "UNICODE-TEXT-FILE"
+TAB_DEPENDENCY_EXPRESSION_FILE = "DEPENDENCY-EXPRESSION-FILE"
+TAB_UNKNOWN_FILE = "UNKNOWN-TYPE-FILE"
+TAB_DEFAULT_BINARY_FILE = "_BINARY_FILE_"
+#
+# used to indicate the state of processing header comment section of dec,
+# inf files
+#
+HEADER_COMMENT_NOT_STARTED = -1
+HEADER_COMMENT_STARTED = 0
+HEADER_COMMENT_FILE = 1
+HEADER_COMMENT_ABSTRACT = 2
+HEADER_COMMENT_DESCRIPTION = 3
+HEADER_COMMENT_COPYRIGHT = 4
+HEADER_COMMENT_LICENSE = 5
+HEADER_COMMENT_END = 6
+
+#
+# Static values for data models
+#
+MODEL_UNKNOWN = 0
+
+MODEL_FILE_C = 1001
+MODEL_FILE_H = 1002
+MODEL_FILE_ASM = 1003
+MODEL_FILE_INF = 1011
+MODEL_FILE_DEC = 1012
+MODEL_FILE_DSC = 1013
+MODEL_FILE_FDF = 1014
+MODEL_FILE_INC = 1015
+MODEL_FILE_CIF = 1016
+
+MODEL_IDENTIFIER_FILE_HEADER = 2001
+MODEL_IDENTIFIER_FUNCTION_HEADER = 2002
+MODEL_IDENTIFIER_COMMENT = 2003
+MODEL_IDENTIFIER_PARAMETER = 2004
+MODEL_IDENTIFIER_STRUCTURE = 2005
+MODEL_IDENTIFIER_VARIABLE = 2006
+MODEL_IDENTIFIER_INCLUDE = 2007
+MODEL_IDENTIFIER_PREDICATE_EXPRESSION = 2008
+MODEL_IDENTIFIER_ENUMERATE = 2009
+MODEL_IDENTIFIER_PCD = 2010
+MODEL_IDENTIFIER_UNION = 2011
+MODEL_IDENTIFIER_MACRO_IFDEF = 2012
+MODEL_IDENTIFIER_MACRO_IFNDEF = 2013
+MODEL_IDENTIFIER_MACRO_DEFINE = 2014
+MODEL_IDENTIFIER_MACRO_ENDIF = 2015
+MODEL_IDENTIFIER_MACRO_PROGMA = 2016
+MODEL_IDENTIFIER_FUNCTION_CALLING = 2018
+MODEL_IDENTIFIER_TYPEDEF = 2017
+MODEL_IDENTIFIER_FUNCTION_DECLARATION = 2019
+MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION = 2020
+
+MODEL_EFI_PROTOCOL = 3001
+MODEL_EFI_PPI = 3002
+MODEL_EFI_GUID = 3003
+MODEL_EFI_LIBRARY_CLASS = 3004
+MODEL_EFI_LIBRARY_INSTANCE = 3005
+MODEL_EFI_PCD = 3006
+MODEL_EFI_SOURCE_FILE = 3007
+MODEL_EFI_BINARY_FILE = 3008
+MODEL_EFI_SKU_ID = 3009
+MODEL_EFI_INCLUDE = 3010
+MODEL_EFI_DEPEX = 3011
+
+MODEL_PCD = 4000
+MODEL_PCD_FIXED_AT_BUILD = 4001
+MODEL_PCD_PATCHABLE_IN_MODULE = 4002
+MODEL_PCD_FEATURE_FLAG = 4003
+MODEL_PCD_DYNAMIC_EX = 4004
+MODEL_PCD_DYNAMIC_EX_DEFAULT = 4005
+MODEL_PCD_DYNAMIC_EX_VPD = 4006
+MODEL_PCD_DYNAMIC_EX_HII = 4007
+MODEL_PCD_DYNAMIC = 4008
+MODEL_PCD_DYNAMIC_DEFAULT = 4009
+MODEL_PCD_DYNAMIC_VPD = 4010
+MODEL_PCD_DYNAMIC_HII = 4011
+
+MODEL_META_DATA_FILE_HEADER = 5000
+MODEL_META_DATA_HEADER = 5001
+MODEL_META_DATA_INCLUDE = 5002
+MODEL_META_DATA_DEFINE = 5003
+MODEL_META_DATA_CONDITIONAL_STATEMENT_IF = 5004
+MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSE = 5005
+MODEL_META_DATA_CONDITIONAL_STATEMENT_IFDEF = 5006
+MODEL_META_DATA_CONDITIONAL_STATEMENT_IFNDEF = 5007
+MODEL_META_DATA_BUILD_OPTION = 5008
+MODEL_META_DATA_COMPONENT = 5009
+MODEL_META_DATA_USER_EXTENSION = 5010
+MODEL_META_DATA_PACKAGE = 5011
+MODEL_META_DATA_NMAKE = 5012
+MODEL_META_DATA_CONDITIONAL_STATEMENT_ELSEIF = 50013
+MODEL_META_DATA_CONDITIONAL_STATEMENT_ENDIF = 5014
+MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH = 5015
+
+TOOL_FAMILY_LIST = ["MSFT",
+ "INTEL",
+ "GCC",
+ "RVCT"
+ ]
+
+TYPE_HOB_SECTION = 'HOB'
+TYPE_EVENT_SECTION = 'EVENT'
+TYPE_BOOTMODE_SECTION = 'BOOTMODE'
diff --git a/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
new file mode 100644
index 0000000000..91041c7a64
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
@@ -0,0 +1,489 @@
+## @file
+# This file is used to check PCD logical expression
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+ExpressionValidate
+'''
+
+##
+# Import Modules
+#
+import re
+from Logger import StringTable as ST
+
+## IsValidBareCString
+#
+# Check if String is comprised by whitespace(0x20), !(0x21), 0x23 - 0x7E
+# or '\n', '\t', '\f', '\r', '\b', '\0', '\\'
+#
+# @param String: string to be checked
+#
+def IsValidBareCString(String):
+ EscapeList = ['n', 't', 'f', 'r', 'b', '0', '\\', '"']
+ PreChar = ''
+ LastChar = ''
+ for Char in String:
+ LastChar = Char
+ if PreChar == '\\':
+ if Char not in EscapeList:
+ return False
+ if Char == '\\':
+ PreChar = ''
+ continue
+ else:
+ IntChar = ord(Char)
+ if IntChar != 0x20 and IntChar != 0x09 and IntChar != 0x21 \
+ and (IntChar < 0x23 or IntChar > 0x7e):
+ return False
+ PreChar = Char
+
+ # Last char cannot be \ if PreChar is not \
+ if LastChar == '\\' and PreChar == LastChar:
+ return False
+ return True
+
+def _ValidateToken(Token):
+ Token = Token.strip()
+ Index = Token.find("\"")
+ if Index != -1:
+ return IsValidBareCString(Token[Index+1:-1])
+ return True
+
+## _ExprError
+#
+# @param Exception: Exception
+#
+class _ExprError(Exception):
+ def __init__(self, Error = ''):
+ Exception.__init__(self)
+ self.Error = Error
+
+## _ExprBase
+#
+class _ExprBase:
+ HEX_PATTERN = '[\t\s]*0[xX][a-fA-F0-9]+'
+ INT_PATTERN = '[\t\s]*[0-9]+'
+ MACRO_PATTERN = '[\t\s]*\$\(([A-Z][_A-Z0-9]*)\)'
+ PCD_PATTERN = \
+ '[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*[\t\s]*\.[\t\s]*[_a-zA-Z][a-zA-Z0-9_]*'
+ QUOTED_PATTERN = '[\t\s]*L?"[^"]*"'
+ BOOL_PATTERN = '[\t\s]*(true|True|TRUE|false|False|FALSE)'
+ def __init__(self, Token):
+ self.Token = Token
+ self.Index = 0
+ self.Len = len(Token)
+
+ ## SkipWhitespace
+ #
+ def SkipWhitespace(self):
+ for Char in self.Token[self.Index:]:
+ if Char not in ' \t':
+ break
+ self.Index += 1
+
+ ## IsCurrentOp
+ #
+ # @param OpList: option list
+ #
+ def IsCurrentOp(self, OpList):
+ self.SkipWhitespace()
+ LetterOp = ["EQ", "NE", "GE", "LE", "GT", "LT", "NOT", "and", "AND",
+ "or", "OR", "XOR"]
+ OpMap = {
+ '|' : '|',
+ '&' : '&',
+ '!' : '=',
+ '>' : '=',
+ '<' : '='
+ }
+ for Operator in OpList:
+ if not self.Token[self.Index:].startswith(Operator):
+ continue
+ self.Index += len(Operator)
+ Char = self.Token[self.Index : self.Index + 1]
+ if (Operator in LetterOp and (Char == '_' or Char.isalnum())) \
+ or (Operator in OpMap and OpMap[Operator] == Char):
+ self.Index -= len(Operator)
+ break
+ return True
+ return False
+
+## _LogicalExpressionParser
+#
+# @param _ExprBase: _ExprBase object
+#
+class _LogicalExpressionParser(_ExprBase):
+ #
+ # STRINGITEM can only be logical field according to spec
+ #
+ STRINGITEM = -1
+
+ #
+ # Evaluate to True or False
+ #
+ LOGICAL = 0
+ REALLOGICAL = 2
+
+ #
+ # Just arithmetic expression
+ #
+ ARITH = 1
+
+ def __init__(self, Token):
+ _ExprBase.__init__(self, Token)
+ self.Parens = 0
+
+ def _CheckToken(self, MatchList):
+ for Match in MatchList:
+ if Match and Match.start() == 0:
+ if not _ValidateToken(
+ self.Token[self.Index:self.Index+Match.end()]
+ ):
+ return False
+
+ self.Index += Match.end()
+ if self.Token[self.Index - 1] == '"':
+ return True
+ if self.Token[self.Index:self.Index+1] == '_' or \
+ self.Token[self.Index:self.Index+1].isalnum():
+ self.Index -= Match.end()
+ return False
+
+ Token = self.Token[self.Index - Match.end():self.Index]
+ if Token.strip() in ["EQ", "NE", "GE", "LE", "GT", "LT",
+ "NOT", "and", "AND", "or", "OR", "XOR"]:
+ self.Index -= Match.end()
+ return False
+
+ return True
+ return False
+
+ def IsAtomicNumVal(self):
+ #
+ # Hex number
+ #
+ Match1 = re.compile(self.HEX_PATTERN).match(self.Token[self.Index:])
+
+ #
+ # Number
+ #
+ Match2 = re.compile(self.INT_PATTERN).match(self.Token[self.Index:])
+
+ #
+ # Macro
+ #
+ Match3 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])
+
+ #
+ # PcdName
+ #
+ Match4 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])
+
+ return self._CheckToken([Match1, Match2, Match3, Match4])
+
+
+ def IsAtomicItem(self):
+ #
+ # Macro
+ #
+ Match1 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])
+
+ #
+ # PcdName
+ #
+ Match2 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])
+
+ #
+ # Quoted string
+ #
+ Match3 = re.compile(self.QUOTED_PATTERN).\
+ match(self.Token[self.Index:].replace('\\\\', '//').\
+ replace('\\\"', '\\\''))
+
+ return self._CheckToken([Match1, Match2, Match3])
+
+ ## A || B
+ #
+ def LogicalExpression(self):
+ Ret = self.SpecNot()
+ while self.IsCurrentOp(['||', 'OR', 'or', '&&', 'AND', 'and', 'XOR']):
+ if self.Token[self.Index-1] == '|' and self.Parens <= 0:
+ raise _ExprError(ST.ERR_EXPR_OR)
+ if Ret == self.ARITH:
+ raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
+ Ret = self.SpecNot()
+ if Ret == self.ARITH:
+ raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
+ Ret = self.REALLOGICAL
+ return Ret
+
+ def SpecNot(self):
+ if self.IsCurrentOp(["NOT", "!"]):
+ return self.SpecNot()
+ return self.Rel()
+
+ ## A < B, A > B, A <= B, A >= b
+ #
+ def Rel(self):
+ Ret = self.Expr()
+ if self.IsCurrentOp(["<=", ">=", ">", "<", "GT", "LT", "GE", "LE",
+ "==", "EQ", "!=", "NE"]):
+ if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
+ raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
+ Ret = self.Expr()
+ if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
+ raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
+ Ret = self.REALLOGICAL
+ return Ret
+
+ ## A + B, A - B
+ #
+ def Expr(self):
+ Ret = self.Factor()
+ while self.IsCurrentOp(["+", "-", "&", "|", "^"]):
+ if self.Token[self.Index-1] == '|' and self.Parens <= 0:
+ raise _ExprError(ST.ERR_EXPR_OR)
+ if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
+ raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
+ Ret = self.Factor()
+ if Ret == self.STRINGITEM or Ret == self.REALLOGICAL:
+ raise _ExprError(ST.ERR_EXPR_LOGICAL % self.Token)
+ Ret = self.ARITH
+ return Ret
+
+ ## Factor
+ #
+ def Factor(self):
+ if self.IsCurrentOp(["("]):
+ self.Parens += 1
+ Ret = self.LogicalExpression()
+ if not self.IsCurrentOp([")"]):
+ raise _ExprError(ST.ERR_EXPR_RIGHT_PAREN % \
+ (self.Token, self.Token[self.Index:]))
+ self.Parens -= 1
+ return Ret
+
+ if self.IsAtomicItem():
+ if self.Token[self.Index - 1] == '"':
+ return self.STRINGITEM
+ return self.LOGICAL
+ elif self.IsAtomicNumVal():
+ return self.ARITH
+ else:
+ raise _ExprError(ST.ERR_EXPR_FACTOR % \
+ (self.Token, self.Token[self.Index:]))
+
+ ## IsValidLogicalExpression
+ #
+ def IsValidLogicalExpression(self):
+ if self.Len == 0:
+ return False, ST.ERR_EXPR_EMPTY
+ try:
+ if self.LogicalExpression() == self.ARITH:
+ return False, ST.ERR_EXPR_LOGICAL % self.Token
+ except _ExprError, XExcept:
+ return False, XExcept.Error
+ self.SkipWhitespace()
+ if self.Index != self.Len:
+ return False, (ST.ERR_EXPR_BOOLEAN % \
+ (self.Token[self.Index:], self.Token))
+ return True, ''
+
+## _ValidRangeExpressionParser
+#
+class _ValidRangeExpressionParser(_ExprBase):
+ INT_RANGE_PATTERN = '[\t\s]*[0-9]+[\t\s]*-[\t\s]*[0-9]+'
+ HEX_RANGE_PATTERN = \
+ '[\t\s]*0[xX][a-fA-F0-9]+[\t\s]*-[\t\s]*0[xX][a-fA-F0-9]+'
+ def __init__(self, Token):
+ _ExprBase.__init__(self, Token)
+
+ ## IsValidRangeExpression
+ #
+ def IsValidRangeExpression(self):
+ if self.Len == 0:
+ return False
+ try:
+ self.RangeExpression()
+ except _ExprError:
+ return False
+ self.SkipWhitespace()
+ if self.Index != self.Len:
+ return False
+ return True
+
+ ## RangeExpression
+ #
+ def RangeExpression(self):
+ self.Unary()
+ while self.IsCurrentOp(['OR', 'AND', 'XOR']):
+ self.Unary()
+
+ ## Unary
+ #
+ def Unary(self):
+ if self.IsCurrentOp(["NOT", "-"]):
+ return self.Unary()
+ return self.ValidRange()
+
+ ## ValidRange
+ #
+ def ValidRange(self):
+ if self.IsCurrentOp(["("]):
+ self.RangeExpression()
+ if not self.IsCurrentOp([")"]):
+ raise _ExprError('')
+ return
+
+ if self.IsCurrentOp(["LT", "GT", "LE", "GE", "EQ"]):
+ IntMatch = \
+ re.compile(self.INT_PATTERN).match(self.Token[self.Index:])
+ HexMatch = \
+ re.compile(self.HEX_PATTERN).match(self.Token[self.Index:])
+ if HexMatch and HexMatch.start() == 0:
+ self.Index += HexMatch.end()
+ elif IntMatch and IntMatch.start() == 0:
+ self.Index += IntMatch.end()
+ else:
+ raise _ExprError('')
+ else:
+ IntRangeMatch = re.compile(
+ self.INT_RANGE_PATTERN).match(self.Token[self.Index:]
+ )
+ HexRangeMatch = re.compile(
+ self.HEX_RANGE_PATTERN).match(self.Token[self.Index:]
+ )
+ if HexRangeMatch and HexRangeMatch.start() == 0:
+ self.Index += HexRangeMatch.end()
+ elif IntRangeMatch and IntRangeMatch.start() == 0:
+ self.Index += IntRangeMatch.end()
+ else:
+ raise _ExprError('')
+
+ if self.Token[self.Index:self.Index+1] == '_' or \
+ self.Token[self.Index:self.Index+1].isalnum():
+ raise _ExprError('')
+
+## _StringTestParser
+#
+class _StringTestParser(_ExprBase):
+ def __init__(self, Token):
+ _ExprBase.__init__(self, Token)
+
+ ## IsValidStringTest
+ #
+ def IsValidStringTest(self):
+ if self.Len == 0:
+ return False, ST.ERR_EXPR_EMPTY
+ try:
+ self.StringTest()
+ except _ExprError, XExcept:
+ return False, XExcept.Error
+ return True, ''
+
+ ## StringItem
+ #
+ def StringItem(self):
+ Match1 = re.compile(self.QUOTED_PATTERN)\
+ .match(self.Token[self.Index:].replace('\\\\', '//')\
+ .replace('\\\"', '\\\''))
+ Match2 = re.compile(self.MACRO_PATTERN).match(self.Token[self.Index:])
+ Match3 = re.compile(self.PCD_PATTERN).match(self.Token[self.Index:])
+ MatchList = [Match1, Match2, Match3]
+ for Match in MatchList:
+ if Match and Match.start() == 0:
+ if not _ValidateToken(
+ self.Token[self.Index:self.Index+Match.end()]
+ ):
+ raise _ExprError(ST.ERR_EXPR_STRING_ITEM % \
+ (self.Token, self.Token[self.Index:]))
+ self.Index += Match.end()
+ Token = self.Token[self.Index - Match.end():self.Index]
+ if Token.strip() in ["EQ", "NE"]:
+ raise _ExprError(ST.ERR_EXPR_STRING_ITEM % \
+ (self.Token, self.Token[self.Index:]))
+ return
+ else:
+ raise _ExprError(ST.ERR_EXPR_STRING_ITEM % \
+ (self.Token, self.Token[self.Index:]))
+
+ ## StringTest
+ #
+ def StringTest(self):
+ self.StringItem()
+ if not self.IsCurrentOp(["==", "EQ", "!=", "NE"]):
+ raise _ExprError(ST.ERR_EXPR_EQUALITY % \
+ (self.Token, self.Token[self.Index:]))
+ self.StringItem()
+ if self.Index != self.Len:
+ raise _ExprError(ST.ERR_EXPR_BOOLEAN % \
+ (self.Token[self.Index:], self.Token))
+
+##
+# Check syntax of logical expression
+#
+# @param Token: expression token
+#
+def IsValidLogicalExpr(Token, Flag=False):
+ #
+ # Not do the check right now, keep the implementation for future enhancement.
+ #
+ if not Flag:
+ return True, ""
+ return _LogicalExpressionParser(Token).IsValidLogicalExpression()
+
+##
+# Check syntax of string test
+#
+# @param Token: string test token
+#
+def IsValidStringTest(Token, Flag=False):
+ #
+ # Not do the check right now, keep the implementation for future enhancement.
+ #
+ if not Flag:
+ return True, ""
+ return _StringTestParser(Token).IsValidStringTest()
+
+##
+# Check syntax of range expression
+#
+# @param Token: range expression token
+#
+def IsValidRangeExpr(Token):
+ return _ValidRangeExpressionParser(Token).IsValidRangeExpression()
+
+##
+# Check whether the feature flag expression is valid or not
+#
+# @param Token: feature flag expression
+#
+def IsValidFeatureFlagExp(Token, Flag=False):
+ #
+ # Not do the check right now, keep the implementation for future enhancement.
+ #
+ if not Flag:
+ return True, "", Token
+ else:
+ if Token in ['TRUE', 'FALSE', 'true', 'false', 'True', 'False',
+ '0x1', '0x01', '0x0', '0x00']:
+ return True, ""
+ Valid, Cause = IsValidStringTest(Token, Flag)
+ if not Valid:
+ Valid, Cause = IsValidLogicalExpr(Token, Flag)
+ if not Valid:
+ return False, Cause
+ return True, ""
+
+if __name__ == '__main__':
+ print _LogicalExpressionParser('a ^ b > a + b').IsValidLogicalExpression()
diff --git a/BaseTools/Source/Python/UPT/Library/GlobalData.py b/BaseTools/Source/Python/UPT/Library/GlobalData.py
new file mode 100644
index 0000000000..fedd981529
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/GlobalData.py
@@ -0,0 +1,94 @@
+## @file
+# This file is used to define common static strings and global data used by UPT
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+GlobalData
+'''
+
+#
+# The workspace directory
+#
+gWORKSPACE = '.'
+
+#
+# INF module directory
+#
+gINF_MODULE_DIR = "."
+gINF_MODULE_NAME = ''
+
+#
+# the directory to holds upt related files
+#
+gUPT_DIR = r"Conf/upt/"
+
+#
+# Log file for invalid meta-data files during force removing
+#
+gINVALID_MODULE_FILE = gUPT_DIR + r"Invalid_Modules.log"
+
+#
+# File name for content zip file in the distribution
+#
+gCONTENT_FILE = "dist.content"
+
+#
+# File name for XML file in the distibution
+#
+gDESC_FILE = 'dist.pkg'
+
+#
+# Case Insensitive flag
+#
+gCASE_INSENSITIVE = ''
+
+#
+# All Files dictionary
+#
+gALL_FILES = {}
+
+#
+# Database instance
+#
+gDB = None
+
+#
+# list for files that are found in module level but not in INF files,
+# items are (File, ModulePath), all these should be relative to $(WORKSPACE)
+#
+gMISS_FILE_IN_MODLIST = []
+
+#
+# Global Current Line
+#
+gINF_CURRENT_LINE = None
+
+#
+# Global pkg list
+#
+gWSPKG_LIST = []
+
+#
+# Flag used to take WARN as ERROR.
+# By default, only ERROR message will break the tools execution.
+#
+gWARNING_AS_ERROR = False
+
+#
+# Used to specify the temp directory to hold the unpacked distribution files
+#
+gUNPACK_DIR = None
+
+#
+# Flag used to mark whether the INF file is Binary INF or not.
+#
+gIS_BINARY_INF = False
diff --git a/BaseTools/Source/Python/UPT/Library/Misc.py b/BaseTools/Source/Python/UPT/Library/Misc.py
new file mode 100644
index 0000000000..658c4e0cfb
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/Misc.py
@@ -0,0 +1,921 @@
+## @file
+# Common routines used by all tools
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Misc
+'''
+
+##
+# Import Modules
+#
+import os.path
+from os import access
+from os import F_OK
+from os import makedirs
+from os import getcwd
+from os import chdir
+from os import listdir
+from os import remove
+from os import rmdir
+from os import linesep
+from os import walk
+from os import environ
+import re
+from UserDict import IterableUserDict
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger import ToolError
+from Library import GlobalData
+from Library.DataType import SUP_MODULE_LIST
+from Library.DataType import END_OF_LINE
+from Library.DataType import TAB_SPLIT
+from Library.DataType import LANGUAGE_EN_US
+from Library.String import GetSplitValueList
+from Library.ParserValidate import IsValidHexVersion
+from Library.ParserValidate import IsValidPath
+from Object.POM.CommonObject import TextObject
+
+## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C
+# structure style
+#
+# @param Guid: The GUID string
+#
+def GuidStringToGuidStructureString(Guid):
+ GuidList = Guid.split('-')
+ Result = '{'
+ for Index in range(0, 3, 1):
+ Result = Result + '0x' + GuidList[Index] + ', '
+ Result = Result + '{0x' + GuidList[3][0:2] + ', 0x' + GuidList[3][2:4]
+ for Index in range(0, 12, 2):
+ Result = Result + ', 0x' + GuidList[4][Index:Index + 2]
+ Result += '}}'
+ return Result
+
+## Check whether GUID string is of format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+#
+# @param GuidValue: The GUID value
+#
+def CheckGuidRegFormat(GuidValue):
+ ## Regular expression used to find out register format of GUID
+ #
+ RegFormatGuidPattern = re.compile("^\s*([0-9a-fA-F]){8}-"
+ "([0-9a-fA-F]){4}-"
+ "([0-9a-fA-F]){4}-"
+ "([0-9a-fA-F]){4}-"
+ "([0-9a-fA-F]){12}\s*$")
+
+ if RegFormatGuidPattern.match(GuidValue):
+ return True
+ else:
+ return False
+
+
+## Convert GUID string in C structure style to
+# xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+#
+# @param GuidValue: The GUID value in C structure format
+#
+def GuidStructureStringToGuidString(GuidValue):
+ GuidValueString = GuidValue.lower().replace("{", "").replace("}", "").\
+ replace(" ", "").replace(";", "")
+ GuidValueList = GuidValueString.split(",")
+ if len(GuidValueList) != 11:
+ return ''
+ try:
+ return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
+ int(GuidValueList[0], 16),
+ int(GuidValueList[1], 16),
+ int(GuidValueList[2], 16),
+ int(GuidValueList[3], 16),
+ int(GuidValueList[4], 16),
+ int(GuidValueList[5], 16),
+ int(GuidValueList[6], 16),
+ int(GuidValueList[7], 16),
+ int(GuidValueList[8], 16),
+ int(GuidValueList[9], 16),
+ int(GuidValueList[10], 16)
+ )
+ except BaseException:
+ return ''
+
+## Create directories
+#
+# @param Directory: The directory name
+#
+def CreateDirectory(Directory):
+ if Directory == None or Directory.strip() == "":
+ return True
+ try:
+ if not access(Directory, F_OK):
+ makedirs(Directory)
+ except BaseException:
+ return False
+ return True
+
+## Remove directories, including files and sub-directories in it
+#
+# @param Directory: The directory name
+#
+def RemoveDirectory(Directory, Recursively=False):
+ if Directory == None or Directory.strip() == "" or not \
+ os.path.exists(Directory):
+ return
+ if Recursively:
+ CurrentDirectory = getcwd()
+ chdir(Directory)
+ for File in listdir("."):
+ if os.path.isdir(File):
+ RemoveDirectory(File, Recursively)
+ else:
+ remove(File)
+ chdir(CurrentDirectory)
+ rmdir(Directory)
+
+## Store content in file
+#
+# This method is used to save file only when its content is changed. This is
+# quite useful for "make" system to decide what will be re-built and what
+# won't.
+#
+# @param File: The path of file
+# @param Content: The new content of the file
+# @param IsBinaryFile: The flag indicating if the file is binary file
+# or not
+#
+def SaveFileOnChange(File, Content, IsBinaryFile=True):
+ if not IsBinaryFile:
+ Content = Content.replace("\n", linesep)
+
+ if os.path.exists(File):
+ try:
+ if Content == open(File, "rb").read():
+ return False
+ except BaseException:
+ Logger.Error(None, ToolError.FILE_OPEN_FAILURE, ExtraData=File)
+
+ CreateDirectory(os.path.dirname(File))
+ try:
+ FileFd = open(File, "wb")
+ FileFd.write(Content)
+ FileFd.close()
+ except BaseException:
+ Logger.Error(None, ToolError.FILE_CREATE_FAILURE, ExtraData=File)
+
+ return True
+
+## Get all files of a directory
+#
+# @param Root: Root dir
+# @param SkipList : The files need be skipped
+#
+def GetFiles(Root, SkipList=None, FullPath=True):
+ OriPath = os.path.normpath(Root)
+ FileList = []
+ for Root, Dirs, Files in walk(Root):
+ if SkipList:
+ for Item in SkipList:
+ if Item in Dirs:
+ Dirs.remove(Item)
+ for Dir in Dirs:
+ if Dir.startswith('.'):
+ Dirs.remove(Dir)
+
+ for File in Files:
+ if File.startswith('.'):
+ continue
+ File = os.path.normpath(os.path.join(Root, File))
+ if not FullPath:
+ File = File[len(OriPath) + 1:]
+ FileList.append(File)
+
+ return FileList
+
+## Get all non-metadata files of a directory
+#
+# @param Root: Root Dir
+# @param SkipList : List of path need be skipped
+# @param FullPath: True if the returned file should be full path
+# @param PrefixPath: the path that need to be added to the files found
+# @return: the list of files found
+#
+def GetNonMetaDataFiles(Root, SkipList, FullPath, PrefixPath):
+ FileList = GetFiles(Root, SkipList, FullPath)
+ NewFileList = []
+ for File in FileList:
+ ExtName = os.path.splitext(File)[1]
+ #
+ # skip '.dec', '.inf', '.dsc', '.fdf' files
+ #
+ if ExtName.lower() not in ['.dec', '.inf', '.dsc', '.fdf']:
+ NewFileList.append(os.path.normpath(os.path.join(PrefixPath, File)))
+
+ return NewFileList
+
+## Check if given file exists or not
+#
+# @param File: File name or path to be checked
+# @param Dir: The directory the file is relative to
+#
+def ValidFile(File, Ext=None):
+ File = File.replace('\\', '/')
+ if Ext != None:
+ FileExt = os.path.splitext(File)[1]
+ if FileExt.lower() != Ext.lower():
+ return False
+ if not os.path.exists(File):
+ return False
+ return True
+
+## RealPath
+#
+# @param File: File name or path to be checked
+# @param Dir: The directory the file is relative to
+# @param OverrideDir: The override directory
+#
+def RealPath(File, Dir='', OverrideDir=''):
+ NewFile = os.path.normpath(os.path.join(Dir, File))
+ NewFile = GlobalData.gALL_FILES[NewFile]
+ if not NewFile and OverrideDir:
+ NewFile = os.path.normpath(os.path.join(OverrideDir, File))
+ NewFile = GlobalData.gALL_FILES[NewFile]
+ return NewFile
+
+## RealPath2
+#
+# @param File: File name or path to be checked
+# @param Dir: The directory the file is relative to
+# @param OverrideDir: The override directory
+#
+def RealPath2(File, Dir='', OverrideDir=''):
+ if OverrideDir:
+ NewFile = GlobalData.gALL_FILES[os.path.normpath(os.path.join\
+ (OverrideDir, File))]
+ if NewFile:
+ if OverrideDir[-1] == os.path.sep:
+ return NewFile[len(OverrideDir):], NewFile[0:len(OverrideDir)]
+ else:
+ return NewFile[len(OverrideDir) + 1:], \
+ NewFile[0:len(OverrideDir)]
+
+ NewFile = GlobalData.gALL_FILES[os.path.normpath(os.path.join(Dir, File))]
+ if NewFile:
+ if Dir:
+ if Dir[-1] == os.path.sep:
+ return NewFile[len(Dir):], NewFile[0:len(Dir)]
+ else:
+ return NewFile[len(Dir) + 1:], NewFile[0:len(Dir)]
+ else:
+ return NewFile, ''
+
+ return None, None
+
+## A dict which can access its keys and/or values orderly
+#
+# The class implements a new kind of dict which its keys or values can be
+# accessed in the order they are added into the dict. It guarantees the order
+# by making use of an internal list to keep a copy of keys.
+#
+class Sdict(IterableUserDict):
+ ## Constructor
+ #
+ def __init__(self):
+ IterableUserDict.__init__(self)
+ self._key_list = []
+
+ ## [] operator
+ #
+ def __setitem__(self, Key, Value):
+ if Key not in self._key_list:
+ self._key_list.append(Key)
+ IterableUserDict.__setitem__(self, Key, Value)
+
+ ## del operator
+ #
+ def __delitem__(self, Key):
+ self._key_list.remove(Key)
+ IterableUserDict.__delitem__(self, Key)
+
+ ## used in "for k in dict" loop to ensure the correct order
+ #
+ def __iter__(self):
+ return self.iterkeys()
+
+ ## len() support
+ #
+ def __len__(self):
+ return len(self._key_list)
+
+ ## "in" test support
+ #
+ def __contains__(self, Key):
+ return Key in self._key_list
+
+ ## indexof support
+ #
+ def index(self, Key):
+ return self._key_list.index(Key)
+
+ ## insert support
+ #
+ def insert(self, Key, Newkey, Newvalue, Order):
+ Index = self._key_list.index(Key)
+ if Order == 'BEFORE':
+ self._key_list.insert(Index, Newkey)
+ IterableUserDict.__setitem__(self, Newkey, Newvalue)
+ elif Order == 'AFTER':
+ self._key_list.insert(Index + 1, Newkey)
+ IterableUserDict.__setitem__(self, Newkey, Newvalue)
+
+ ## append support
+ #
+ def append(self, Sdict2):
+ for Key in Sdict2:
+ if Key not in self._key_list:
+ self._key_list.append(Key)
+ IterableUserDict.__setitem__(self, Key, Sdict2[Key])
+ ## hash key
+ #
+ def has_key(self, Key):
+ return Key in self._key_list
+
+ ## Empty the dict
+ #
+ def clear(self):
+ self._key_list = []
+ IterableUserDict.clear(self)
+
+ ## Return a copy of keys
+ #
+ def keys(self):
+ Keys = []
+ for Key in self._key_list:
+ Keys.append(Key)
+ return Keys
+
+ ## Return a copy of values
+ #
+ def values(self):
+ Values = []
+ for Key in self._key_list:
+ Values.append(self[Key])
+ return Values
+
+ ## Return a copy of (key, value) list
+ #
+ def items(self):
+ Items = []
+ for Key in self._key_list:
+ Items.append((Key, self[Key]))
+ return Items
+
+ ## Iteration support
+ #
+ def iteritems(self):
+ return iter(self.items())
+
+ ## Keys interation support
+ #
+ def iterkeys(self):
+ return iter(self.keys())
+
+ ## Values interation support
+ #
+ def itervalues(self):
+ return iter(self.values())
+
+ ## Return value related to a key, and remove the (key, value) from the dict
+ #
+ def pop(self, Key, *Dv):
+ Value = None
+ if Key in self._key_list:
+ Value = self[Key]
+ self.__delitem__(Key)
+ elif len(Dv) != 0 :
+ Value = Dv[0]
+ return Value
+
+ ## Return (key, value) pair, and remove the (key, value) from the dict
+ #
+ def popitem(self):
+ Key = self._key_list[-1]
+ Value = self[Key]
+ self.__delitem__(Key)
+ return Key, Value
+ ## update method
+ #
+ def update(self, Dict=None, **Kwargs):
+ if Dict != None:
+ for Key1, Val1 in Dict.items():
+ self[Key1] = Val1
+ if len(Kwargs):
+ for Key1, Val1 in Kwargs.items():
+ self[Key1] = Val1
+
+## CommonPath
+#
+# @param PathList: PathList
+#
+def CommonPath(PathList):
+ Path1 = min(PathList).split(os.path.sep)
+ Path2 = max(PathList).split(os.path.sep)
+ for Index in xrange(min(len(Path1), len(Path2))):
+ if Path1[Index] != Path2[Index]:
+ return os.path.sep.join(Path1[:Index])
+ return os.path.sep.join(Path1)
+
+## PathClass
+#
+class PathClass(object):
+ def __init__(self, File='', Root='', AlterRoot='', Type='', IsBinary=False,
+ Arch='COMMON', ToolChainFamily='', Target='', TagName='', \
+ ToolCode=''):
+ self.Arch = Arch
+ self.File = str(File)
+ if os.path.isabs(self.File):
+ self.Root = ''
+ self.AlterRoot = ''
+ else:
+ self.Root = str(Root)
+ self.AlterRoot = str(AlterRoot)
+
+ #
+ # Remove any '.' and '..' in path
+ #
+ if self.Root:
+ self.Path = os.path.normpath(os.path.join(self.Root, self.File))
+ self.Root = os.path.normpath(CommonPath([self.Root, self.Path]))
+ #
+ # eliminate the side-effect of 'C:'
+ #
+ if self.Root[-1] == ':':
+ self.Root += os.path.sep
+ #
+ # file path should not start with path separator
+ #
+ if self.Root[-1] == os.path.sep:
+ self.File = self.Path[len(self.Root):]
+ else:
+ self.File = self.Path[len(self.Root) + 1:]
+ else:
+ self.Path = os.path.normpath(self.File)
+
+ self.SubDir, self.Name = os.path.split(self.File)
+ self.BaseName, self.Ext = os.path.splitext(self.Name)
+
+ if self.Root:
+ if self.SubDir:
+ self.Dir = os.path.join(self.Root, self.SubDir)
+ else:
+ self.Dir = self.Root
+ else:
+ self.Dir = self.SubDir
+
+ if IsBinary:
+ self.Type = Type
+ else:
+ self.Type = self.Ext.lower()
+
+ self.IsBinary = IsBinary
+ self.Target = Target
+ self.TagName = TagName
+ self.ToolCode = ToolCode
+ self.ToolChainFamily = ToolChainFamily
+
+ self._Key = None
+
+ ## Convert the object of this class to a string
+ #
+ # Convert member Path of the class to a string
+ #
+ def __str__(self):
+ return self.Path
+
+ ## Override __eq__ function
+ #
+ # Check whether PathClass are the same
+ #
+ def __eq__(self, Other):
+ if type(Other) == type(self):
+ return self.Path == Other.Path
+ else:
+ return self.Path == str(Other)
+
+ ## Override __hash__ function
+ #
+ # Use Path as key in hash table
+ #
+ def __hash__(self):
+ return hash(self.Path)
+
+ ## _GetFileKey
+ #
+ def _GetFileKey(self):
+ if self._Key == None:
+ self._Key = self.Path.upper()
+ return self._Key
+ ## Validate
+ #
+ def Validate(self, Type='', CaseSensitive=True):
+ if GlobalData.gCASE_INSENSITIVE:
+ CaseSensitive = False
+ if Type and Type.lower() != self.Type:
+ return ToolError.FILE_TYPE_MISMATCH, '%s (expect %s but got %s)' % \
+ (self.File, Type, self.Type)
+
+ RealFile, RealRoot = RealPath2(self.File, self.Root, self.AlterRoot)
+ if not RealRoot and not RealFile:
+ RealFile = self.File
+ if self.AlterRoot:
+ RealFile = os.path.join(self.AlterRoot, self.File)
+ elif self.Root:
+ RealFile = os.path.join(self.Root, self.File)
+ return ToolError.FILE_NOT_FOUND, os.path.join(self.AlterRoot, RealFile)
+
+ ErrorCode = 0
+ ErrorInfo = ''
+ if RealRoot != self.Root or RealFile != self.File:
+ if CaseSensitive and (RealFile != self.File or \
+ (RealRoot != self.Root and RealRoot != \
+ self.AlterRoot)):
+ ErrorCode = ToolError.FILE_CASE_MISMATCH
+ ErrorInfo = self.File + '\n\t' + RealFile + \
+ " [in file system]"
+
+ self.SubDir, self.Name = os.path.split(RealFile)
+ self.BaseName, self.Ext = os.path.splitext(self.Name)
+ if self.SubDir:
+ self.Dir = os.path.join(RealRoot, self.SubDir)
+ else:
+ self.Dir = RealRoot
+ self.File = RealFile
+ self.Root = RealRoot
+ self.Path = os.path.join(RealRoot, RealFile)
+ return ErrorCode, ErrorInfo
+
+ Key = property(_GetFileKey)
+
+## Check environment variables
+#
+# Check environment variables that must be set for build. Currently they are
+#
+# WORKSPACE The directory all packages/platforms start from
+# EDK_TOOLS_PATH The directory contains all tools needed by the build
+# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
+#
+# If any of above environment variable is not set or has error, the build
+# will be broken.
+#
+def CheckEnvVariable():
+ #
+ # check WORKSPACE
+ #
+ if "WORKSPACE" not in environ:
+ Logger.Error("UPT",
+ ToolError.UPT_ENVIRON_MISSING_ERROR,
+ ST.ERR_NOT_FOUND_ENVIRONMENT,
+ ExtraData="WORKSPACE")
+
+ WorkspaceDir = os.path.normpath(environ["WORKSPACE"])
+ if not os.path.exists(WorkspaceDir):
+ Logger.Error("UPT",
+ ToolError.UPT_ENVIRON_MISSING_ERROR,
+ ST.ERR_WORKSPACE_NOTEXIST,
+ ExtraData="%s" % WorkspaceDir)
+ elif ' ' in WorkspaceDir:
+ Logger.Error("UPT",
+ ToolError.FORMAT_NOT_SUPPORTED,
+ ST.ERR_SPACE_NOTALLOWED,
+ ExtraData=WorkspaceDir)
+
+## Check whether all module types are in list
+#
+# check whether all module types (SUP_MODULE_LIST) are in list
+#
+# @param ModuleList: a list of ModuleType
+#
+def IsAllModuleList(ModuleList):
+ NewModuleList = [Module.upper() for Module in ModuleList]
+ for Module in SUP_MODULE_LIST:
+ if Module not in NewModuleList:
+ return False
+ else:
+ return True
+
+## Dictionary that use comment(GenericComment, TailComment) as value,
+# if a new comment which key already in the dic is inserted, then the
+# comment will be merged.
+# Key is (Statement, SupArch), when TailComment is added, it will ident
+# according to Statement
+#
+class MergeCommentDict(dict):
+ ## []= operator
+ #
+ def __setitem__(self, Key, CommentVal):
+ GenericComment, TailComment = CommentVal
+ if Key in self:
+ OrigVal1, OrigVal2 = dict.__getitem__(self, Key)
+ Statement = Key[0]
+ dict.__setitem__(self, Key, (OrigVal1 + GenericComment, OrigVal2 \
+ + len(Statement) * ' ' + TailComment))
+ else:
+ dict.__setitem__(self, Key, (GenericComment, TailComment))
+
+ ## =[] operator
+ #
+ def __getitem__(self, Key):
+ return dict.__getitem__(self, Key)
+
+
+## GenDummyHelpTextObj
+#
+# @retval HelpTxt: Generated dummy help text object
+#
+def GenDummyHelpTextObj():
+ HelpTxt = TextObject()
+ HelpTxt.SetLang(LANGUAGE_EN_US)
+ HelpTxt.SetString(' ')
+ return HelpTxt
+
+## ConvertVersionToDecimal, the minor version should be within 0 - 99
+# <HexVersion> ::= "0x" <Major> <Minor>
+# <Major> ::= (a-fA-F0-9){4}
+# <Minor> ::= (a-fA-F0-9){4}
+# <DecVersion> ::= (0-65535) ["." (0-99)]
+#
+# @param StringIn: The string contains version defined in INF file.
+# It can be Decimal or Hex
+#
+def ConvertVersionToDecimal(StringIn):
+ if IsValidHexVersion(StringIn):
+ Value = int(StringIn, 16)
+ Major = Value >> 16
+ Minor = Value & 0xFFFF
+ MinorStr = str(Minor)
+ if len(MinorStr) == 1:
+ MinorStr = '0' + MinorStr
+ return str(Major) + '.' + MinorStr
+ else:
+ if StringIn.find(TAB_SPLIT) != -1:
+ return StringIn
+ elif StringIn:
+ return StringIn + '.0'
+ else:
+ #
+ # when StringIn is '', return it directly
+ #
+ return StringIn
+
+## GetHelpStringByRemoveHashKey
+#
+# Remove hash key at the header of string and return the remain.
+#
+# @param String: The string need to be processed.
+#
+def GetHelpStringByRemoveHashKey(String):
+ ReturnString = ''
+ PattenRemoveHashKey = re.compile(r"^[#+\s]+", re.DOTALL)
+ String = String.strip()
+ if String == '':
+ return String
+
+ LineList = GetSplitValueList(String, END_OF_LINE)
+ for Line in LineList:
+ ValueList = PattenRemoveHashKey.split(Line)
+ if len(ValueList) == 1:
+ ReturnString += ValueList[0] + END_OF_LINE
+ else:
+ ReturnString += ValueList[1] + END_OF_LINE
+
+ if ReturnString.endswith('\n') and not ReturnString.endswith('\n\n') and ReturnString != '\n':
+ ReturnString = ReturnString[:-1]
+
+ return ReturnString
+
+## ConvPathFromAbsToRel
+#
+# Get relative file path from absolute path.
+#
+# @param Path: The string contain file absolute path.
+# @param Root: The string contain the parent path of Path in.
+#
+#
+def ConvPathFromAbsToRel(Path, Root):
+ Path = os.path.normpath(Path)
+ Root = os.path.normpath(Root)
+ FullPath = os.path.normpath(os.path.join(Root, Path))
+
+ #
+ # If Path is absolute path.
+ # It should be in Root.
+ #
+ if os.path.isabs(Path):
+ return FullPath[FullPath.find(Root) + len(Root) + 1:]
+
+ else:
+ return Path
+
+## ConvertPath
+#
+# Convert special characters to '_', '\' to '/'
+# return converted path: Test!1.inf -> Test_1.inf
+#
+# @param Path: Path to be converted
+#
+def ConvertPath(Path):
+ RetPath = ''
+ for Char in Path.strip():
+ if Char.isalnum() or Char in '.-_/':
+ RetPath = RetPath + Char
+ elif Char == '\\':
+ RetPath = RetPath + '/'
+ else:
+ RetPath = RetPath + '_'
+ return RetPath
+
+## ConvertSpec
+#
+# during install, convert the Spec string extract from UPD into INF allowable definition,
+# the difference is period is allowed in the former (not the first letter) but not in the latter.
+# return converted Spec string
+#
+# @param SpecStr: SpecStr to be converted
+#
+def ConvertSpec(SpecStr):
+ RetStr = ''
+ for Char in SpecStr:
+ if Char.isalnum() or Char == '_':
+ RetStr = RetStr + Char
+ else:
+ RetStr = RetStr + '_'
+
+ return RetStr
+
+
+## IsEqualList
+#
+# Judge two lists are identical(contain same item).
+# The rule is elements in List A are in List B and elements in List B are in List A.
+#
+# @param ListA, ListB Lists need to be judged.
+#
+# @return True ListA and ListB are identical
+# @return False ListA and ListB are different with each other
+#
+def IsEqualList(ListA, ListB):
+ if ListA == ListB:
+ return True
+
+ for ItemA in ListA:
+ if not ItemA in ListB:
+ return False
+
+ for ItemB in ListB:
+ if not ItemB in ListA:
+ return False
+
+ return True
+
+## ConvertArchList
+#
+# Convert item in ArchList if the start character is lower case.
+# In UDP spec, Arch is only allowed as: [A-Z]([a-zA-Z0-9])*
+#
+# @param ArchList The ArchList need to be converted.
+#
+# @return NewList The ArchList been converted.
+#
+def ConvertArchList(ArchList):
+ NewArchList = []
+ if not ArchList:
+ return NewArchList
+
+ if type(ArchList) == list:
+ for Arch in ArchList:
+ Arch = Arch.upper()
+ NewArchList.append(Arch)
+ elif type(ArchList) == str:
+ ArchList = ArchList.upper()
+ NewArchList.append(ArchList)
+
+ return NewArchList
+
+## ProcessLineExtender
+#
+# Process the LineExtender of Line in LineList.
+# If one line ends with a line extender, then it will be combined together with next line.
+#
+# @param LineList The LineList need to be processed.
+#
+# @return NewList The ArchList been processed.
+#
+def ProcessLineExtender(LineList):
+ NewList = []
+ Count = 0
+ while Count < len(LineList):
+ if LineList[Count].strip().endswith("\\") and Count + 1 < len(LineList):
+ NewList.append(LineList[Count].strip()[:-2] + LineList[Count + 1])
+ Count = Count + 1
+ else:
+ NewList.append(LineList[Count])
+
+ Count = Count + 1
+
+ return NewList
+
+## GetLibInstanceInfo
+#
+# Get the information from Library Instance INF file.
+#
+# @param string. A string start with # and followed by INF file path
+# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
+#
+# @return GUID, Version
+def GetLibInstanceInfo(String, WorkSpace, LineNo):
+
+ FileGuidString = ""
+ VerString = ""
+
+ OrignalString = String
+ String = String.strip()
+ if not String:
+ return None, None
+ #
+ # Remove "#" characters at the beginning
+ #
+ String = GetHelpStringByRemoveHashKey(String)
+ String = String.strip()
+
+ #
+ # Validate file name exist.
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, String)))
+ if not (ValidFile(FullFileName)):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_FILELIST_EXIST % (String),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=OrignalString)
+
+ #
+ # Validate file exist/format.
+ #
+ if IsValidPath(String, WorkSpace):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (String),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=OrignalString)
+ return False
+ if IsValidFileFlag:
+ FileLinesList = []
+
+ try:
+ FInputfile = open(FullFileName, "rb", 0)
+ try:
+ FileLinesList = FInputfile.readlines()
+ except BaseException:
+ Logger.Error("InfParser",
+ ToolError.FILE_READ_FAILURE,
+ ST.ERR_FILE_OPEN_FAILURE,
+ File=FullFileName)
+ finally:
+ FInputfile.close()
+ except BaseException:
+ Logger.Error("InfParser",
+ ToolError.FILE_READ_FAILURE,
+ ST.ERR_FILE_OPEN_FAILURE,
+ File=FullFileName)
+
+ ReFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
+ ReVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
+
+ FileLinesList = ProcessLineExtender(FileLinesList)
+
+ for Line in FileLinesList:
+ if ReFileGuidPattern.match(Line):
+ FileGuidString = Line
+ if ReVerStringPattern.match(Line):
+ VerString = Line
+
+ if FileGuidString:
+ FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
+ if VerString:
+ VerString = GetSplitValueList(VerString, '=', 1)[1]
+
+ return FileGuidString, VerString
diff --git a/BaseTools/Source/Python/UPT/Library/ParserValidate.py b/BaseTools/Source/Python/UPT/Library/ParserValidate.py
new file mode 100644
index 0000000000..d6b9a096c7
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/ParserValidate.py
@@ -0,0 +1,717 @@
+## @file ParserValidate.py
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+PaserValidate
+'''
+
+import os.path
+import re
+
+from Library.DataType import MODULE_LIST
+from Library.DataType import COMPONENT_TYPE_LIST
+from Library.DataType import PCD_USAGE_TYPE_LIST_OF_MODULE
+from Library.DataType import TAB_SPACE_SPLIT
+from Library.String import GetSplitValueList
+from Library.ExpressionValidate import IsValidBareCString
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+
+## __HexDigit() method
+#
+# Whether char input is a Hex data bit
+#
+# @param TempChar: The char to test
+#
+def __HexDigit(TempChar):
+ if (TempChar >= 'a' and TempChar <= 'f') or \
+ (TempChar >= 'A' and TempChar <= 'F') \
+ or (TempChar >= '0' and TempChar <= '9'):
+ return True
+ else:
+ return False
+
+## IsValidHex() method
+#
+# Whether char input is a Hex data.
+#
+# @param TempChar: The char to test
+#
+def IsValidHex(HexStr):
+ if not HexStr.upper().startswith("0X"):
+ return False
+ CharList = [c for c in HexStr[2:] if not __HexDigit(c)]
+ if len(CharList) == 0:
+ return True
+ else:
+ return False
+
+## Judge the input string is valid bool type or not.
+#
+# <TRUE> ::= {"TRUE"} {"true"} {"True"} {"0x1"} {"0x01"}
+# <FALSE> ::= {"FALSE"} {"false"} {"False"} {"0x0"} {"0x00"}
+# <BoolType> ::= {<TRUE>} {<FALSE>}
+#
+# @param BoolString: A string contained the value need to be judged.
+#
+def IsValidBoolType(BoolString):
+ #
+ # Valid Ture
+ #
+ if BoolString == 'TRUE' or \
+ BoolString == 'True' or \
+ BoolString == 'true' or \
+ BoolString == '0x1' or \
+ BoolString == '0x01':
+ return True
+ #
+ # Valid False
+ #
+ elif BoolString == 'FALSE' or \
+ BoolString == 'False' or \
+ BoolString == 'false' or \
+ BoolString == '0x0' or \
+ BoolString == '0x00':
+ return True
+ #
+ # Invalid bool type
+ #
+ else:
+ return False
+
+## Is Valid Module Type List or not
+#
+# @param ModuleTypeList: A list contain ModuleType strings need to be
+# judged.
+#
+def IsValidInfMoudleTypeList(ModuleTypeList):
+ for ModuleType in ModuleTypeList:
+ return IsValidInfMoudleType(ModuleType)
+
+## Is Valid Module Type or not
+#
+# @param ModuleType: A string contain ModuleType need to be judged.
+#
+def IsValidInfMoudleType(ModuleType):
+ if ModuleType in MODULE_LIST:
+ return True
+ else:
+ return False
+
+## Is Valid Component Type or not
+#
+# @param ComponentType: A string contain ComponentType need to be judged.
+#
+def IsValidInfComponentType(ComponentType):
+ if ComponentType.upper() in COMPONENT_TYPE_LIST:
+ return True
+ else:
+ return False
+
+
+## Is valid Tool Family or not
+#
+# @param ToolFamily: A string contain Tool Family need to be judged.
+# Famlily := [A-Z]([a-zA-Z0-9])*
+#
+def IsValidToolFamily(ToolFamily):
+ ReIsValieFamily = re.compile(r"^[A-Z]+[A-Za-z0-9]{0,}$", re.DOTALL)
+ if ReIsValieFamily.match(ToolFamily) == None:
+ return False
+ return True
+
+## Is valid Tool TagName or not
+#
+# The TagName sample is MYTOOLS and VS2005.
+#
+# @param TagName: A string contain Tool TagName need to be judged.
+#
+def IsValidToolTagName(TagName):
+ if TagName.strip() == '':
+ return True
+ if TagName.strip() == '*':
+ return True
+ if not IsValidWord(TagName):
+ return False
+ return True
+
+## Is valid arch or not
+#
+# @param Arch The arch string need to be validated
+# <OA> ::= (a-zA-Z)(A-Za-z0-9){0,}
+# <arch> ::= {"IA32"} {"X64"} {"IPF"} {"EBC"} {<OA>}
+# {"common"}
+# @param Arch: Input arch
+#
+def IsValidArch(Arch):
+ if Arch == 'common':
+ return True
+ ReIsValieArch = re.compile(r"^[a-zA-Z]+[a-zA-Z0-9]{0,}$", re.DOTALL)
+ if ReIsValieArch.match(Arch) == None:
+ return False
+ return True
+
+## Is valid family or not
+#
+# <Family> ::= {"MSFT"} {"GCC"} {"INTEL"} {<Usr>} {"*"}
+# <Usr> ::= [A-Z][A-Za-z0-9]{0,}
+#
+# @param family: The family string need to be validated
+#
+def IsValidFamily(Family):
+ Family = Family.strip()
+ if Family == '*':
+ return True
+
+ if Family == '':
+ return True
+
+ ReIsValidFamily = re.compile(r"^[A-Z]+[A-Za-z0-9]{0,}$", re.DOTALL)
+ if ReIsValidFamily.match(Family) == None:
+ return False
+ return True
+
+## Is valid build option name or not
+#
+# @param BuildOptionName: The BuildOptionName string need to be validated
+#
+def IsValidBuildOptionName(BuildOptionName):
+ if not BuildOptionName:
+ return False
+
+ ToolOptionList = GetSplitValueList(BuildOptionName, '_', 4)
+
+ if len(ToolOptionList) != 5:
+ return False
+
+ ReIsValidBuildOption1 = re.compile(r"^\s*(\*)|([A-Z][a-zA-Z0-9]*)$")
+ ReIsValidBuildOption2 = re.compile(r"^\s*(\*)|([a-zA-Z][a-zA-Z0-9]*)$")
+
+ if ReIsValidBuildOption1.match(ToolOptionList[0]) == None:
+ return False
+
+ if ReIsValidBuildOption1.match(ToolOptionList[1]) == None:
+ return False
+
+ if ReIsValidBuildOption2.match(ToolOptionList[2]) == None:
+ return False
+
+ if ToolOptionList[3] == "*" and ToolOptionList[4] not in ['FAMILY', 'DLL', 'DPATH']:
+ return False
+
+ return True
+
+## IsValidToken
+#
+# Check if pattern string matches total token
+#
+# @param ReString: regular string
+# @param Token: Token to be matched
+#
+def IsValidToken(ReString, Token):
+ Match = re.compile(ReString).match(Token)
+ return Match and Match.start() == 0 and Match.end() == len(Token)
+
+## IsValidPath
+#
+# Check if path exist
+#
+# @param Path: Absolute path or relative path to be checked
+# @param Root: Root path
+#
+def IsValidPath(Path, Root):
+ Path = Path.strip()
+ OrigPath = Path.replace('\\', '/')
+
+ Path = os.path.normpath(Path).replace('\\', '/')
+ Root = os.path.normpath(Root).replace('\\', '/')
+ FullPath = os.path.normpath(os.path.join(Root, Path)).replace('\\', '/')
+
+ if not os.path.exists(FullPath):
+ return False
+
+ #
+ # If Path is absolute path.
+ # It should be in Root.
+ #
+ if os.path.isabs(Path):
+ if not Path.startswith(Root):
+ return False
+ return True
+
+ #
+ # Check illegal character
+ #
+ for Rel in ['/', './', '../']:
+ if OrigPath.startswith(Rel):
+ return False
+ for Rel in ['//', '/./', '/../']:
+ if Rel in OrigPath:
+ return False
+ for Rel in ['/.', '/..', '/']:
+ if OrigPath.endswith(Rel):
+ return False
+
+ Path = Path.rstrip('/')
+
+ #
+ # Check relative path
+ #
+ for Word in Path.split('/'):
+ if not IsValidWord(Word):
+ return False
+
+ return True
+
+## IsValidInstallPath
+#
+# Check if an install path valid or not.
+#
+# Absolute path or path starts with '.' or path contains '..' are invalid.
+#
+# @param Path: path to be checked
+#
+def IsValidInstallPath(Path):
+ if os.path.isabs(Path):
+ return False
+
+ if Path.startswith('.'):
+ return False
+
+ if Path.find('..') != -1:
+ return False
+
+ return True
+
+
+## IsValidCFormatGuid
+#
+# Check if GUID format has the from of {8,4,4,{2,2,2,2,2,2,2,2}}
+#
+# @param Guid: Guid to be checked
+#
+def IsValidCFormatGuid(Guid):
+ #
+ # Valid: { 0xf0b11735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38,
+ # 0xaf, 0x48, 0xce }}
+ # Invalid: { 0xf0b11735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38,
+ # 0xaf, 0x48, 0xce }} 0x123
+ # Invalid: { 0xf0b1 1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38,
+ # 0xaf, 0x48, 0xce }}
+ #
+ List = ['{', 10, ',', 6, ',', 6, ',{', 4, ',', 4, ',', 4,
+ ',', 4, ',', 4, ',', 4, ',', 4, ',', 4, '}}']
+ Index = 0
+ Value = ''
+ SepValue = ''
+ for Char in Guid:
+ if Char not in '{},\t ':
+ Value += Char
+ continue
+ if Value:
+ try:
+ #
+ # Index may out of bound
+ #
+ if not SepValue or SepValue != List[Index]:
+ return False
+ Index += 1
+ SepValue = ''
+
+ if not Value.startswith('0x') and not Value.startswith('0X'):
+ return False
+
+ #
+ # Index may out of bound
+ #
+ if type(List[Index]) != type(1) or \
+ len(Value) > List[Index] or len(Value) < 3:
+ return False
+
+ #
+ # Check if string can be converted to integer
+ # Throw exception if not
+ #
+ int(Value, 16)
+ except BaseException:
+ #
+ # Exception caught means invalid format
+ #
+ return False
+ Value = ''
+ Index += 1
+ if Char in '{},':
+ SepValue += Char
+
+ return SepValue == '}}' and Value == ''
+
+## IsValidPcdType
+#
+# Check whether the PCD type is valid
+#
+# @param PcdTypeString: The PcdType string need to be checked.
+#
+def IsValidPcdType(PcdTypeString):
+ if PcdTypeString.upper() in PCD_USAGE_TYPE_LIST_OF_MODULE:
+ return True
+ else:
+ return False
+
+## IsValidWord
+#
+# Check whether the word is valid.
+# <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with
+# optional
+# dash "-" and/or underscore "_" characters. No whitespace
+# characters are permitted.
+#
+# @param Word: The word string need to be checked.
+#
+def IsValidWord(Word):
+ if not Word:
+ return False
+ #
+ # The first char should be alpha, _ or Digit.
+ #
+ if not Word[0].isalnum() and \
+ not Word[0] == '_' and \
+ not Word[0].isdigit():
+ return False
+
+ LastChar = ''
+ for Char in Word[1:]:
+ if (not Char.isalpha()) and \
+ (not Char.isdigit()) and \
+ Char != '-' and \
+ Char != '_' and \
+ Char != '.':
+ return False
+ if Char == '.' and LastChar == '.':
+ return False
+ LastChar = Char
+
+ return True
+
+
+## IsValidSimpleWord
+#
+# Check whether the SimpleWord is valid.
+# <SimpleWord> ::= (a-zA-Z0-9)(a-zA-Z0-9_-){0,}
+# A word that cannot contain a period character.
+#
+# @param Word: The word string need to be checked.
+#
+def IsValidSimpleWord(Word):
+ ReIsValidSimpleWord = \
+ re.compile(r"^[0-9A-Za-z][0-9A-Za-z\-_]*$", re.DOTALL)
+ Word = Word.strip()
+ if not Word:
+ return False
+
+ if not ReIsValidSimpleWord.match(Word):
+ return False
+
+ return True
+
+## IsValidDecVersion
+#
+# Check whether the decimal version is valid.
+# <DecVersion> ::= (0-9){1,} ["." (0-9){1,}]
+#
+# @param Word: The word string need to be checked.
+#
+def IsValidDecVersion(Word):
+ if Word.find('.') > -1:
+ ReIsValidDecVersion = re.compile(r"[0-9]+\.?[0-9]+$")
+ else:
+ ReIsValidDecVersion = re.compile(r"[0-9]+$")
+ if ReIsValidDecVersion.match(Word) == None:
+ return False
+ return True
+
+## IsValidHexVersion
+#
+# Check whether the hex version is valid.
+# <HexVersion> ::= "0x" <Major> <Minor>
+# <Major> ::= <HexDigit>{4}
+# <Minor> ::= <HexDigit>{4}
+#
+# @param Word: The word string need to be checked.
+#
+def IsValidHexVersion(Word):
+ ReIsValidHexVersion = re.compile(r"[0][xX][0-9A-Fa-f]{8}$", re.DOTALL)
+ if ReIsValidHexVersion.match(Word) == None:
+ return False
+
+ return True
+
+## IsValidBuildNumber
+#
+# Check whether the BUILD_NUMBER is valid.
+# ["BUILD_NUMBER" "=" <Integer>{1,4} <EOL>]
+#
+# @param Word: The BUILD_NUMBER string need to be checked.
+#
+def IsValidBuildNumber(Word):
+ ReIsValieBuildNumber = re.compile(r"[0-9]{1,4}$", re.DOTALL)
+ if ReIsValieBuildNumber.match(Word) == None:
+ return False
+
+ return True
+
+## IsValidDepex
+#
+# Check whether the Depex is valid.
+#
+# @param Word: The Depex string need to be checked.
+#
+def IsValidDepex(Word):
+ Index = Word.upper().find("PUSH")
+ if Index > -1:
+ return IsValidCFormatGuid(Word[Index+4:].strip())
+
+ ReIsValidCName = re.compile(r"^[A-Za-z_][0-9A-Za-z_\s\.]*$", re.DOTALL)
+ if ReIsValidCName.match(Word) == None:
+ return False
+
+ return True
+
+## IsValidNormalizedString
+#
+# Check
+# <NormalizedString> ::= <DblQuote> [{<Word>} {<Space>}]{1,} <DblQuote>
+# <Space> ::= 0x20
+#
+# @param String: string to be checked
+#
+def IsValidNormalizedString(String):
+ if String == '':
+ return True
+
+ for Char in String:
+ if Char == '\t':
+ return False
+
+ StringList = GetSplitValueList(String, TAB_SPACE_SPLIT)
+
+ for Item in StringList:
+ if not Item:
+ continue
+ if not IsValidWord(Item):
+ return False
+
+ return True
+
+## IsValidIdString
+#
+# Check whether the IdString is valid.
+#
+# @param IdString: The IdString need to be checked.
+#
+def IsValidIdString(String):
+ if IsValidSimpleWord(String.strip()):
+ return True
+
+ if String.strip().startswith('"') and \
+ String.strip().endswith('"'):
+ String = String[1:-1]
+ if String.strip() == "":
+ return True
+ if IsValidNormalizedString(String):
+ return True
+
+ return False
+
+## IsValidVersionString
+#
+# Check whether the VersionString is valid.
+# <AsciiString> ::= [ [<WhiteSpace>]{0,} [<AsciiChars>]{0,} ] {0,}
+# <WhiteSpace> ::= {<Tab>} {<Space>}
+# <Tab> ::= 0x09
+# <Space> ::= 0x20
+# <AsciiChars> ::= (0x21 - 0x7E)
+#
+# @param VersionString: The VersionString need to be checked.
+#
+def IsValidVersionString(VersionString):
+ VersionString = VersionString.strip()
+ for Char in VersionString:
+ if not (Char >= 0x21 and Char <= 0x7E):
+ return False
+
+ return True
+
+## IsValidPcdValue
+#
+# Check whether the PcdValue is valid.
+#
+# @param VersionString: The PcdValue need to be checked.
+#
+def IsValidPcdValue(PcdValue):
+ for Char in PcdValue:
+ if Char == '\n' or Char == '\t' or Char == '\f':
+ return False
+
+ #
+ # <Boolean>
+ #
+ if IsValidFeatureFlagExp(PcdValue, True)[0]:
+ return True
+
+ #
+ # <Number> ::= {<Integer>} {<HexNumber>}
+ # <Integer> ::= {(0-9)} {(1-9)(0-9){1,}}
+ # <HexNumber> ::= "0x" <HexDigit>{1,}
+ # <HexDigit> ::= (a-fA-F0-9)
+ #
+ if IsValidHex(PcdValue):
+ return True
+
+ ReIsValidIntegerSingle = re.compile(r"^\s*[0-9]\s*$", re.DOTALL)
+ if ReIsValidIntegerSingle.match(PcdValue) != None:
+ return True
+
+ ReIsValidIntegerMulti = re.compile(r"^\s*[1-9][0-9]+\s*$", re.DOTALL)
+ if ReIsValidIntegerMulti.match(PcdValue) != None:
+ return True
+
+
+ #
+ # <StringVal> ::= {<StringType>} {<Array>} {"$(" <MACRO> ")"}
+ # <StringType> ::= {<UnicodeString>} {<CString>}
+ #
+ ReIsValidStringType = re.compile(r"^\s*[\"L].*[\"]\s*$")
+ if ReIsValidStringType.match(PcdValue):
+ IsTrue = False
+ if PcdValue.strip().startswith('L\"'):
+ StringValue = PcdValue.strip().lstrip('L\"').rstrip('\"')
+ if IsValidBareCString(StringValue):
+ IsTrue = True
+ elif PcdValue.strip().startswith('\"'):
+ StringValue = PcdValue.strip().lstrip('\"').rstrip('\"')
+ if IsValidBareCString(StringValue):
+ IsTrue = True
+ if IsTrue:
+ return IsTrue
+
+ #
+ # <Array> ::= {<CArray>} {<NList>} {<CFormatGUID>}
+ # <CArray> ::= "{" [<NList>] <CArray>{0,} "}"
+ # <NList> ::= <HexByte> ["," <HexByte>]{0,}
+ # <HexDigit> ::= (a-fA-F0-9)
+ # <HexByte> ::= "0x" <HexDigit>{1,2}
+ #
+ if IsValidCFormatGuid(PcdValue):
+ return True
+
+ ReIsValidByteHex = re.compile(r"^\s*0x[0-9a-fA-F]{1,2}\s*$", re.DOTALL)
+ if PcdValue.strip().startswith('{') and PcdValue.strip().endswith('}') :
+ StringValue = PcdValue.strip().lstrip('{').rstrip('}')
+ ValueList = StringValue.split(',')
+ AllValidFlag = True
+ for ValueItem in ValueList:
+ if not ReIsValidByteHex.match(ValueItem.strip()):
+ AllValidFlag = False
+
+ if AllValidFlag:
+ return True
+
+ #
+ # NList
+ #
+ AllValidFlag = True
+ ValueList = PcdValue.split(',')
+ for ValueItem in ValueList:
+ if not ReIsValidByteHex.match(ValueItem.strip()):
+ AllValidFlag = False
+
+ if AllValidFlag:
+ return True
+
+ return False
+
+## IsValidCVariableName
+#
+# Check whether the PcdValue is valid.
+#
+# @param VersionString: The PcdValue need to be checked.
+#
+def IsValidCVariableName(CName):
+ ReIsValidCName = re.compile(r"^[A-Za-z_][0-9A-Za-z_]*$", re.DOTALL)
+ if ReIsValidCName.match(CName) == None:
+ return False
+
+ return True
+
+## IsValidIdentifier
+#
+# <Identifier> ::= <NonDigit> <Chars>{0,}
+# <Chars> ::= (a-zA-Z0-9_)
+# <NonDigit> ::= (a-zA-Z_)
+#
+# @param Ident: identifier to be checked
+#
+def IsValidIdentifier(Ident):
+ ReIdent = re.compile(r"^[A-Za-z_][0-9A-Za-z_]*$", re.DOTALL)
+ if ReIdent.match(Ident) == None:
+ return False
+
+ return True
+
+## IsValidDecVersionVal
+#
+# {(0-9){1,} "." (0-99)}
+#
+# @param Ver: version to be checked
+#
+def IsValidDecVersionVal(Ver):
+ ReVersion = re.compile(r"[0-9]+(\.[0-9]{1,2})$")
+
+ if ReVersion.match(Ver) == None:
+ return False
+
+ return True
+
+
+## IsValidLibName
+#
+# (A-Z)(a-zA-Z0-9){0,} and could not be "NULL"
+#
+def IsValidLibName(LibName):
+ if LibName == 'NULL':
+ return False
+ ReLibName = re.compile("^[A-Z]+[a-zA-Z0-9]*$")
+ if not ReLibName.match(LibName):
+ return False
+
+ return True
+
+# IsValidUserId
+#
+# <UserId> ::= (a-zA-Z)(a-zA-Z0-9_.){0,}
+# Words that contain period "." must be encapsulated in double quotation marks.
+#
+def IsValidUserId(UserId):
+ UserId = UserId.strip()
+ Quoted = False
+ if UserId.startswith('"') and UserId.endswith('"'):
+ Quoted = True
+ UserId = UserId[1:-1]
+ if not UserId or not UserId[0].isalpha():
+ return False
+ for Char in UserId[1:]:
+ if not Char.isalnum() and not Char in '_.':
+ return False
+ if Char == '.' and not Quoted:
+ return False
+ return True
+
diff --git a/BaseTools/Source/Python/UPT/Library/Parsing.py b/BaseTools/Source/Python/UPT/Library/Parsing.py
new file mode 100644
index 0000000000..95c51406b2
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/Parsing.py
@@ -0,0 +1,993 @@
+## @file
+# This file is used to define common parsing related functions used in parsing
+# INF/DEC/DSC process
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Parsing
+'''
+
+##
+# Import Modules
+#
+import os.path
+import re
+
+from Library.String import RaiseParserError
+from Library.String import GetSplitValueList
+from Library.String import CheckFileType
+from Library.String import CheckFileExist
+from Library.String import CleanString
+from Library.String import NormPath
+
+from Logger.ToolError import FILE_NOT_FOUND
+from Logger.ToolError import FatalError
+from Logger.ToolError import FORMAT_INVALID
+
+from Library import DataType
+
+from Library.Misc import GuidStructureStringToGuidString
+from Library.Misc import CheckGuidRegFormat
+from Logger import StringTable as ST
+import Logger.Log as Logger
+
+from Parser.DecParser import Dec
+
+gPKG_INFO_DICT = {}
+
+## GetBuildOption
+#
+# Parse a string with format "[<Family>:]<ToolFlag>=Flag"
+# Return (Family, ToolFlag, Flag)
+#
+# @param String: String with BuildOption statement
+# @param File: The file which defines build option, used in error report
+#
+def GetBuildOption(String, File, LineNo=-1):
+ (Family, ToolChain, Flag) = ('', '', '')
+ if String.find(DataType.TAB_EQUAL_SPLIT) < 0:
+ RaiseParserError(String, 'BuildOptions', File, \
+ '[<Family>:]<ToolFlag>=Flag', LineNo)
+ else:
+ List = GetSplitValueList(String, DataType.TAB_EQUAL_SPLIT, MaxSplit=1)
+ if List[0].find(':') > -1:
+ Family = List[0][ : List[0].find(':')].strip()
+ ToolChain = List[0][List[0].find(':') + 1 : ].strip()
+ else:
+ ToolChain = List[0].strip()
+ Flag = List[1].strip()
+ return (Family, ToolChain, Flag)
+
+## Get Library Class
+#
+# Get Library of Dsc as <LibraryClassKeyWord>|<LibraryInstance>
+#
+# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
+# @param ContainerFile: The file which describes the library class, used for
+# error report
+#
+def GetLibraryClass(Item, ContainerFile, WorkspaceDir, LineNo=-1):
+ List = GetSplitValueList(Item[0])
+ SupMod = DataType.SUP_MODULE_LIST_STRING
+ if len(List) != 2:
+ RaiseParserError(Item[0], 'LibraryClasses', ContainerFile, \
+ '<LibraryClassKeyWord>|<LibraryInstance>')
+ else:
+ CheckFileType(List[1], '.Inf', ContainerFile, \
+ 'library class instance', Item[0], LineNo)
+ CheckFileExist(WorkspaceDir, List[1], ContainerFile, \
+ 'LibraryClasses', Item[0], LineNo)
+ if Item[1] != '':
+ SupMod = Item[1]
+
+ return (List[0], List[1], SupMod)
+
+## Get Library Class
+#
+# Get Library of Dsc as <LibraryClassKeyWord>[|<LibraryInstance>]
+# [|<TokenSpaceGuidCName>.<PcdCName>]
+#
+# @param Item: String as <LibraryClassKeyWord>|<LibraryInstance>
+# @param ContainerFile: The file which describes the library class, used for
+# error report
+#
+def GetLibraryClassOfInf(Item, ContainerFile, WorkspaceDir, LineNo = -1):
+ ItemList = GetSplitValueList((Item[0] + DataType.TAB_VALUE_SPLIT * 2))
+ SupMod = DataType.SUP_MODULE_LIST_STRING
+
+ if len(ItemList) > 5:
+ RaiseParserError\
+ (Item[0], 'LibraryClasses', ContainerFile, \
+ '<LibraryClassKeyWord>[|<LibraryInstance>]\
+ [|<TokenSpaceGuidCName>.<PcdCName>]')
+ else:
+ CheckFileType(ItemList[1], '.Inf', ContainerFile, 'LibraryClasses', \
+ Item[0], LineNo)
+ CheckFileExist(WorkspaceDir, ItemList[1], ContainerFile, \
+ 'LibraryClasses', Item[0], LineNo)
+ if ItemList[2] != '':
+ CheckPcdTokenInfo(ItemList[2], 'LibraryClasses', \
+ ContainerFile, LineNo)
+ if Item[1] != '':
+ SupMod = Item[1]
+
+ return (ItemList[0], ItemList[1], ItemList[2], SupMod)
+
+## CheckPcdTokenInfo
+#
+# Check if PcdTokenInfo is following <TokenSpaceGuidCName>.<PcdCName>
+#
+# @param TokenInfoString: String to be checked
+# @param Section: Used for error report
+# @param File: Used for error report
+#
+def CheckPcdTokenInfo(TokenInfoString, Section, File, LineNo=-1):
+ Format = '<TokenSpaceGuidCName>.<PcdCName>'
+ if TokenInfoString != '' and TokenInfoString != None:
+ TokenInfoList = GetSplitValueList(TokenInfoString, DataType.TAB_SPLIT)
+ if len(TokenInfoList) == 2:
+ return True
+
+ RaiseParserError(TokenInfoString, Section, File, Format, LineNo)
+
+## Get Pcd
+#
+# Get Pcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<Value>
+# [|<Type>|<MaximumDatumSize>]
+#
+# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
+# <Value>[|<Type>|<MaximumDatumSize>]
+# @param ContainerFile: The file which describes the pcd, used for error
+# report
+
+#
+def GetPcd(Item, Type, ContainerFile, LineNo=-1):
+ TokenGuid, TokenName, Value, MaximumDatumSize, Token = '', '', '', '', ''
+ List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)
+
+ if len(List) < 4 or len(List) > 6:
+ RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
+ '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
+ [|<Type>|<MaximumDatumSize>]', LineNo)
+ else:
+ Value = List[1]
+ MaximumDatumSize = List[2]
+ Token = List[3]
+
+ if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
+ (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+
+ return (TokenName, TokenGuid, Value, MaximumDatumSize, Token, Type)
+
+## Get FeatureFlagPcd
+#
+# Get FeatureFlagPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE
+#
+# @param Item: String as <PcdTokenSpaceGuidCName>
+# .<TokenCName>|TRUE/FALSE
+# @param ContainerFile: The file which describes the pcd, used for error
+# report
+#
+def GetFeatureFlagPcd(Item, Type, ContainerFile, LineNo=-1):
+ TokenGuid, TokenName, Value = '', '', ''
+ List = GetSplitValueList(Item)
+ if len(List) != 2:
+ RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
+ '<PcdTokenSpaceGuidCName>.<TokenCName>|TRUE/FALSE', \
+ LineNo)
+ else:
+ Value = List[1]
+ if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
+ (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+
+ return (TokenName, TokenGuid, Value, Type)
+
+## Get DynamicDefaultPcd
+#
+# Get DynamicDefaultPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>
+# |<Value>[|<DatumTyp>[|<MaxDatumSize>]]
+#
+# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
+# TRUE/FALSE
+# @param ContainerFile: The file which describes the pcd, used for error
+# report
+#
+def GetDynamicDefaultPcd(Item, Type, ContainerFile, LineNo=-1):
+ TokenGuid, TokenName, Value, DatumTyp, MaxDatumSize = '', '', '', '', ''
+ List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)
+ if len(List) < 4 or len(List) > 8:
+ RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
+ '<PcdTokenSpaceGuidCName>.<TokenCName>|<Value>\
+ [|<DatumTyp>[|<MaxDatumSize>]]', LineNo)
+ else:
+ Value = List[1]
+ DatumTyp = List[2]
+ MaxDatumSize = List[3]
+ if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
+ (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+
+ return (TokenName, TokenGuid, Value, DatumTyp, MaxDatumSize, Type)
+
+## Get DynamicHiiPcd
+#
+# Get DynamicHiiPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|<String>|
+# <VariableGuidCName>|<VariableOffset>[|<DefaultValue>[|<MaximumDatumSize>]]
+#
+# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>|
+# TRUE/FALSE
+# @param ContainerFile: The file which describes the pcd, used for error
+# report
+#
+def GetDynamicHiiPcd(Item, Type, ContainerFile, LineNo = -1):
+ TokenGuid, TokenName, List1, List2, List3, List4, List5 = \
+ '', '', '', '', '', '', ''
+ List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT * 2)
+ if len(List) < 6 or len(List) > 8:
+ RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
+ '<PcdTokenSpaceGuidCName>.<TokenCName>|<String>|\
+ <VariableGuidCName>|<VariableOffset>[|<DefaultValue>\
+ [|<MaximumDatumSize>]]', LineNo)
+ else:
+ List1, List2, List3, List4, List5 = \
+ List[1], List[2], List[3], List[4], List[5]
+ if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
+ (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+
+ return (TokenName, TokenGuid, List1, List2, List3, List4, List5, Type)
+
+## Get DynamicVpdPcd
+#
+# Get DynamicVpdPcd of Dsc as <PcdTokenSpaceGuidCName>.<TokenCName>|
+# <VpdOffset>[|<MaximumDatumSize>]
+#
+# @param Item: String as <PcdTokenSpaceGuidCName>.<TokenCName>
+# |TRUE/FALSE
+# @param ContainerFile: The file which describes the pcd, used for error
+# report
+#
+def GetDynamicVpdPcd(Item, Type, ContainerFile, LineNo=-1):
+ TokenGuid, TokenName, List1, List2 = '', '', '', ''
+ List = GetSplitValueList(Item + DataType.TAB_VALUE_SPLIT)
+ if len(List) < 3 or len(List) > 4:
+ RaiseParserError(Item, 'Pcds' + Type, ContainerFile, \
+ '<PcdTokenSpaceGuidCName>.<TokenCName>|<VpdOffset>\
+ [|<MaximumDatumSize>]', LineNo)
+ else:
+ List1, List2 = List[1], List[2]
+ if CheckPcdTokenInfo(List[0], 'Pcds' + Type, ContainerFile, LineNo):
+ (TokenGuid, TokenName) = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+
+ return (TokenName, TokenGuid, List1, List2, Type)
+
+## GetComponent
+#
+# Parse block of the components defined in dsc file
+# Set KeyValues as [ ['component name', [lib1, lib2, lib3],
+# [bo1, bo2, bo3], [pcd1, pcd2, pcd3]], ...]
+#
+# @param Lines: The content to be parsed
+# @param KeyValues: To store data after parsing
+#
+def GetComponent(Lines, KeyValues):
+ (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \
+ FindPcdsDynamicEx) = (False, False, False, False, False, False, False, \
+ False)
+ ListItem = None
+ LibraryClassItem = []
+ BuildOption = []
+ Pcd = []
+
+ for Line in Lines:
+ Line = Line[0]
+ #
+ # Ignore !include statement
+ #
+ if Line.upper().find(DataType.TAB_INCLUDE.upper() + ' ') > -1 or \
+ Line.upper().find(DataType.TAB_DEFINE + ' ') > -1:
+ continue
+
+ if FindBlock == False:
+ ListItem = Line
+ #
+ # find '{' at line tail
+ #
+ if Line.endswith('{'):
+ FindBlock = True
+ ListItem = CleanString(Line.rsplit('{', 1)[0], \
+ DataType.TAB_COMMENT_SPLIT)
+
+ #
+ # Parse a block content
+ #
+ if FindBlock:
+ if Line.find('<LibraryClasses>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (True, False, False, False, False, False, False)
+ continue
+ if Line.find('<BuildOptions>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, True, False, False, False, False, False)
+ continue
+ if Line.find('<PcdsFeatureFlag>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, True, False, False, False, False)
+ continue
+ if Line.find('<PcdsPatchableInModule>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, True, False, False, False)
+ continue
+ if Line.find('<PcdsFixedAtBuild>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, True, False, False)
+ continue
+ if Line.find('<PcdsDynamic>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, False, True, False)
+ continue
+ if Line.find('<PcdsDynamicEx>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, False, False, True)
+ continue
+ if Line.endswith('}'):
+ #
+ # find '}' at line tail
+ #
+ KeyValues.append([ListItem, LibraryClassItem, \
+ BuildOption, Pcd])
+ (FindBlock, FindLibraryClass, FindBuildOption, \
+ FindPcdsFeatureFlag, FindPcdsPatchableInModule, \
+ FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, False, False, False, False)
+ LibraryClassItem, BuildOption, Pcd = [], [], []
+ continue
+
+ if FindBlock:
+ if FindLibraryClass:
+ LibraryClassItem.append(Line)
+ elif FindBuildOption:
+ BuildOption.append(Line)
+ elif FindPcdsFeatureFlag:
+ Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG_NULL, Line))
+ elif FindPcdsPatchableInModule:
+ Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE_NULL, Line))
+ elif FindPcdsFixedAtBuild:
+ Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD_NULL, Line))
+ elif FindPcdsDynamic:
+ Pcd.append((DataType.TAB_PCDS_DYNAMIC_DEFAULT_NULL, Line))
+ elif FindPcdsDynamicEx:
+ Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX_DEFAULT_NULL, Line))
+ else:
+ KeyValues.append([ListItem, [], [], []])
+
+ return True
+
+## GetExec
+#
+# Parse a string with format "InfFilename [EXEC = ExecFilename]"
+# Return (InfFilename, ExecFilename)
+#
+# @param String: String with EXEC statement
+#
+def GetExec(String):
+ InfFilename = ''
+ ExecFilename = ''
+ if String.find('EXEC') > -1:
+ InfFilename = String[ : String.find('EXEC')].strip()
+ ExecFilename = String[String.find('EXEC') + len('EXEC') : ].strip()
+ else:
+ InfFilename = String.strip()
+
+ return (InfFilename, ExecFilename)
+
+## GetComponents
+#
+# Parse block of the components defined in dsc file
+# Set KeyValues as [ ['component name', [lib1, lib2, lib3], [bo1, bo2, bo3],
+# [pcd1, pcd2, pcd3]], ...]
+#
+# @param Lines: The content to be parsed
+# @param Key: Reserved
+# @param KeyValues: To store data after parsing
+# @param CommentCharacter: Comment char, used to ignore comment content
+#
+# @retval True Get component successfully
+#
+def GetComponents(Lines, KeyValues, CommentCharacter):
+ if Lines.find(DataType.TAB_SECTION_END) > -1:
+ Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
+ (FindBlock, FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, FindPcdsDynamic, \
+ FindPcdsDynamicEx) = \
+ (False, False, False, False, False, False, False, False)
+ ListItem = None
+ LibraryClassItem = []
+ BuildOption = []
+ Pcd = []
+
+ LineList = Lines.split('\n')
+ for Line in LineList:
+ Line = CleanString(Line, CommentCharacter)
+ if Line == None or Line == '':
+ continue
+
+ if FindBlock == False:
+ ListItem = Line
+ #
+ # find '{' at line tail
+ #
+ if Line.endswith('{'):
+ FindBlock = True
+ ListItem = CleanString(Line.rsplit('{', 1)[0], CommentCharacter)
+
+ #
+ # Parse a block content
+ #
+ if FindBlock:
+ if Line.find('<LibraryClasses>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (True, False, False, False, False, False, False)
+ continue
+ if Line.find('<BuildOptions>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, True, False, False, False, False, False)
+ continue
+ if Line.find('<PcdsFeatureFlag>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, True, False, False, False, False)
+ continue
+ if Line.find('<PcdsPatchableInModule>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, True, False, False, False)
+ continue
+ if Line.find('<PcdsFixedAtBuild>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, True, False, False)
+ continue
+ if Line.find('<PcdsDynamic>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, False, True, False)
+ continue
+ if Line.find('<PcdsDynamicEx>') != -1:
+ (FindLibraryClass, FindBuildOption, FindPcdsFeatureFlag, \
+ FindPcdsPatchableInModule, FindPcdsFixedAtBuild, \
+ FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, False, False, True)
+ continue
+ if Line.endswith('}'):
+ #
+ # find '}' at line tail
+ #
+ KeyValues.append([ListItem, LibraryClassItem, BuildOption, \
+ Pcd])
+ (FindBlock, FindLibraryClass, FindBuildOption, \
+ FindPcdsFeatureFlag, FindPcdsPatchableInModule, \
+ FindPcdsFixedAtBuild, FindPcdsDynamic, FindPcdsDynamicEx) = \
+ (False, False, False, False, False, False, False, False)
+ LibraryClassItem, BuildOption, Pcd = [], [], []
+ continue
+
+ if FindBlock:
+ if FindLibraryClass:
+ LibraryClassItem.append(Line)
+ elif FindBuildOption:
+ BuildOption.append(Line)
+ elif FindPcdsFeatureFlag:
+ Pcd.append((DataType.TAB_PCDS_FEATURE_FLAG, Line))
+ elif FindPcdsPatchableInModule:
+ Pcd.append((DataType.TAB_PCDS_PATCHABLE_IN_MODULE, Line))
+ elif FindPcdsFixedAtBuild:
+ Pcd.append((DataType.TAB_PCDS_FIXED_AT_BUILD, Line))
+ elif FindPcdsDynamic:
+ Pcd.append((DataType.TAB_PCDS_DYNAMIC, Line))
+ elif FindPcdsDynamicEx:
+ Pcd.append((DataType.TAB_PCDS_DYNAMIC_EX, Line))
+ else:
+ KeyValues.append([ListItem, [], [], []])
+
+ return True
+
+## Get Source
+#
+# Get Source of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
+# [|<PcdFeatureFlag>]]]]
+#
+# @param Item: String as <Filename>[|<Family>[|<TagName>[|<ToolCode>
+# [|<PcdFeatureFlag>]]]]
+# @param ContainerFile: The file which describes the library class, used
+# for error report
+#
+def GetSource(Item, ContainerFile, FileRelativePath, LineNo=-1):
+ ItemNew = Item + DataType.TAB_VALUE_SPLIT * 4
+ List = GetSplitValueList(ItemNew)
+ if len(List) < 5 or len(List) > 9:
+ RaiseParserError(Item, 'Sources', ContainerFile, \
+ '<Filename>[|<Family>[|<TagName>[|<ToolCode>\
+ [|<PcdFeatureFlag>]]]]', LineNo)
+ List[0] = NormPath(List[0])
+ CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Sources', \
+ Item, LineNo)
+ if List[4] != '':
+ CheckPcdTokenInfo(List[4], 'Sources', ContainerFile, LineNo)
+
+ return (List[0], List[1], List[2], List[3], List[4])
+
+## Get Binary
+#
+# Get Binary of Inf as <Filename>[|<Family>[|<TagName>[|<ToolCode>
+# [|<PcdFeatureFlag>]]]]
+#
+# @param Item: String as <Filename>[|<Family>[|<TagName>
+# [|<ToolCode>[|<PcdFeatureFlag>]]]]
+# @param ContainerFile: The file which describes the library class,
+# used for error report
+#
+def GetBinary(Item, ContainerFile, LineNo=-1):
+ ItemNew = Item + DataType.TAB_VALUE_SPLIT
+ List = GetSplitValueList(ItemNew)
+ if len(List) < 3 or len(List) > 5:
+ RaiseParserError(Item, 'Binaries', ContainerFile, \
+ "<FileType>|<Filename>[|<Target>\
+ [|<TokenSpaceGuidCName>.<PcdCName>]]", LineNo)
+
+ if len(List) >= 4:
+ if List[3] != '':
+ CheckPcdTokenInfo(List[3], 'Binaries', ContainerFile, LineNo)
+ return (List[0], List[1], List[2], List[3])
+ elif len(List) == 3:
+ return (List[0], List[1], List[2], '')
+
+## Get Guids/Protocols/Ppis
+#
+# Get Guids/Protocols/Ppis of Inf as <GuidCName>[|<PcdFeatureFlag>]
+#
+# @param Item: String as <GuidCName>[|<PcdFeatureFlag>]
+# @param Type: Type of parsing string
+# @param ContainerFile: The file which describes the library class,
+# used for error report
+#
+def GetGuidsProtocolsPpisOfInf(Item):
+ ItemNew = Item + DataType.TAB_VALUE_SPLIT
+ List = GetSplitValueList(ItemNew)
+ return (List[0], List[1])
+
+## Get Guids/Protocols/Ppis
+#
+# Get Guids/Protocols/Ppis of Dec as <GuidCName>=<GuidValue>
+#
+# @param Item: String as <GuidCName>=<GuidValue>
+# @param Type: Type of parsing string
+# @param ContainerFile: The file which describes the library class,
+# used for error report
+#
+def GetGuidsProtocolsPpisOfDec(Item, Type, ContainerFile, LineNo=-1):
+ List = GetSplitValueList(Item, DataType.TAB_EQUAL_SPLIT)
+ if len(List) != 2:
+ RaiseParserError(Item, Type, ContainerFile, '<CName>=<GuidValue>', \
+ LineNo)
+ #
+ #convert C-Format Guid to Register Format
+ #
+ if List[1][0] == '{' and List[1][-1] == '}':
+ RegisterFormatGuid = GuidStructureStringToGuidString(List[1])
+ if RegisterFormatGuid == '':
+ RaiseParserError(Item, Type, ContainerFile, \
+ 'CFormat or RegisterFormat', LineNo)
+ else:
+ if CheckGuidRegFormat(List[1]):
+ RegisterFormatGuid = List[1]
+ else:
+ RaiseParserError(Item, Type, ContainerFile, \
+ 'CFormat or RegisterFormat', LineNo)
+
+ return (List[0], RegisterFormatGuid)
+
+## GetPackage
+#
+# Get Package of Inf as <PackagePath>[|<PcdFeatureFlag>]
+#
+# @param Item: String as <PackagePath>[|<PcdFeatureFlag>]
+# @param Type: Type of parsing string
+# @param ContainerFile: The file which describes the library class,
+# used for error report
+#
+def GetPackage(Item, ContainerFile, FileRelativePath, LineNo=-1):
+ ItemNew = Item + DataType.TAB_VALUE_SPLIT
+ List = GetSplitValueList(ItemNew)
+ CheckFileType(List[0], '.Dec', ContainerFile, 'package', List[0], LineNo)
+ CheckFileExist(FileRelativePath, List[0], ContainerFile, 'Packages', \
+ List[0], LineNo)
+ if List[1] != '':
+ CheckPcdTokenInfo(List[1], 'Packages', ContainerFile, LineNo)
+
+ return (List[0], List[1])
+
+## Get Pcd Values of Inf
+#
+# Get Pcd of Inf as <TokenSpaceGuidCName>.<PcdCName>[|<Value>]
+#
+# @param Item: The string describes pcd
+# @param Type: The type of Pcd
+# @param File: The file which describes the pcd, used for error report
+#
+def GetPcdOfInf(Item, Type, File, LineNo):
+ Format = '<TokenSpaceGuidCName>.<PcdCName>[|<Value>]'
+ TokenGuid, TokenName, Value, InfType = '', '', '', ''
+
+ if Type == DataType.TAB_PCDS_FIXED_AT_BUILD:
+ InfType = DataType.TAB_INF_FIXED_PCD
+ elif Type == DataType.TAB_PCDS_PATCHABLE_IN_MODULE:
+ InfType = DataType.TAB_INF_PATCH_PCD
+ elif Type == DataType.TAB_PCDS_FEATURE_FLAG:
+ InfType = DataType.TAB_INF_FEATURE_PCD
+ elif Type == DataType.TAB_PCDS_DYNAMIC_EX:
+ InfType = DataType.TAB_INF_PCD_EX
+ elif Type == DataType.TAB_PCDS_DYNAMIC:
+ InfType = DataType.TAB_INF_PCD
+ List = GetSplitValueList(Item, DataType.TAB_VALUE_SPLIT, 1)
+ TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+ if len(TokenInfo) != 2:
+ RaiseParserError(Item, InfType, File, Format, LineNo)
+ else:
+ TokenGuid = TokenInfo[0]
+ TokenName = TokenInfo[1]
+
+ if len(List) > 1:
+ Value = List[1]
+ else:
+ Value = None
+ return (TokenGuid, TokenName, Value, InfType)
+
+
+## Get Pcd Values of Dec
+#
+# Get Pcd of Dec as <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
+# @param Item: Pcd item
+# @param Type: Pcd type
+# @param File: Dec file
+# @param LineNo: Line number
+#
+def GetPcdOfDec(Item, Type, File, LineNo=-1):
+ Format = '<TokenSpaceGuidCName>.<PcdCName>|<Value>|<DatumType>|<Token>'
+ TokenGuid, TokenName, Value, DatumType, Token = '', '', '', '', ''
+ List = GetSplitValueList(Item)
+ if len(List) != 4:
+ RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
+ else:
+ Value = List[1]
+ DatumType = List[2]
+ Token = List[3]
+ TokenInfo = GetSplitValueList(List[0], DataType.TAB_SPLIT)
+ if len(TokenInfo) != 2:
+ RaiseParserError(Item, 'Pcds' + Type, File, Format, LineNo)
+ else:
+ TokenGuid = TokenInfo[0]
+ TokenName = TokenInfo[1]
+
+ return (TokenGuid, TokenName, Value, DatumType, Token, Type)
+
+## Parse DEFINE statement
+#
+# Get DEFINE macros
+#
+# @param LineValue: A DEFINE line value
+# @param StartLine: A DEFINE start line
+# @param Table: A table
+# @param FileID: File ID
+# @param Filename: File name
+# @param SectionName: DEFINE section name
+# @param SectionModel: DEFINE section model
+# @param Arch: DEFINE arch
+#
+def ParseDefine(LineValue, StartLine, Table, FileID, SectionName, \
+ SectionModel, Arch):
+ Logger.Debug(Logger.DEBUG_2, ST.MSG_DEFINE_STATEMENT_FOUND % (LineValue, \
+ SectionName))
+ Define = \
+ GetSplitValueList(CleanString\
+ (LineValue[LineValue.upper().\
+ find(DataType.TAB_DEFINE.upper() + ' ') + \
+ len(DataType.TAB_DEFINE + ' ') : ]), \
+ DataType.TAB_EQUAL_SPLIT, 1)
+ Table.Insert(DataType.MODEL_META_DATA_DEFINE, Define[0], Define[1], '', \
+ '', '', Arch, SectionModel, FileID, StartLine, -1, \
+ StartLine, -1, 0)
+
+## InsertSectionItems
+#
+# Insert item data of a section to a dict
+#
+# @param Model: A model
+# @param CurrentSection: Current section
+# @param SectionItemList: Section item list
+# @param ArchList: Arch list
+# @param ThirdList: Third list
+# @param RecordSet: Record set
+#
+def InsertSectionItems(Model, SectionItemList, ArchList, \
+ ThirdList, RecordSet):
+ #
+ # Insert each item data of a section
+ #
+ for Index in range(0, len(ArchList)):
+ Arch = ArchList[Index]
+ Third = ThirdList[Index]
+ if Arch == '':
+ Arch = DataType.TAB_ARCH_COMMON
+
+ Records = RecordSet[Model]
+ for SectionItem in SectionItemList:
+ LineValue, StartLine, Comment = SectionItem[0], \
+ SectionItem[1], SectionItem[2]
+
+ Logger.Debug(4, ST.MSG_PARSING %LineValue)
+ #
+ # And then parse DEFINE statement
+ #
+ if LineValue.upper().find(DataType.TAB_DEFINE.upper() + ' ') > -1:
+ continue
+ #
+ # At last parse other sections
+ #
+ IdNum = -1
+ Records.append([LineValue, Arch, StartLine, IdNum, Third, Comment])
+
+ if RecordSet != {}:
+ RecordSet[Model] = Records
+
+## GenMetaDatSectionItem
+#
+# @param Key: A key
+# @param Value: A value
+# @param List: A list
+#
+def GenMetaDatSectionItem(Key, Value, List):
+ if Key not in List:
+ List[Key] = [Value]
+ else:
+ List[Key].append(Value)
+
+## GetPkgInfoFromDec
+#
+# get package name, guid, version info from dec files
+#
+# @param Path: File path
+#
+def GetPkgInfoFromDec(Path):
+ PkgName = None
+ PkgGuid = None
+ PkgVersion = None
+
+ Path = Path.replace('\\', '/')
+
+ if not os.path.exists(Path):
+ Logger.Error("\nUPT", FILE_NOT_FOUND, File = Path)
+
+ if Path in gPKG_INFO_DICT:
+ return gPKG_INFO_DICT[Path]
+
+ try:
+ DecParser = Dec(Path)
+ PkgName = DecParser.GetPackageName()
+ PkgGuid = DecParser.GetPackageGuid()
+ PkgVersion = DecParser.GetPackageVersion()
+ gPKG_INFO_DICT[Path] = (PkgName, PkgGuid, PkgVersion)
+ return PkgName, PkgGuid, PkgVersion
+ except FatalError:
+ return None, None, None
+
+
+## GetWorkspacePackage
+#
+# Get a list of workspace package information.
+#
+def GetWorkspacePackage():
+ DecFileList = []
+ WorkspaceDir = os.environ["WORKSPACE"]
+ for Root, Dirs, Files in os.walk(WorkspaceDir):
+ if 'CVS' in Dirs:
+ Dirs.remove('CVS')
+ if '.svn' in Dirs:
+ Dirs.remove('.svn')
+ for Dir in Dirs:
+ if Dir.startswith('.'):
+ Dirs.remove(Dir)
+ for FileSp in Files:
+ if FileSp.startswith('.'):
+ continue
+ Ext = os.path.splitext(FileSp)[1]
+ if Ext.lower() in ['.dec']:
+ DecFileList.append\
+ (os.path.normpath(os.path.join(Root, FileSp)))
+ #
+ # abstract package guid, version info from DecFile List
+ #
+ PkgList = []
+ for DecFile in DecFileList:
+ (PkgName, PkgGuid, PkgVersion) = GetPkgInfoFromDec(DecFile)
+ if PkgName and PkgGuid and PkgVersion:
+ PkgList.append((PkgName, PkgGuid, PkgVersion, DecFile))
+
+ return PkgList
+
+## GetWorkspaceModule
+#
+# Get a list of workspace modules.
+#
+def GetWorkspaceModule():
+ InfFileList = []
+ WorkspaceDir = os.environ["WORKSPACE"]
+ for Root, Dirs, Files in os.walk(WorkspaceDir):
+ if 'CVS' in Dirs:
+ Dirs.remove('CVS')
+ if '.svn' in Dirs:
+ Dirs.remove('.svn')
+ if 'Build' in Dirs:
+ Dirs.remove('Build')
+ for Dir in Dirs:
+ if Dir.startswith('.'):
+ Dirs.remove(Dir)
+ for FileSp in Files:
+ if FileSp.startswith('.'):
+ continue
+ Ext = os.path.splitext(FileSp)[1]
+ if Ext.lower() in ['.inf']:
+ InfFileList.append\
+ (os.path.normpath(os.path.join(Root, FileSp)))
+
+ return InfFileList
+
+## MacroParser used to parse macro definition
+#
+# @param Line: The content contain linestring and line number
+# @param FileName: The meta-file file name
+# @param SectionType: Section for the Line belong to
+# @param FileLocalMacros: A list contain Macro defined in [Defines] section.
+#
+def MacroParser(Line, FileName, SectionType, FileLocalMacros):
+ MacroDefPattern = re.compile("^(DEFINE)[ \t]+")
+ LineContent = Line[0]
+ LineNo = Line[1]
+ Match = MacroDefPattern.match(LineContent)
+ if not Match:
+ #
+ # Not 'DEFINE/EDK_GLOBAL' statement, call decorated method
+ #
+ return None, None
+
+ TokenList = GetSplitValueList(LineContent[Match.end(1):], \
+ DataType.TAB_EQUAL_SPLIT, 1)
+ #
+ # Syntax check
+ #
+ if not TokenList[0]:
+ Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACRONAME_NOGIVEN,
+ ExtraData=LineContent, File=FileName, Line=LineNo)
+ if len(TokenList) < 2:
+ Logger.Error('Parser', FORMAT_INVALID, ST.ERR_MACROVALUE_NOGIVEN,
+ ExtraData=LineContent, File=FileName, Line=LineNo)
+
+ Name, Value = TokenList
+
+ #
+ # DEFINE defined macros
+ #
+ if SectionType == DataType.MODEL_META_DATA_HEADER:
+ FileLocalMacros[Name] = Value
+
+ ReIsValidMacroName = re.compile(r"^[A-Z][A-Z0-9_]*$", re.DOTALL)
+ if ReIsValidMacroName.match(Name) == None:
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_MACRONAME_INVALID%(Name),
+ ExtraData=LineContent,
+ File=FileName,
+ Line=LineNo)
+
+ # Validate MACRO Value
+ #
+ # <MacroDefinition> ::= [<Comments>]{0,}
+ # "DEFINE" <MACRO> "=" [{<PATH>} {<VALUE>}] <EOL>
+ # <Value> ::= {<NumVal>} {<Boolean>} {<AsciiString>} {<GUID>}
+ # {<CString>} {<UnicodeString>} {<CArray>}
+ #
+ # The definition of <NumVal>, <PATH>, <Boolean>, <GUID>, <CString>,
+ # <UnicodeString>, <CArray> are subset of <AsciiString>.
+ #
+ ReIsValidMacroValue = re.compile(r"^[\x20-\x7e]*$", re.DOTALL)
+ if ReIsValidMacroValue.match(Value) == None:
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_MACROVALUE_INVALID%(Value),
+ ExtraData=LineContent,
+ File=FileName,
+ Line=LineNo)
+
+ return Name, Value
+
+## GenSection
+#
+# generate section contents
+#
+# @param SectionName: indicate the name of the section, details refer to
+# INF, DEC specs
+# @param SectionDict: section statement dict, key is SectionAttrs(arch,
+# moduletype or platform may exist as needed) list
+# seperated by space,
+# value is statement
+#
+def GenSection(SectionName, SectionDict, SplitArch=True):
+ Content = ''
+ for SectionAttrs in SectionDict:
+ StatementList = SectionDict[SectionAttrs]
+ if SectionAttrs and SectionName != 'Defines' and SectionAttrs.strip().upper() != DataType.TAB_ARCH_COMMON:
+ if SplitArch:
+ ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_SPACE_SPLIT)
+ else:
+ if SectionName != 'UserExtensions':
+ ArchList = GetSplitValueList(SectionAttrs, DataType.TAB_COMMENT_SPLIT)
+ else:
+ ArchList = [SectionAttrs]
+ for Index in xrange(0, len(ArchList)):
+ ArchList[Index] = ConvertArchForInstall(ArchList[Index])
+ Section = '[' + SectionName + '.' + (', ' + SectionName + '.').join(ArchList) + ']'
+ else:
+ Section = '[' + SectionName + ']'
+ Content += '\n\n' + Section + '\n'
+ if StatementList != None:
+ for Statement in StatementList:
+ Content += Statement + '\n'
+
+ return Content
+
+## ConvertArchForInstall
+# if Arch.upper() is in "IA32", "X64", "IPF", and "EBC", it must be upper case. "common" must be lower case.
+# Anything else, the case must be preserved
+#
+# @param Arch: the arch string that need to be converted, it should be stripped before pass in
+# @return: the arch string that get converted
+#
+def ConvertArchForInstall(Arch):
+ if Arch.upper() in [DataType.TAB_ARCH_IA32, DataType.TAB_ARCH_X64,
+ DataType.TAB_ARCH_IPF, DataType.TAB_ARCH_EBC]:
+ Arch = Arch.upper()
+ elif Arch.upper() == DataType.TAB_ARCH_COMMON:
+ Arch = Arch.lower()
+
+ return Arch
diff --git a/BaseTools/Source/Python/UPT/Library/String.py b/BaseTools/Source/Python/UPT/Library/String.py
new file mode 100644
index 0000000000..47301aebb0
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/String.py
@@ -0,0 +1,968 @@
+## @file
+# This file is used to define common string related functions used in parsing
+# process
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+String
+'''
+##
+# Import Modules
+#
+import re
+import os.path
+from string import strip
+import Logger.Log as Logger
+import Library.DataType as DataType
+from Logger.ToolError import FORMAT_INVALID
+from Logger.ToolError import PARSER_ERROR
+from Logger import StringTable as ST
+
+#
+# Regular expression for matching macro used in DSC/DEC/INF file inclusion
+#
+gMACRO_PATTERN = re.compile("\$\(([_A-Z][_A-Z0-9]*)\)", re.UNICODE)
+
+## GetSplitValueList
+#
+# Get a value list from a string with multiple values splited with SplitTag
+# The default SplitTag is DataType.TAB_VALUE_SPLIT
+# 'AAA|BBB|CCC' -> ['AAA', 'BBB', 'CCC']
+#
+# @param String: The input string to be splitted
+# @param SplitTag: The split key, default is DataType.TAB_VALUE_SPLIT
+# @param MaxSplit: The max number of split values, default is -1
+#
+#
+def GetSplitValueList(String, SplitTag=DataType.TAB_VALUE_SPLIT, MaxSplit=-1):
+ return map(lambda l: l.strip(), String.split(SplitTag, MaxSplit))
+
+## MergeArches
+#
+# Find a key's all arches in dict, add the new arch to the list
+# If not exist any arch, set the arch directly
+#
+# @param Dict: The input value for Dict
+# @param Key: The input value for Key
+# @param Arch: The Arch to be added or merged
+#
+def MergeArches(Dict, Key, Arch):
+ if Key in Dict.keys():
+ Dict[Key].append(Arch)
+ else:
+ Dict[Key] = Arch.split()
+
+## GenDefines
+#
+# Parse a string with format "DEFINE <VarName> = <PATH>"
+# Generate a map Defines[VarName] = PATH
+# Return False if invalid format
+#
+# @param String: String with DEFINE statement
+# @param Arch: Supportted Arch
+# @param Defines: DEFINE statement to be parsed
+#
+def GenDefines(String, Arch, Defines):
+ if String.find(DataType.TAB_DEFINE + ' ') > -1:
+ List = String.replace(DataType.TAB_DEFINE + ' ', '').\
+ split(DataType.TAB_EQUAL_SPLIT)
+ if len(List) == 2:
+ Defines[(CleanString(List[0]), Arch)] = CleanString(List[1])
+ return 0
+ else:
+ return -1
+ return 1
+
+## GetLibraryClassesWithModuleType
+#
+# Get Library Class definition when no module type defined
+#
+# @param Lines: The content to be parsed
+# @param Key: Reserved
+# @param KeyValues: To store data after parsing
+# @param CommentCharacter: Comment char, used to ignore comment content
+#
+def GetLibraryClassesWithModuleType(Lines, Key, KeyValues, CommentCharacter):
+ NewKey = SplitModuleType(Key)
+ Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
+ LineList = Lines.splitlines()
+ for Line in LineList:
+ Line = CleanString(Line, CommentCharacter)
+ if Line != '' and Line[0] != CommentCharacter:
+ KeyValues.append([CleanString(Line, CommentCharacter), NewKey[1]])
+
+ return True
+
+## GetDynamics
+#
+# Get Dynamic Pcds
+#
+# @param Lines: The content to be parsed
+# @param Key: Reserved
+# @param KeyValues: To store data after parsing
+# @param CommentCharacter: Comment char, used to ignore comment content
+#
+def GetDynamics(Lines, Key, KeyValues, CommentCharacter):
+ #
+ # Get SkuId Name List
+ #
+ SkuIdNameList = SplitModuleType(Key)
+
+ Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
+ LineList = Lines.splitlines()
+ for Line in LineList:
+ Line = CleanString(Line, CommentCharacter)
+ if Line != '' and Line[0] != CommentCharacter:
+ KeyValues.append([CleanString(Line, CommentCharacter), SkuIdNameList[1]])
+
+ return True
+
+## SplitModuleType
+#
+# Split ModuleType out of section defien to get key
+# [LibraryClass.Arch.ModuleType|ModuleType|ModuleType] -> [
+# 'LibraryClass.Arch', ['ModuleType', 'ModuleType', 'ModuleType'] ]
+#
+# @param Key: String to be parsed
+#
+def SplitModuleType(Key):
+ KeyList = Key.split(DataType.TAB_SPLIT)
+ #
+ # Fill in for arch
+ #
+ KeyList.append('')
+ #
+ # Fill in for moduletype
+ #
+ KeyList.append('')
+ ReturnValue = []
+ KeyValue = KeyList[0]
+ if KeyList[1] != '':
+ KeyValue = KeyValue + DataType.TAB_SPLIT + KeyList[1]
+ ReturnValue.append(KeyValue)
+ ReturnValue.append(GetSplitValueList(KeyList[2]))
+
+ return ReturnValue
+
+## Replace macro in string
+#
+# This method replace macros used in given string. The macros are given in a
+# dictionary.
+#
+# @param String String to be processed
+# @param MacroDefinitions The macro definitions in the form of dictionary
+# @param SelfReplacement To decide whether replace un-defined macro to ''
+# @param Line: The content contain line string and line number
+# @param FileName: The meta-file file name
+#
+def ReplaceMacro(String, MacroDefinitions = None, SelfReplacement = False, Line = None, FileName = None, Flag = False):
+ LastString = String
+ if MacroDefinitions == None:
+ MacroDefinitions = {}
+ while MacroDefinitions:
+ QuotedStringList = []
+ HaveQuotedMacroFlag = False
+ if not Flag:
+ MacroUsed = gMACRO_PATTERN.findall(String)
+ else:
+ ReQuotedString = re.compile('\"')
+ QuotedStringList = ReQuotedString.split(String)
+ if len(QuotedStringList) >= 3:
+ HaveQuotedMacroFlag = True
+ Count = 0
+ MacroString = ""
+ for QuotedStringItem in QuotedStringList:
+ Count += 1
+ if Count % 2 != 0:
+ MacroString += QuotedStringItem
+
+ if Count == len(QuotedStringList) and Count%2 == 0:
+ MacroString += QuotedStringItem
+
+ MacroUsed = gMACRO_PATTERN.findall(MacroString)
+ #
+ # no macro found in String, stop replacing
+ #
+ if len(MacroUsed) == 0:
+ break
+ for Macro in MacroUsed:
+ if Macro not in MacroDefinitions:
+ if SelfReplacement:
+ String = String.replace("$(%s)" % Macro, '')
+ Logger.Debug(5, "Delete undefined MACROs in file %s line %d: %s!" %(FileName, Line[1], Line[0]))
+ continue
+ if not HaveQuotedMacroFlag:
+ String = String.replace("$(%s)" % Macro, MacroDefinitions[Macro])
+ else:
+ Count = 0
+ for QuotedStringItem in QuotedStringList:
+ Count += 1
+ if Count % 2 != 0:
+ QuotedStringList[Count-1] = QuotedStringList[Count-1].replace("$(%s)" % Macro,
+ MacroDefinitions[Macro])
+ elif Count == len(QuotedStringList) and Count%2 == 0:
+ QuotedStringList[Count-1] = QuotedStringList[Count-1].replace("$(%s)" % Macro,
+ MacroDefinitions[Macro])
+
+ RetString = ''
+ if HaveQuotedMacroFlag:
+ Count = 0
+ for QuotedStringItem in QuotedStringList:
+ Count += 1
+ if Count != len(QuotedStringList):
+ RetString += QuotedStringList[Count-1] + "\""
+ else:
+ RetString += QuotedStringList[Count-1]
+
+ String = RetString
+
+ #
+ # in case there's macro not defined
+ #
+ if String == LastString:
+ break
+ LastString = String
+
+ return String
+
+## NormPath
+#
+# Create a normal path
+# And replace DFEINE in the path
+#
+# @param Path: The input value for Path to be converted
+# @param Defines: A set for DEFINE statement
+#
+def NormPath(Path, Defines = None):
+ IsRelativePath = False
+ if Defines == None:
+ Defines = {}
+ if Path:
+ if Path[0] == '.':
+ IsRelativePath = True
+ #
+ # Replace with Define
+ #
+ if Defines:
+ Path = ReplaceMacro(Path, Defines)
+ #
+ # To local path format
+ #
+ Path = os.path.normpath(Path)
+
+ if IsRelativePath and Path[0] != '.':
+ Path = os.path.join('.', Path)
+ return Path
+
+## CleanString
+#
+# Remove comments in a string
+# Remove spaces
+#
+# @param Line: The string to be cleaned
+# @param CommentCharacter: Comment char, used to ignore comment content,
+# default is DataType.TAB_COMMENT_SPLIT
+#
+def CleanString(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyleComment=False):
+ #
+ # remove whitespace
+ #
+ Line = Line.strip()
+ #
+ # Replace EDK1's comment character
+ #
+ if AllowCppStyleComment:
+ Line = Line.replace(DataType.TAB_COMMENT_EDK1_SPLIT, CommentCharacter)
+ #
+ # remove comments, but we should escape comment character in string
+ #
+ InString = False
+ for Index in range(0, len(Line)):
+ if Line[Index] == '"':
+ InString = not InString
+ elif Line[Index] == CommentCharacter and not InString:
+ Line = Line[0: Index]
+ break
+ #
+ # remove whitespace again
+ #
+ Line = Line.strip()
+
+ return Line
+
+## CleanString2
+#
+# Split comments in a string
+# Remove spaces
+#
+# @param Line: The string to be cleaned
+# @param CommentCharacter: Comment char, used to ignore comment content,
+# default is DataType.TAB_COMMENT_SPLIT
+#
+def CleanString2(Line, CommentCharacter=DataType.TAB_COMMENT_SPLIT, AllowCppStyleComment=False):
+ #
+ # remove whitespace
+ #
+ Line = Line.strip()
+ #
+ # Replace EDK1's comment character
+ #
+ if AllowCppStyleComment:
+ Line = Line.replace(DataType.TAB_COMMENT_EDK1_SPLIT, CommentCharacter)
+ #
+ # separate comments and statements
+ #
+ LineParts = Line.split(CommentCharacter, 1)
+ #
+ # remove whitespace again
+ #
+ Line = LineParts[0].strip()
+ if len(LineParts) > 1:
+ Comment = LineParts[1].strip()
+ #
+ # Remove prefixed and trailing comment characters
+ #
+ Start = 0
+ End = len(Comment)
+ while Start < End and Comment.startswith(CommentCharacter, Start, End):
+ Start += 1
+ while End >= 0 and Comment.endswith(CommentCharacter, Start, End):
+ End -= 1
+ Comment = Comment[Start:End]
+ Comment = Comment.strip()
+ else:
+ Comment = ''
+
+ return Line, Comment
+
+## GetMultipleValuesOfKeyFromLines
+#
+# Parse multiple strings to clean comment and spaces
+# The result is saved to KeyValues
+#
+# @param Lines: The content to be parsed
+# @param Key: Reserved
+# @param KeyValues: To store data after parsing
+# @param CommentCharacter: Comment char, used to ignore comment content
+#
+def GetMultipleValuesOfKeyFromLines(Lines, Key, KeyValues, CommentCharacter):
+ if Key:
+ pass
+ if KeyValues:
+ pass
+ Lines = Lines.split(DataType.TAB_SECTION_END, 1)[1]
+ LineList = Lines.split('\n')
+ for Line in LineList:
+ Line = CleanString(Line, CommentCharacter)
+ if Line != '' and Line[0] != CommentCharacter:
+ KeyValues += [Line]
+ return True
+
+## GetDefineValue
+#
+# Parse a DEFINE statement to get defined value
+# DEFINE Key Value
+#
+# @param String: The content to be parsed
+# @param Key: The key of DEFINE statement
+# @param CommentCharacter: Comment char, used to ignore comment content
+#
+def GetDefineValue(String, Key, CommentCharacter):
+ if CommentCharacter:
+ pass
+ String = CleanString(String)
+ return String[String.find(Key + ' ') + len(Key + ' ') : ]
+
+## GetSingleValueOfKeyFromLines
+#
+# Parse multiple strings as below to get value of each definition line
+# Key1 = Value1
+# Key2 = Value2
+# The result is saved to Dictionary
+#
+# @param Lines: The content to be parsed
+# @param Dictionary: To store data after parsing
+# @param CommentCharacter: Comment char, be used to ignore comment content
+# @param KeySplitCharacter: Key split char, between key name and key value.
+# Key1 = Value1, '=' is the key split char
+# @param ValueSplitFlag: Value split flag, be used to decide if has
+# multiple values
+# @param ValueSplitCharacter: Value split char, be used to split multiple
+# values. Key1 = Value1|Value2, '|' is the value
+# split char
+#
+def GetSingleValueOfKeyFromLines(Lines, Dictionary, CommentCharacter, KeySplitCharacter, \
+ ValueSplitFlag, ValueSplitCharacter):
+ Lines = Lines.split('\n')
+ Keys = []
+ Value = ''
+ DefineValues = ['']
+ SpecValues = ['']
+
+ for Line in Lines:
+ #
+ # Handle DEFINE and SPEC
+ #
+ if Line.find(DataType.TAB_INF_DEFINES_DEFINE + ' ') > -1:
+ if '' in DefineValues:
+ DefineValues.remove('')
+ DefineValues.append(GetDefineValue(Line, DataType.TAB_INF_DEFINES_DEFINE, CommentCharacter))
+ continue
+ if Line.find(DataType.TAB_INF_DEFINES_SPEC + ' ') > -1:
+ if '' in SpecValues:
+ SpecValues.remove('')
+ SpecValues.append(GetDefineValue(Line, DataType.TAB_INF_DEFINES_SPEC, CommentCharacter))
+ continue
+
+ #
+ # Handle Others
+ #
+ LineList = Line.split(KeySplitCharacter, 1)
+ if len(LineList) >= 2:
+ Key = LineList[0].split()
+ if len(Key) == 1 and Key[0][0] != CommentCharacter:
+ #
+ # Remove comments and white spaces
+ #
+ LineList[1] = CleanString(LineList[1], CommentCharacter)
+ if ValueSplitFlag:
+ Value = map(strip, LineList[1].split(ValueSplitCharacter))
+ else:
+ Value = CleanString(LineList[1], CommentCharacter).splitlines()
+
+ if Key[0] in Dictionary:
+ if Key[0] not in Keys:
+ Dictionary[Key[0]] = Value
+ Keys.append(Key[0])
+ else:
+ Dictionary[Key[0]].extend(Value)
+ else:
+ Dictionary[DataType.TAB_INF_DEFINES_MACRO][Key[0]] = Value[0]
+
+ if DefineValues == []:
+ DefineValues = ['']
+ if SpecValues == []:
+ SpecValues = ['']
+ Dictionary[DataType.TAB_INF_DEFINES_DEFINE] = DefineValues
+ Dictionary[DataType.TAB_INF_DEFINES_SPEC] = SpecValues
+
+ return True
+
+## The content to be parsed
+#
+# Do pre-check for a file before it is parsed
+# Check $()
+# Check []
+#
+# @param FileName: Used for error report
+# @param FileContent: File content to be parsed
+# @param SupSectionTag: Used for error report
+#
+def PreCheck(FileName, FileContent, SupSectionTag):
+ if SupSectionTag:
+ pass
+ LineNo = 0
+ IsFailed = False
+ NewFileContent = ''
+ for Line in FileContent.splitlines():
+ LineNo = LineNo + 1
+ #
+ # Clean current line
+ #
+ Line = CleanString(Line)
+ #
+ # Remove commented line
+ #
+ if Line.find(DataType.TAB_COMMA_SPLIT) == 0:
+ Line = ''
+ #
+ # Check $()
+ #
+ if Line.find('$') > -1:
+ if Line.find('$(') < 0 or Line.find(')') < 0:
+ Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = Logger.IS_RAISE_ERROR)
+ #
+ # Check []
+ #
+ if Line.find('[') > -1 or Line.find(']') > -1:
+ #
+ # Only get one '[' or one ']'
+ #
+ if not (Line.find('[') > -1 and Line.find(']') > -1):
+ Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = Logger.IS_RAISE_ERROR)
+ #
+ # Regenerate FileContent
+ #
+ NewFileContent = NewFileContent + Line + '\r\n'
+
+ if IsFailed:
+ Logger.Error("Parser", FORMAT_INVALID, Line=LineNo, File=FileName, RaiseError = Logger.IS_RAISE_ERROR)
+
+ return NewFileContent
+
+## CheckFileType
+#
+# Check if the Filename is including ExtName
+# Return True if it exists
+# Raise a error message if it not exists
+#
+# @param CheckFilename: Name of the file to be checked
+# @param ExtName: Ext name of the file to be checked
+# @param ContainerFilename: The container file which describes the file to be
+# checked, used for error report
+# @param SectionName: Used for error report
+# @param Line: The line in container file which defines the file
+# to be checked
+#
+def CheckFileType(CheckFilename, ExtName, ContainerFilename, SectionName, Line, LineNo=-1):
+ if CheckFilename != '' and CheckFilename != None:
+ (Root, Ext) = os.path.splitext(CheckFilename)
+ if Ext.upper() != ExtName.upper() and Root:
+ ContainerFile = open(ContainerFilename, 'r').read()
+ if LineNo == -1:
+ LineNo = GetLineNo(ContainerFile, Line)
+ ErrorMsg = ST.ERR_SECTIONNAME_INVALID % (SectionName, CheckFilename, ExtName)
+ Logger.Error("Parser", PARSER_ERROR, ErrorMsg, Line=LineNo, \
+ File=ContainerFilename, RaiseError=Logger.IS_RAISE_ERROR)
+
+ return True
+
+## CheckFileExist
+#
+# Check if the file exists
+# Return True if it exists
+# Raise a error message if it not exists
+#
+# @param CheckFilename: Name of the file to be checked
+# @param WorkspaceDir: Current workspace dir
+# @param ContainerFilename: The container file which describes the file to
+# be checked, used for error report
+# @param SectionName: Used for error report
+# @param Line: The line in container file which defines the
+# file to be checked
+#
+def CheckFileExist(WorkspaceDir, CheckFilename, ContainerFilename, SectionName, Line, LineNo=-1):
+ CheckFile = ''
+ if CheckFilename != '' and CheckFilename != None:
+ CheckFile = WorkspaceFile(WorkspaceDir, CheckFilename)
+ if not os.path.isfile(CheckFile):
+ ContainerFile = open(ContainerFilename, 'r').read()
+ if LineNo == -1:
+ LineNo = GetLineNo(ContainerFile, Line)
+ ErrorMsg = ST.ERR_CHECKFILE_NOTFOUND % (CheckFile, SectionName)
+ Logger.Error("Parser", PARSER_ERROR, ErrorMsg,
+ File=ContainerFilename, Line = LineNo, RaiseError=Logger.IS_RAISE_ERROR)
+ return CheckFile
+
+## GetLineNo
+#
+# Find the index of a line in a file
+#
+# @param FileContent: Search scope
+# @param Line: Search key
+#
+def GetLineNo(FileContent, Line, IsIgnoreComment=True):
+ LineList = FileContent.splitlines()
+ for Index in range(len(LineList)):
+ if LineList[Index].find(Line) > -1:
+ #
+ # Ignore statement in comment
+ #
+ if IsIgnoreComment:
+ if LineList[Index].strip()[0] == DataType.TAB_COMMENT_SPLIT:
+ continue
+ return Index + 1
+
+ return -1
+
+## RaiseParserError
+#
+# Raise a parser error
+#
+# @param Line: String which has error
+# @param Section: Used for error report
+# @param File: File which has the string
+# @param Format: Correct format
+#
+def RaiseParserError(Line, Section, File, Format='', LineNo=-1):
+ if LineNo == -1:
+ LineNo = GetLineNo(open(os.path.normpath(File), 'r').read(), Line)
+ ErrorMsg = ST.ERR_INVALID_NOTFOUND % (Line, Section)
+ if Format != '':
+ Format = "Correct format is " + Format
+ Logger.Error("Parser", PARSER_ERROR, ErrorMsg, File=File, Line=LineNo, \
+ ExtraData=Format, RaiseError=Logger.IS_RAISE_ERROR)
+
+## WorkspaceFile
+#
+# Return a full path with workspace dir
+#
+# @param WorkspaceDir: Workspace dir
+# @param Filename: Relative file name
+#
+def WorkspaceFile(WorkspaceDir, Filename):
+ return os.path.join(NormPath(WorkspaceDir), NormPath(Filename))
+
+## Split string
+#
+# Revmove '"' which startswith and endswith string
+#
+# @param String: The string need to be splited
+#
+def SplitString(String):
+ if String.startswith('\"'):
+ String = String[1:]
+ if String.endswith('\"'):
+ String = String[:-1]
+ return String
+
+## Convert To Sql String
+#
+# Replace "'" with "''" in each item of StringList
+#
+# @param StringList: A list for strings to be converted
+#
+def ConvertToSqlString(StringList):
+ return map(lambda s: s.replace("'", "''") , StringList)
+
+## Convert To Sql String
+#
+# Replace "'" with "''" in the String
+#
+# @param String: A String to be converted
+#
+def ConvertToSqlString2(String):
+ return String.replace("'", "''")
+
+## RemoveBlockComment
+#
+# Remove comment block
+#
+# @param Lines: Block Comment Lines
+#
+def RemoveBlockComment(Lines):
+ IsFindBlockComment = False
+ ReservedLine = ''
+ NewLines = []
+
+ for Line in Lines:
+ Line = Line.strip()
+ #
+ # Remove comment block
+ #
+ if Line.find(DataType.TAB_COMMENT_EDK1_START) > -1:
+ ReservedLine = GetSplitValueList(Line, DataType.TAB_COMMENT_EDK1_START, 1)[0]
+ IsFindBlockComment = True
+ if Line.find(DataType.TAB_COMMENT_EDK1_END) > -1:
+ Line = ReservedLine + GetSplitValueList(Line, DataType.TAB_COMMENT_EDK1_END, 1)[1]
+ ReservedLine = ''
+ IsFindBlockComment = False
+ if IsFindBlockComment:
+ NewLines.append('')
+ continue
+ NewLines.append(Line)
+ return NewLines
+
+## GetStringOfList
+#
+# Get String of a List
+#
+# @param Lines: string list
+# @param Split: split character
+#
+def GetStringOfList(List, Split = ' '):
+ if type(List) != type([]):
+ return List
+ Str = ''
+ for Item in List:
+ Str = Str + Item + Split
+ return Str.strip()
+
+## Get HelpTextList
+#
+# Get HelpTextList from HelpTextClassList
+#
+# @param HelpTextClassList: Help Text Class List
+#
+def GetHelpTextList(HelpTextClassList):
+ List = []
+ if HelpTextClassList:
+ for HelpText in HelpTextClassList:
+ if HelpText.String.endswith('\n'):
+ HelpText.String = HelpText.String[0: len(HelpText.String) - len('\n')]
+ List.extend(HelpText.String.split('\n'))
+ return List
+
+## Get String Array Length
+#
+# Get String Array Length
+#
+# @param String: the source string
+#
+def StringArrayLength(String):
+ if isinstance(String, unicode):
+ return (len(String) + 1) * 2 + 1
+ elif String.startswith('L"'):
+ return (len(String) - 3 + 1) * 2
+ elif String.startswith('"'):
+ return (len(String) - 2 + 1)
+ else:
+ return len(String.split()) + 1
+
+## RemoveDupOption
+#
+# Remove Dup Option
+#
+# @param OptionString: the option string
+# @param Which: Which flag
+# @param Against: Against flag
+#
+def RemoveDupOption(OptionString, Which="/I", Against=None):
+ OptionList = OptionString.split()
+ ValueList = []
+ if Against:
+ ValueList += Against
+ for Index in range(len(OptionList)):
+ Opt = OptionList[Index]
+ if not Opt.startswith(Which):
+ continue
+ if len(Opt) > len(Which):
+ Val = Opt[len(Which):]
+ else:
+ Val = ""
+ if Val in ValueList:
+ OptionList[Index] = ""
+ else:
+ ValueList.append(Val)
+ return " ".join(OptionList)
+
+## Check if the string is HexDgit
+#
+# Return true if all characters in the string are digits and there is at
+# least one character
+# or valid Hexs (started with 0x, following by hexdigit letters)
+# , false otherwise.
+# @param string: input string
+#
+def IsHexDigit(Str):
+ try:
+ int(Str, 10)
+ return True
+ except ValueError:
+ if len(Str) > 2 and Str.upper().startswith('0X'):
+ try:
+ int(Str, 16)
+ return True
+ except ValueError:
+ return False
+ return False
+
+## Check if the string is HexDgit and its interger value within limit of UINT32
+#
+# Return true if all characters in the string are digits and there is at
+# least one character
+# or valid Hexs (started with 0x, following by hexdigit letters)
+# , false otherwise.
+# @param string: input string
+#
+def IsHexDigitUINT32(Str):
+ try:
+ Value = int(Str, 10)
+ if (Value <= 0xFFFFFFFF) and (Value >= 0):
+ return True
+ except ValueError:
+ if len(Str) > 2 and Str.upper().startswith('0X'):
+ try:
+ Value = int(Str, 16)
+ if (Value <= 0xFFFFFFFF) and (Value >= 0):
+ return True
+ except ValueError:
+ return False
+ return False
+
+## CleanSpecialChar
+#
+# The ASCII text files of type INF, DEC, INI are edited by developers,
+# and may contain characters that cannot be directly translated to strings that
+# are conformant with the UDP XML Schema. Any characters in this category
+# (0x00-0x08, TAB [0x09], 0x0B, 0x0C, 0x0E-0x1F, 0x80-0xFF)
+# must be converted to a space character[0x20] as part of the parsing process.
+#
+def ConvertSpecialChar(Lines):
+ RetLines = []
+ for line in Lines:
+ ReMatchSpecialChar = re.compile(r"[\x00-\x08]|\x09|\x0b|\x0c|[\x0e-\x1f]|[\x7f-\xff]")
+ RetLines.append(ReMatchSpecialChar.sub(' ', line))
+
+ return RetLines
+
+## __GetTokenList
+#
+# Assume Str is a valid feature flag expression.
+# Return a list which contains tokens: alpha numeric token and other token
+# Whitespace are not stripped
+#
+def __GetTokenList(Str):
+ InQuote = False
+ Token = ''
+ TokenOP = ''
+ PreChar = ''
+ List = []
+ for Char in Str:
+ if InQuote:
+ Token += Char
+ if Char == '"' and PreChar != '\\':
+ InQuote = not InQuote
+ List.append(Token)
+ Token = ''
+ continue
+ if Char == '"':
+ if Token and Token != 'L':
+ List.append(Token)
+ Token = ''
+ if TokenOP:
+ List.append(TokenOP)
+ TokenOP = ''
+ InQuote = not InQuote
+ Token += Char
+ continue
+
+ if not (Char.isalnum() or Char in '_'):
+ TokenOP += Char
+ if Token:
+ List.append(Token)
+ Token = ''
+ else:
+ Token += Char
+ if TokenOP:
+ List.append(TokenOP)
+ TokenOP = ''
+
+ if PreChar == '\\' and Char == '\\':
+ PreChar = ''
+ else:
+ PreChar = Char
+ if Token:
+ List.append(Token)
+ if TokenOP:
+ List.append(TokenOP)
+ return List
+
+## ConvertNEToNOTEQ
+#
+# Convert NE operator to NOT EQ
+# For example: 1 NE 2 -> 1 NOT EQ 2
+#
+# @param Expr: Feature flag expression to be converted
+#
+def ConvertNEToNOTEQ(Expr):
+ List = __GetTokenList(Expr)
+ for Index in range(len(List)):
+ if List[Index] == 'NE':
+ List[Index] = 'NOT EQ'
+ return ''.join(List)
+
+## ConvertNOTEQToNE
+#
+# Convert NOT EQ operator to NE
+# For example: 1 NOT NE 2 -> 1 NE 2
+#
+# @param Expr: Feature flag expression to be converted
+#
+def ConvertNOTEQToNE(Expr):
+ List = __GetTokenList(Expr)
+ HasNOT = False
+ RetList = []
+ for Token in List:
+ if HasNOT and Token == 'EQ':
+ # At least, 'NOT' is in the list
+ while not RetList[-1].strip():
+ RetList.pop()
+ RetList[-1] = 'NE'
+ HasNOT = False
+ continue
+ if Token == 'NOT':
+ HasNOT = True
+ elif Token.strip():
+ HasNOT = False
+ RetList.append(Token)
+
+ return ''.join(RetList)
+
+## SplitPcdEntry
+#
+# Split an PCD entry string to Token.CName and PCD value and FFE.
+# NOTE: PCD Value and FFE can contain "|" in it's expression. And in INF specification, have below rule.
+# When using the characters "|" or "||" in an expression, the expression must be encapsulated in
+# open "(" and close ")" parenthesis.
+#
+# @param String An PCD entry string need to be split.
+#
+# @return List [PcdTokenCName, Value, FFE]
+#
+def SplitPcdEntry(String):
+ if not String:
+ return ['', '',''], False
+
+ PcdTokenCName = ''
+ PcdValue = ''
+ PcdFeatureFlagExp = ''
+
+ ValueList = GetSplitValueList(String, "|", 1)
+
+ #
+ # Only contain TokenCName
+ #
+ if len(ValueList) == 1:
+ return [ValueList[0]], True
+
+ NewValueList = []
+
+ if len(ValueList) == 2:
+ PcdTokenCName = ValueList[0]
+ ValueList = GetSplitValueList(ValueList[1], "|")
+
+ RemainCount = 0
+ for Item in ValueList:
+ ParenthesisCount = 0
+ for Char in Item:
+ if Char == "(":
+ ParenthesisCount += 1
+ if Char == ")":
+ ParenthesisCount -= 1
+
+ #
+ # An individual item
+ #
+ if RemainCount == 0 and ParenthesisCount >= 0:
+ NewValueList.append(Item)
+ RemainCount = ParenthesisCount
+ elif RemainCount > 0 and RemainCount + ParenthesisCount >= 0:
+ NewValueList[-1] = NewValueList[-1] + '|' + Item
+ RemainCount = RemainCount + ParenthesisCount
+ elif RemainCount > 0 and RemainCount + ParenthesisCount < 0:
+ #
+ # ERROR, return
+ #
+ return ['', '', ''], False
+
+ if len(NewValueList) == 1:
+ PcdValue = NewValueList[0]
+ return [PcdTokenCName, PcdValue], True
+ elif len(NewValueList) == 2:
+ PcdValue = NewValueList[0]
+ PcdFeatureFlagExp = NewValueList[1]
+ return [PcdTokenCName, PcdValue, PcdFeatureFlagExp], True
+ else:
+ return ['', '', ''], False
+
+ return ['', '', ''], False
diff --git a/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py b/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py
new file mode 100644
index 0000000000..7029e59889
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py
@@ -0,0 +1,228 @@
+## @file
+# This is an XML API that uses a syntax similar to XPath, but it is written in
+# standard python so that no extra python packages are required to use it.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+XmlRoutines
+'''
+
+##
+# Import Modules
+#
+import xml.dom.minidom
+import re
+from Logger.ToolError import PARSER_ERROR
+import Logger.Log as Logger
+
+## Create a element of XML
+#
+# @param Name
+# @param String
+# @param NodeList
+# @param AttributeList
+#
+def CreateXmlElement(Name, String, NodeList, AttributeList):
+ Doc = xml.dom.minidom.Document()
+ Element = Doc.createElement(Name)
+ if String != '' and String != None:
+ Element.appendChild(Doc.createTextNode(String))
+
+ for Item in NodeList:
+ if type(Item) == type([]):
+ Key = Item[0]
+ Value = Item[1]
+ if Key != '' and Key != None and Value != '' and Value != None:
+ Node = Doc.createElement(Key)
+ Node.appendChild(Doc.createTextNode(Value))
+ Element.appendChild(Node)
+ else:
+ Element.appendChild(Item)
+ for Item in AttributeList:
+ Key = Item[0]
+ Value = Item[1]
+ if Key != '' and Key != None and Value != '' and Value != None:
+ Element.setAttribute(Key, Value)
+
+ return Element
+
+## Get a list of XML nodes using XPath style syntax.
+#
+# Return a list of XML DOM nodes from the root Dom specified by XPath String.
+# If the input Dom or String is not valid, then an empty list is returned.
+#
+# @param Dom The root XML DOM node.
+# @param String A XPath style path.
+#
+def XmlList(Dom, String):
+ if String == None or String == "" or Dom == None or Dom == "":
+ return []
+ if Dom.nodeType == Dom.DOCUMENT_NODE:
+ Dom = Dom.documentElement
+ if String[0] == "/":
+ String = String[1:]
+ TagList = String.split('/')
+ Nodes = [Dom]
+ Index = 0
+ End = len(TagList) - 1
+ while Index <= End:
+ ChildNodes = []
+ for Node in Nodes:
+ if Node.nodeType == Node.ELEMENT_NODE and Node.tagName == \
+ TagList[Index]:
+ if Index < End:
+ ChildNodes.extend(Node.childNodes)
+ else:
+ ChildNodes.append(Node)
+ Nodes = ChildNodes
+ ChildNodes = []
+ Index += 1
+
+ return Nodes
+
+
+## Get a single XML node using XPath style syntax.
+#
+# Return a single XML DOM node from the root Dom specified by XPath String.
+# If the input Dom or String is not valid, then an empty string is returned.
+#
+# @param Dom The root XML DOM node.
+# @param String A XPath style path.
+#
+def XmlNode(Dom, String):
+ if String == None or String == "" or Dom == None or Dom == "":
+ return None
+ if Dom.nodeType == Dom.DOCUMENT_NODE:
+ Dom = Dom.documentElement
+ if String[0] == "/":
+ String = String[1:]
+ TagList = String.split('/')
+ Index = 0
+ End = len(TagList) - 1
+ ChildNodes = [Dom]
+ while Index <= End:
+ for Node in ChildNodes:
+ if Node.nodeType == Node.ELEMENT_NODE and \
+ Node.tagName == TagList[Index]:
+ if Index < End:
+ ChildNodes = Node.childNodes
+ else:
+ return Node
+ break
+ Index += 1
+ return None
+
+
+## Get a single XML element using XPath style syntax.
+#
+# Return a single XML element from the root Dom specified by XPath String.
+# If the input Dom or String is not valid, then an empty string is returned.
+#
+# @param Dom The root XML DOM object.
+# @param Strin A XPath style path.
+#
+def XmlElement(Dom, String):
+ try:
+ return XmlNode(Dom, String).firstChild.data.strip()
+ except BaseException:
+ return ""
+
+## Get a single XML element using XPath style syntax.
+#
+# Similar with XmlElement, but do not strip all the leading and tailing space
+# and newline, instead just remove the newline and spaces introduced by
+# toprettyxml()
+#
+# @param Dom The root XML DOM object.
+# @param Strin A XPath style path.
+#
+def XmlElement2(Dom, String):
+ try:
+ HelpStr = XmlNode(Dom, String).firstChild.data
+ gRemovePrettyRe = re.compile(r"""(?:(\n *) )(.*)\1""", re.DOTALL)
+ HelpStr = re.sub(gRemovePrettyRe, r"\2", HelpStr)
+ return HelpStr
+ except BaseException:
+ return ""
+
+
+## Get a single XML element of the current node.
+#
+# Return a single XML element specified by the current root Dom.
+# If the input Dom is not valid, then an empty string is returned.
+#
+# @param Dom The root XML DOM object.
+#
+def XmlElementData(Dom):
+ try:
+ return Dom.firstChild.data.strip()
+ except BaseException:
+ return ""
+
+
+## Get a list of XML elements using XPath style syntax.
+#
+# Return a list of XML elements from the root Dom specified by XPath String.
+# If the input Dom or String is not valid, then an empty list is returned.
+#
+# @param Dom The root XML DOM object.
+# @param String A XPath style path.
+#
+def XmlElementList(Dom, String):
+ return map(XmlElementData, XmlList(Dom, String))
+
+
+## Get the XML attribute of the current node.
+#
+# Return a single XML attribute named Attribute from the current root Dom.
+# If the input Dom or Attribute is not valid, then an empty string is returned.
+#
+# @param Dom The root XML DOM object.
+# @param Attribute The name of Attribute.
+#
+def XmlAttribute(Dom, Attribute):
+ try:
+ return Dom.getAttribute(Attribute)
+ except BaseException:
+ return ''
+
+
+## Get the XML node name of the current node.
+#
+# Return a single XML node name from the current root Dom.
+# If the input Dom is not valid, then an empty string is returned.
+#
+# @param Dom The root XML DOM object.
+#
+def XmlNodeName(Dom):
+ try:
+ return Dom.nodeName.strip()
+ except BaseException:
+ return ''
+
+## Parse an XML file.
+#
+# Parse the input XML file named FileName and return a XML DOM it stands for.
+# If the input File is not a valid XML file, then an empty string is returned.
+#
+# @param FileName The XML file name.
+#
+def XmlParseFile(FileName):
+ try:
+ XmlFile = open(FileName)
+ Dom = xml.dom.minidom.parse(XmlFile)
+ XmlFile.close()
+ return Dom
+ except BaseException, XExcept:
+ XmlFile.close()
+ Logger.Error('\nUPT', PARSER_ERROR, XExcept, File=FileName, RaiseError=True)
diff --git a/BaseTools/Source/Python/UPT/Library/Xml/__init__.py b/BaseTools/Source/Python/UPT/Library/Xml/__init__.py
new file mode 100644
index 0000000000..5d268d990b
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/Xml/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Library' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Xml
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Library/__init__.py b/BaseTools/Source/Python/UPT/Library/__init__.py
new file mode 100644
index 0000000000..b265bc873c
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Library/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Library' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Library
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Logger/Log.py b/BaseTools/Source/Python/UPT/Logger/Log.py
new file mode 100644
index 0000000000..0915bb7263
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Logger/Log.py
@@ -0,0 +1,325 @@
+## @file
+# This file implements the log mechanism for Python tools.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Logger
+'''
+
+## Import modules
+from sys import argv
+from sys import stdout
+from sys import stderr
+import os.path
+from os import remove
+from logging import getLogger
+from logging import Formatter
+from logging import StreamHandler
+from logging import FileHandler
+from traceback import extract_stack
+
+from Logger.ToolError import FatalError
+from Logger.ToolError import WARNING_AS_ERROR
+from Logger.ToolError import gERROR_MESSAGE
+from Logger.ToolError import UNKNOWN_ERROR
+from Library import GlobalData
+
+#
+# Log level constants
+#
+DEBUG_0 = 1
+DEBUG_1 = 2
+DEBUG_2 = 3
+DEBUG_3 = 4
+DEBUG_4 = 5
+DEBUG_5 = 6
+DEBUG_6 = 7
+DEBUG_7 = 8
+DEBUG_8 = 9
+DEBUG_9 = 10
+VERBOSE = 15
+INFO = 20
+WARN = 30
+QUIET = 40
+QUIET_1 = 41
+ERROR = 50
+SILENT = 60
+
+IS_RAISE_ERROR = True
+SUPRESS_ERROR = False
+
+#
+# Tool name
+#
+_TOOL_NAME = os.path.basename(argv[0])
+#
+# For validation purpose
+#
+_LOG_LEVELS = [DEBUG_0, DEBUG_1, DEBUG_2, DEBUG_3, DEBUG_4, DEBUG_5, DEBUG_6, \
+ DEBUG_7, DEBUG_8, DEBUG_9, VERBOSE, WARN, INFO, ERROR, QUIET, \
+ QUIET_1, SILENT]
+#
+# For DEBUG level (All DEBUG_0~9 are applicable)
+#
+_DEBUG_LOGGER = getLogger("tool_debug")
+_DEBUG_FORMATTER = Formatter("[%(asctime)s.%(msecs)d]: %(message)s", \
+ datefmt="%H:%M:%S")
+#
+# For VERBOSE, INFO, WARN level
+#
+_INFO_LOGGER = getLogger("tool_info")
+_INFO_FORMATTER = Formatter("%(message)s")
+#
+# For ERROR level
+#
+_ERROR_LOGGER = getLogger("tool_error")
+_ERROR_FORMATTER = Formatter("%(message)s")
+
+#
+# String templates for ERROR/WARN/DEBUG log message
+#
+_ERROR_MESSAGE_TEMPLATE = \
+('\n\n%(tool)s...\n%(file)s(%(line)s): error %(errorcode)04X: %(msg)s\n\t%(extra)s')
+
+__ERROR_MESSAGE_TEMPLATE_WITHOUT_FILE = \
+'\n\n%(tool)s...\n : error %(errorcode)04X: %(msg)s\n\t%(extra)s'
+
+_WARNING_MESSAGE_TEMPLATE = '%(tool)s...\n%(file)s(%(line)s): warning: %(msg)s'
+_WARNING_MESSAGE_TEMPLATE_WITHOUT_FILE = '%(tool)s: : warning: %(msg)s'
+_DEBUG_MESSAGE_TEMPLATE = '%(file)s(%(line)s): debug: \n %(msg)s'
+
+
+#
+# Log INFO message
+#
+#Info = _INFO_LOGGER.info
+
+def Info(msg, *args, **kwargs):
+ _INFO_LOGGER.info(msg, *args, **kwargs)
+
+#
+# Log information which should be always put out
+#
+def Quiet(msg, *args, **kwargs):
+ _ERROR_LOGGER.error(msg, *args, **kwargs)
+
+## Log debug message
+#
+# @param Level DEBUG level (DEBUG0~9)
+# @param Message Debug information
+# @param ExtraData More information associated with "Message"
+#
+def Debug(Level, Message, ExtraData=None):
+ if _DEBUG_LOGGER.level > Level:
+ return
+ if Level > DEBUG_9:
+ return
+ #
+ # Find out the caller method information
+ #
+ CallerStack = extract_stack()[-2]
+ TemplateDict = {
+ "file" : CallerStack[0],
+ "line" : CallerStack[1],
+ "msg" : Message,
+ }
+
+ if ExtraData != None:
+ LogText = _DEBUG_MESSAGE_TEMPLATE % TemplateDict + "\n %s" % ExtraData
+ else:
+ LogText = _DEBUG_MESSAGE_TEMPLATE % TemplateDict
+
+ _DEBUG_LOGGER.log(Level, LogText)
+
+## Log verbose message
+#
+# @param Message Verbose information
+#
+def Verbose(Message):
+ return _INFO_LOGGER.log(VERBOSE, Message)
+
+## Log warning message
+#
+# Warning messages are those which might be wrong but won't fail the tool.
+#
+# @param ToolName The name of the tool. If not given, the name of caller
+# method will be used.
+# @param Message Warning information
+# @param File The name of file which caused the warning.
+# @param Line The line number in the "File" which caused the warning.
+# @param ExtraData More information associated with "Message"
+#
+def Warn(ToolName, Message, File=None, Line=None, ExtraData=None):
+ if _INFO_LOGGER.level > WARN:
+ return
+ #
+ # if no tool name given, use caller's source file name as tool name
+ #
+ if ToolName == None or ToolName == "":
+ ToolName = os.path.basename(extract_stack()[-2][0])
+
+ if Line == None:
+ Line = "..."
+ else:
+ Line = "%d" % Line
+
+ TemplateDict = {
+ "tool" : ToolName,
+ "file" : File,
+ "line" : Line,
+ "msg" : Message,
+ }
+
+ if File != None:
+ LogText = _WARNING_MESSAGE_TEMPLATE % TemplateDict
+ else:
+ LogText = _WARNING_MESSAGE_TEMPLATE_WITHOUT_FILE % TemplateDict
+
+ if ExtraData != None:
+ LogText += "\n %s" % ExtraData
+
+ _INFO_LOGGER.log(WARN, LogText)
+ #
+ # Raise an execption if indicated
+ #
+ if GlobalData.gWARNING_AS_ERROR == True:
+ raise FatalError(WARNING_AS_ERROR)
+
+## Log ERROR message
+#
+# Once an error messages is logged, the tool's execution will be broken by
+# raising an execption. If you don't want to break the execution later, you
+# can give "RaiseError" with "False" value.
+#
+# @param ToolName The name of the tool. If not given, the name of caller
+# method will be used.
+# @param ErrorCode The error code
+# @param Message Warning information
+# @param File The name of file which caused the error.
+# @param Line The line number in the "File" which caused the warning.
+# @param ExtraData More information associated with "Message"
+# @param RaiseError Raise an exception to break the tool's executuion if
+# it's True. This is the default behavior.
+#
+def Error(ToolName, ErrorCode, Message=None, File=None, Line=None, \
+ ExtraData=None, RaiseError=IS_RAISE_ERROR):
+ if ToolName:
+ pass
+ if Line == None:
+ Line = "..."
+ else:
+ Line = "%d" % Line
+
+ if Message == None:
+ if ErrorCode in gERROR_MESSAGE:
+ Message = gERROR_MESSAGE[ErrorCode]
+ else:
+ Message = gERROR_MESSAGE[UNKNOWN_ERROR]
+
+ if ExtraData == None:
+ ExtraData = ""
+
+ TemplateDict = {
+ "tool" : _TOOL_NAME,
+ "file" : File,
+ "line" : Line,
+ "errorcode" : ErrorCode,
+ "msg" : Message,
+ "extra" : ExtraData
+ }
+
+ if File != None:
+ LogText = _ERROR_MESSAGE_TEMPLATE % TemplateDict
+ else:
+ LogText = __ERROR_MESSAGE_TEMPLATE_WITHOUT_FILE % TemplateDict
+
+ if not SUPRESS_ERROR:
+ _ERROR_LOGGER.log(ERROR, LogText)
+ if RaiseError:
+ raise FatalError(ErrorCode)
+
+
+## Initialize log system
+#
+def Initialize():
+ #
+ # Since we use different format to log different levels of message into
+ # different place (stdout or stderr), we have to use different "Logger"
+ # objects to do this.
+ #
+ # For DEBUG level (All DEBUG_0~9 are applicable)
+ _DEBUG_LOGGER.setLevel(INFO)
+ _DebugChannel = StreamHandler(stdout)
+ _DebugChannel.setFormatter(_DEBUG_FORMATTER)
+ _DEBUG_LOGGER.addHandler(_DebugChannel)
+ #
+ # For VERBOSE, INFO, WARN level
+ #
+ _INFO_LOGGER.setLevel(INFO)
+ _InfoChannel = StreamHandler(stdout)
+ _InfoChannel.setFormatter(_INFO_FORMATTER)
+ _INFO_LOGGER.addHandler(_InfoChannel)
+ #
+ # For ERROR level
+ #
+ _ERROR_LOGGER.setLevel(INFO)
+ _ErrorCh = StreamHandler(stderr)
+ _ErrorCh.setFormatter(_ERROR_FORMATTER)
+ _ERROR_LOGGER.addHandler(_ErrorCh)
+
+
+## Set log level
+#
+# @param Level One of log level in _LogLevel
+#
+def SetLevel(Level):
+ if Level not in _LOG_LEVELS:
+ Info("Not supported log level (%d). Use default level instead." % \
+ Level)
+ Level = INFO
+ _DEBUG_LOGGER.setLevel(Level)
+ _INFO_LOGGER.setLevel(Level)
+ _ERROR_LOGGER.setLevel(Level)
+
+## Get current log level
+#
+def GetLevel():
+ return _INFO_LOGGER.getEffectiveLevel()
+
+## Raise up warning as error
+#
+def SetWarningAsError():
+ GlobalData.gWARNING_AS_ERROR = True
+
+## Specify a file to store the log message as well as put on console
+#
+# @param LogFile The file path used to store the log message
+#
+def SetLogFile(LogFile):
+ if os.path.exists(LogFile):
+ remove(LogFile)
+
+ _Ch = FileHandler(LogFile)
+ _Ch.setFormatter(_DEBUG_FORMATTER)
+ _DEBUG_LOGGER.addHandler(_Ch)
+
+ _Ch = FileHandler(LogFile)
+ _Ch.setFormatter(_INFO_FORMATTER)
+ _INFO_LOGGER.addHandler(_Ch)
+
+ _Ch = FileHandler(LogFile)
+ _Ch.setFormatter(_ERROR_FORMATTER)
+ _ERROR_LOGGER.addHandler(_Ch)
+
+
+
diff --git a/BaseTools/Source/Python/UPT/Logger/StringTable.py b/BaseTools/Source/Python/UPT/Logger/StringTable.py
new file mode 100644
index 0000000000..230c659189
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Logger/StringTable.py
@@ -0,0 +1,768 @@
+## @file
+# This file is used to define strings used in the UPT tool
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+"""
+This file contains user visible strings in a format that can be used for
+localization
+"""
+
+import gettext
+
+#
+# string table starts here...
+#
+
+## strings are classified as following types
+# MSG_...: it is a message string
+# ERR_...: it is a error string
+# WRN_...: it is a warning string
+# HLP_...: it is a help string
+#
+
+_ = gettext.gettext
+
+MSG_USAGE_STRING = _("\n"
+ "Intel(r) UEFI Packaging Tool (Intel(r) UEFIPT)\n"
+ "%prog [options]"
+ )
+
+##
+# Version and Copyright
+#
+MSG_VERSION_NUMBER = _("1.0")
+MSG_VERSION = _("Intel(r) UEFI Packaging Tool (Intel(r) UEFIPT) - Revision " + \
+ MSG_VERSION_NUMBER)
+MSG_COPYRIGHT = _("Copyright (c) 2011 Intel Corporation All Rights Reserved.")
+MSG_VERSION_COPYRIGHT = _("\n %s\n %s" % (MSG_VERSION, MSG_COPYRIGHT))
+MSG_USAGE = _("%s [options]\n%s" % ("upt.exe", MSG_VERSION_COPYRIGHT))
+MSG_DESCRIPTION = _("The Intel(r) UEFIUPT is used to create, " + \
+ "install or remove a UEFI Distribution Package.")
+
+
+#
+# INF Parser related strings.
+#
+ERR_INF_PARSER_HEADER_FILE = _(
+ "The Header comment section should start with an @file at the top.")
+ERR_INF_PARSER_HEADER_MISSGING = _(
+ "The Header comment is missing. It must be corrected before continuing.")
+ERR_INF_PARSER_UNKNOWN_SECTION = _("An unknown section was found. "
+ "It must be corrected before continuing. ")
+ERR_INF_PARSER_NO_SECTION_ERROR = _("No section was found. "
+ "A section must be included before continuing.")
+ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID = \
+ _("Build Option format incorrect.")
+ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID = _(
+ "The format of binary %s item is incorrect. "
+ "It should contain at least 2 elements.")
+ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX = _(
+ "The format of binary %s item is invalid, "
+ "it should contain not more than %d elements.")
+ERR_INF_PARSER_BINARY_ITEM_INVALID_FILETYPE = _(
+ "The Binary FileType is incorrect. It should in %s")
+ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST = _(
+ "The Binary File: %s not exist.")
+ERR_INF_PARSER_BINARY_VER_TYPE = _(
+ "Only this type is allowed: \"%s\".")
+ERR_INF_PARSER_MULTI_DEFINE_SECTION = \
+ _("Multiple define sections found. "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND = \
+ _("More then 1 %s is defined in DEFINES section. "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_DEFINE_NAME_INVALID = \
+ _("Incorrect name format for : %s")
+ERR_INF_PARSER_DEFINE_GUID_INVALID = \
+ _("The format of this GUID is incorrect: %s")
+ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID = _("Incorrect MODULE_TYPE: %s")
+ERR_INF_PARSER_DEFINE_FROMAT_INVALID = _("Incorrect format: %s")
+ERR_INF_PARSER_FILE_NOT_EXIST = _("This file does not exist: %s")
+ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID = \
+ _("The file does not exist or has an incorrect file name or not in "
+ "sub-directories of the directory containing the INF file: %s. "
+ "It must be corrected before continuing")
+ERR_INF_PARSER_DEFINE_SHADOW_INVALID = \
+ _("The SHADOW keyword is only valid for"
+ " SEC, PEI_CORE and PEIM module types.")
+ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID = \
+ _("The format of the section header is incorrect")
+ERR_INF_PARSER_DEPEX_SECTION_INVALID = \
+ _("A module can't have a Depex section when its module type is %s")
+ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_LIBRARY_CLASS = \
+ _("A library class can't have a Depex section when its supported module type list is not defined.")
+ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_DRIVER = \
+ _("A driver can't have a Depex section when its module type is UEFI_DRIVER.")
+ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED = \
+ _("Cannot determine the module's Depex type. The Depex's module types are conflict")
+ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST = _(
+ "No %s found in INF file, please check it.")
+ERR_INF_PARSER_DEPEX_SECTION_MODULE_TYPE_ERROR = \
+ _("The module type of [Depex] section is invalid, not support type of %s")
+ERR_INF_PARSER_DEPEX_SECTION_CONTENT_MISSING = \
+ _("Missing content in: %s")
+ERR_INF_PARSER_DEPEX_SECTION_CONTENT_ERROR = \
+ _("The [Depex] section contains invalid content: %s")
+ERR_INF_PARSER_DEPEX_SECTION_SEC_TYPE_ERROR = \
+ _("The format is incorrect. The section type keyword of the content in the"
+ " [Depex] section is only for 'PEI_DEPEX', 'DXE_DEPEX', 'SMM_DEPEX', "
+ "it does not support type: %s")
+ERR_INF_PARSER_UE_SECTION_USER_ID_ERROR = \
+ _("This format is incorrect. "
+ "The UserID: %s in [UserExtension] section is incorrect.")
+ERR_INF_PARSER_UE_SECTION_ID_STRING_ERROR = \
+ _("This format is incorrect. "
+ "IdString: %s in [UserExtension] section is incorrect.")
+ERR_INF_PARSER_LIBRARY_SECTION_CONTENT_ERROR = \
+ _("The format is incorrect. "
+ "You can only have a Library name and a Feature flag in one line.")
+ERR_INF_PARSER_LIBRARY_SECTION_LIBNAME_MISSING = \
+ _("Format invalid. Please specify a library name.")
+ERR_INF_PARSER_SOURCES_SECTION_CONTENT_ERROR = \
+ _("The format is incorrect. It should be formated as follows: "
+ "FileName, Family | TagName | ToolCode | FeatureFlagExpr.")
+ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR = \
+ _("The PCD section type is incorrect. The value should be this list: %s")
+ERR_INF_PARSER_PCD_SECTION_CONTENT_ERROR = \
+ _("PcdName format invalid."
+ "Should like following: PcdName | Value | FeatureFlag.")
+ERR_INF_PARSER_PCD_NAME_FORMAT_ERROR = \
+ _("Format invalid."
+ "Should like following: <TokenSpaceGuidCName>.<PcdCName> ")
+ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR = \
+ _("The format is incorrect. "
+ "It should be formated as follows: CName | FeatureFlag.")
+ERR_INF_PARSER_PACKAGE_SECTION_CONTENT_ERROR = \
+ _("The format is incorrect. "
+ "It should be formated as follows: <TokenSpaceGuidCName>.<PcdCName>")
+ERR_INF_PARSER_PCD_TAIL_COMMENTS_INVALID = \
+ _("The format is incorrect. "
+ "Multiple usage descriptions must be described on subsequent lines.")
+ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR = \
+ _("This section format is incorrect: %s.")
+ERR_INF_PARSER_SECTION_NAME_DUPLICATE = \
+ _("This section has multiple section names, "
+ "only one section name is permitted.")
+ERR_INF_PARSER_SECTION_ARCH_CONFLICT = \
+ _("The 'common' ARCH must not be used with the specified ARCHs.")
+ERR_INF_PARSER_SOURCE_SECTION_TAGNAME_INVALID = \
+ _("This TagName is incorrect: %s. "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_TAGNAME_NOT_PERMITTED = \
+ _("TagName is not permitted: %s. "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_TOOLCODE_NOT_PERMITTED = \
+ _("ToolCode is not permitted: %s. "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_SOURCE_SECTION_FAMILY_INVALID = \
+ _("This family is incorrect: %s. "
+ "It must be corrected before continuing. ")
+ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID = \
+ _("This SectionName is incorrect: %s. "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_PCD_CVAR_GUID = \
+ _("TokenSpaceGuidCName must be valid C variable format.")
+ERR_INF_PARSER_PCD_CVAR_PCDCNAME = \
+ _("PcdCName must be valid C variable format.")
+ERR_INF_PARSER_PCD_VALUE_INVALID = \
+ _("The PCD value is incorrect. It must be corrected before continuing.")
+ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID = \
+ _("Incorrect feature flag expression: %s")
+ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING = \
+ _("The feature flag expression is missing. Please specify a feature flag.")
+ERR_INF_PARSER_INVALID_CNAME = \
+ _("Incorrect CName: %s. You must specify a valid C variable name.")
+ERR_INF_PARSER_CNAME_MISSING = \
+ _("Missing CName. Specify a valid C variable name.")
+ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID = \
+ _("The Define section contains an invalid keyword: \"%s\"."
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_FILE_MISS_DEFINE = \
+ _("The following file listed in the module "
+ "directory is not listed in the INF: %s")
+ERR_INF_PARSER_VERSION_NUMBER_DEPRICATED = \
+ _("VERSION_NUMBER depricated. "
+ "The INF file %s should be modified to use the VERSION_STRING instead.")
+ERR_INF_PARSER_VER_EXIST_BOTH_NUM_STR = \
+ _("The INF file %s defines both VERSION_NUMBER and VERSION_STRING, "
+ "using VERSION_STRING")
+ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF = _("EDKI INF is not supported")
+
+ERR_INF_PARSER_FEATUREPCD_USAGE_INVALID = _("The usage for FeaturePcd can only"
+ " be type of \"CONSUMES\".")
+
+ERR_INF_PARSER_DEFINE_ITEM_NO_NAME = _("No name specified")
+ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE = _("No value specified")
+
+ERR_INF_PARSER_MODULETYPE_INVALID = _("Drivers and applications are not allowed to have a MODULE_TYPE of \"BASE\". "
+"Only libraries are permitted to a have a MODULE_TYPE of \"BASE\".")
+ERR_INF_GET_PKG_DEPENDENCY_FAIL = _("Failed to get PackageDependencies information from file %s")
+ERR_INF_NO_PKG_DEPENDENCY_INFO = _("There are no packages defined that use the AsBuilt PCD information.")
+
+#
+# Item duplicate
+#
+ERR_INF_PARSER_ITEM_DUPLICATE = _("%s define duplicated! "
+ "It must be corrected before continuing.")
+ERR_INF_PARSER_ITEM_DUPLICATE_COMMON = _("%s define duplicated! Item listed"
+"in an architectural section must not be listed in the common architectural"
+"section.It must be corrected before continuing.")
+ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR = \
+_("%s define duplicated! Each UserExtensions section header must have a "
+ "unique set of UserId, IdString and Arch values. "
+ "It must be corrected before continuing.")
+
+ERR_INF_PARSER_DEFINE_LIB_NAME_INVALID = \
+_("The name 'NULL' for LibraryClass is a reserved word."
+"Please don't use it.")
+
+ERR_GLOBAL_MARCO_INVALID = \
+_("Using global MACRO in INF/DEC is not permitted: %s . "
+"It must be corrected before continuing.")
+
+ERR_MARCO_DEFINITION_MISS_ERROR = \
+_("MACRO expand incorrectly, can not find the MACRO definition. "
+"It must be corrected before continuing.")
+
+#
+# AsBuilt related
+#
+ERR_LIB_CONTATIN_ASBUILD_AND_COMMON = _("A binary INF file should not contain both AsBuilt LIB_INSTANCES information "
+ "and a common library entry.")
+ERR_LIB_INSTANCE_MISS_GUID = _("Could not get FILE_GUID definition from instance INF file.")
+
+ERR_BO_CONTATIN_ASBUILD_AND_COMMON = _("A binary INF file should contain either AsBuilt information "
+ "or a common build option entry, not both.")
+
+ERR_ASBUILD_PCD_SECTION_TYPE = _("The AsBuilt INF file contains a PCD section type that is not permitted: %s.")
+ERR_ASBUILD_PATCHPCD_FORMAT_INVALID = _("The AsBuilt PatchPcd entry must contain 3 elements: PcdName|Value|Offset")
+ERR_ASBUILD_PCDEX_FORMAT_INVALID = _("The AsBuilt PcdEx entry must contain 2 elements: PcdName|Value")
+ERR_ASBUILD_PCD_VALUE_INVALID = \
+ _("The AsBuilt PCD value %s is incorrect or not align with it's datum type %s. "
+ "It must be corrected before continuing.")
+ERR_ASBUILD_PCD_TOKENSPACE_GUID_VALUE_MISS = _("Package file value could not be retrieved for %s.")
+ERR_ASBUILD_PCD_DECLARITION_MISS = _("PCD Declaration in DEC files could not be found for: %s.")
+ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID = _("PCD offset format invalid, number of (0-4294967295) or"
+"Hex number of UINT32 allowed : %s.")
+
+#
+# XML parser related strings
+#
+ERR_XML_PARSER_REQUIRED_ITEM_MISSING = \
+ _("The XML section/attribute '%s' is required under %s, it can't be missing or empty")
+ERR_XML_INVALID_VARIABLENAME = \
+ _("The VariableName of the GUID in the XML tree does not conform to the packaging specification. "
+ "Only a Hex Byte Array of UCS-2 format or L\"string\" is allowed): %s %s %s")
+ERR_XML_INVALID_LIB_SUPMODLIST = _("The LIBRARY_CLASS entry %s must have the list appended using the format as: \n"
+"BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER SMM_CORE DXE_SMM_DRIVER DXE_RUNTIME_DRIVER "
+"DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION USER_DEFINED\n Current is %s.")
+ERR_XML_INVALID_EXTERN_SUPARCHLIST = \
+ _("There is a mismatch of SupArchList %s between the EntryPoint, UnloadImage, Constructor, "
+ "and Destructor elements in the ModuleSurfaceArea.ModuleProperties: SupArchList: %s. ")
+ERR_XML_INVALID_EXTERN_SUPMODLIST = _("The SupModList attribute of the CONSTRUCTOR or DESTRUCTOR element: %s does not "
+"match the Supported Module Types listed after LIBRARY_CLASS = <Keyword> | %s")
+ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB = _("The module is not a library module. "
+ "The MODULE_TYPE : %s listed in the ModuleSurfaceArea.Header "
+ "must match the SupModList attribute %s")
+ERR_XML_INVALID_BINARY_FILE_TYPE = _("Invalid binary file type %s.")
+
+#
+# Verbosity related strings.
+#
+MSG_DISTRIBUTION_PACKAGE_FILE_EXISTS = _(
+ "The distribution package file %s already exists.\nPress Y to override it."
+ " To exit the application, press any other key.")
+MSG_CHECK_MODULE_EXIST = _(
+ "\nChecking to see if module exists in workspace started ...")
+MSG_CHECK_MODULE_EXIST_FINISH = \
+ _("Checking to see if module exists in workspace ... Done.")
+MSG_CHECK_MODULE_DEPEX_START = _(
+ "\nChecking to see if module depex met by workspace started ...")
+MSG_CHECK_MODULE_DEPEX_FINISH = _(
+ "Checking to see if module depex met by workspace ... Done.")
+MSG_CHECK_PACKAGE_START = _(
+ "\nChecking to see if package exists in workspace started ...")
+MSG_CHECK_PACKAGE_FINISH = _(
+ "Checking to see if package exists in workspace ... Done.")
+MSG_CHECK_DP_START = \
+ _("\nChecking to see if DP exists in workspace ... Done.")
+MSG_CHECK_DP_FINISH = _("Check DP exists in workspace ... Done.")
+MSG_MODULE_DEPEND_ON = _("Module %s depends on Package %s")
+MSG_INIT_IPI_START = _("\nInitialize IPI database started ...")
+MSG_INIT_IPI_FINISH = _("Initialize IPI database ... Done.")
+MSG_GET_DP_INSTALL_LIST = _(
+ "\nGetting list of DP install information started ...")
+MSG_GET_DP_INSTALL_INFO_START = _(
+ "\nGetting list of DP install information started ...")
+MSG_GET_DP_INSTALL_INFO_FINISH = _("Getting DP install information ... Done.")
+MSG_UZIP_PARSE_XML = _(
+ "Unzipping and parsing distribution package XML file ... ")
+MSG_INSTALL_PACKAGE = _("Installing package ... %s")
+MSG_INSTALL_MODULE = _("Installing module ... %s")
+MSG_NEW_FILE_NAME_FOR_DIST = _(
+ "Provide new filename for distribution file to be saved:\n")
+MSG_UPDATE_PACKAGE_DATABASE = _("Update Distribution Package Database ...")
+MSG_PYTHON_ON = _("(Python %s on %s) ")
+MSG_SEARCH_FOR_HELP = _(
+ "\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for\n"
+ " help, attach the following call stack trace.)\n")
+MSG_REMOVE_TEMP_FILE_STARTED = _("Removing temp files started ... ")
+MSG_REMOVE_TEMP_FILE_DONE = _("Removing temp files ... Done.")
+MSG_FINISH = _("Successfully Done.")
+MSG_COMPRESS_DISTRIBUTION_PKG = _("Compressing Distribution Package File ...")
+MSG_CONFIRM_REMOVE = _(
+ "Some packages or modules depend on this distribution package.\n"
+ "Do you really want to remove it?")
+MSG_CONFIRM_REMOVE2 = _(
+ "This file has been modified: %s. Do you want to remove it?"
+ "Press Y to remove or other key to keep it")
+MSG_CONFIRM_REMOVE3 = _(
+ "This is a newly created file: %s. Are you sure you want to remove it? "
+ "Press Y to remove or any other key to keep it")
+MSG_USER_DELETE_OP = _(
+ "Press Y to delete all files or press any other key to quit:")
+MSG_REMOVE_FILE = _("Removing file: %s ...")
+
+MSG_INITIALIZE_ECC_STARTED = _("\nInitialize ECC database started ...")
+MSG_INITIALIZE_ECC_DONE = _("Initialize ECC database ... Done.")
+MSG_DEFINE_STATEMENT_FOUND = _("DEFINE statement '%s' found in section %s")
+MSG_PARSING = _("Parsing %s ...")
+
+MSG_REPKG_CONFLICT = \
+_("Repackaging is not allowed on this file: %s. "
+ "It was installed from distribution %s(Guid %s Version %s).")
+
+MSG_INVALID_MODULE_INTRODUCED = _("Some modules are not valid after removal.")
+MSG_CHECK_LOG_FILE = _("Please check log file %s for full list")
+MSG_NEW_FILE_NAME = _(
+ "Provide new filename:\n")
+MSG_RELATIVE_PATH_ONLY = _("Please specify a relative path, full path is not allowed: %s")
+MSG_NEW_PKG_PATH = _(
+ "Select package location. To quit with no input, press [Enter].")
+
+#
+# Error related strings.
+#
+
+ERR_DEPENDENCY_NOT_MATCH = _(
+ "Module %s's dependency on package %s (GUID %s Version %s) "
+ "cannot be satisfied")
+ERR_MODULE_NOT_INSTALLED = _(
+ "This module is not installed in the workspace: %s\n")
+ERR_DIR_ALREADY_EXIST = _(
+ "This directory already exists: %s.\n"
+ "Select another location. Press [Enter] with no input to quit:")
+ERR_USER_INTERRUPT = _("The user has paused the application")
+ERR_DIST_FILE_TOOMANY = _(
+ "Only one .content and one .pkg file in ZIP file are allowed.")
+ERR_DIST_FILE_TOOFEW = _(
+ "Must have one .content and one .pkg file in the ZIP file.")
+ERR_FILE_ALREADY_EXIST = _(
+ "This file already exists: %s.\n"
+ "Select another path to continue. To quit with no input press [Enter]:")
+ERR_SPECIFY_PACKAGE = _(
+ "One distribution package must be specified")
+ERR_FILE_BROKEN = _(
+ "This file is invalid in the distribution package: %s")
+ERR_PACKAGE_NOT_MATCH_DEPENDENCY = _(
+ "This distribution package does not meet the dependency requirements")
+ERR_UNKNOWN_FATAL_INSTALL_ERR = \
+_("Unknown unrecoverable error when installing: %s")
+ERR_OPTION_NOT_FOUND = _("Options not found")
+ERR_INVALID_PACKAGE_NAME = _("Incorrect package name: %s. ")
+ERR_INVALID_PACKAGE_PATH = \
+_("Incorrect package path: %s. The path must be a relative path.")
+ERR_NOT_FOUND = _("This was not found: %s")
+ERR_INVALID_MODULE_NAME = _("This is not a valid module name: %s")
+ERR_INVALID_METAFILE_PATH = _('This file must be in sub-directory of WORKSPACE: %s.')
+ERR_INVALID_MODULE_PATH = \
+_("Incorrect module path: %s. The path must be a relative path.")
+ERR_UNKNOWN_FATAL_CREATING_ERR = _("Unknown error when creating: %s")
+ERR_PACKAGE_NOT_INSTALLED = _(
+ "This distribution package not installed: %s")
+ERR_DISTRIBUTION_NOT_INSTALLED = _(
+ "The distribution package is not installed.")
+ERR_UNKNOWN_FATAL_REMOVING_ERR = _("Unknown error when removing package")
+ERR_NOT_CONFIGURE_WORKSPACE_ENV = _(
+ "The WORKSPACE environment variable must be configured.")
+ERR_NO_TEMPLATE_FILE = _("This package information data file is not found: %s")
+ERR_DEBUG_LEVEL = _(
+ "Not supported debug level. Use default level instead.")
+ERR_REQUIRE_T_OPTION = _(
+ "Option -t is required during distribution creation.")
+ERR_REQUIRE_I_C_R_OPTION = _(
+ "Options -i, -c and -r are mutually exclusive.")
+ERR_I_C_EXCLUSIVE = \
+_("Option -c and -i are mutually exclusive.")
+ERR_I_R_EXCLUSIVE = \
+_("Option -i and -r are mutually exclusive.")
+ERR_C_R_EXCLUSIVE = \
+_("Option -c and -r are mutually exclusive.")
+
+ERR_FAILED_LOAD = _("Failed to load %s\n\t%s")
+ERR_PLACEHOLDER_DIFFERENT_REPEAT = _(
+ "${%s} has different repeat time from others.")
+ERR_KEY_NOTALLOWED = _("This keyword is not allowed: %s")
+ERR_NOT_FOUND_ENVIRONMENT = _("Environment variable not found")
+ERR_WORKSPACE_NOTEXIST = _("WORKSPACE doesn't exist")
+ERR_SPACE_NOTALLOWED = _(
+ "Whitespace characters are not allowed in the WORKSPACE path. ")
+ERR_MACRONAME_NOGIVEN = _("No MACRO name given")
+ERR_MACROVALUE_NOGIVEN = _("No MACRO value given")
+ERR_MACRONAME_INVALID = _("Incorrect MACRO name: %s")
+ERR_MACROVALUE_INVALID = _("Incorrect MACRO value: %s")
+ERR_NAME_ONLY_DEFINE = _(
+ "This variable can only be defined via environment variable: %s")
+ERR_EDK_GLOBAL_SAMENAME = _(
+ "EDK_GLOBAL defined a macro with the same name as one defined by 'DEFINE'")
+ERR_SECTIONNAME_INVALID = _(
+ "An incorrect section name was found: %s. 'The correct file is '%s' .")
+ERR_CHECKFILE_NOTFOUND = _(
+ "Can't find file '%s' defined in section '%s'")
+ERR_INVALID_NOTFOUND = _(
+ "Incorrect statement '%s' was found in section '%s'")
+ERR_TEMPLATE_NOTFOUND = _("This package information data file is not found: %s")
+ERR_SECTION_NAME_INVALID = _('Incorrect section name: %s')
+ERR_SECTION_REDEFINE = _(
+ "This section already defined: %s.")
+ERR_SECTION_NAME_NONE = \
+ _('The section needs to be specified first.')
+ERR_KEYWORD_INVALID = _('Invalid keyword: %s')
+ERR_VALUE_INVALID = _("Invalid \"%s\" value in section [%s].")
+ERR_FILELIST_LOCATION = _(
+ 'The directory "%s" must contain this file: "%s".')
+ERR_KEYWORD_REDEFINE = _(
+ "Keyword in this section can only be used once: %s.")
+ERR_FILELIST_EXIST = _(
+ 'This file does not exist: %s.')
+ERR_COPYRIGHT_CONTENT = _(
+ "The copyright content must contain the word \"Copyright\" (case insensitive).")
+ERR_WRONG_FILELIST_FORMAT = \
+_('File list format is incorrect.'
+ 'The correct format is: filename|key=value[|key=value]')
+ERR_FILELIST_ATTR = _(
+ "The value of attribute \"%s\" includes illegal character.")
+ERR_UNKNOWN_FILELIST_ATTR = _(
+ 'Unknown attribute name: %s.')
+ERR_EMPTY_VALUE = _("Empty value is not allowed")
+ERR_KEYWORD_MANDATORY = _('This keyword is mandatory: %s')
+ERR_BOOLEAN_VALUE = _(
+ 'Value of key [%s] must be true or false, current: [%s]')
+ERR_GUID_VALUE = _(
+ 'GUID must have the format of 8-4-4-4-12 with HEX value. '
+ 'Current value: [%s]')
+ERR_VERSION_VALUE = _(
+ 'The value of key [%s] must be a decimal number. Found: [%s]')
+ERR_VERSION_XMLSPEC = _(
+ 'XmlSpecification value must be 1.1, current: %s.')
+
+ERR_INVALID_GUID = _("Incorrect GUID value string: %s")
+
+ERR_FILE_NOT_FOUND = \
+ _("File or directory not found in workspace")
+ERR_FILE_OPEN_FAILURE = _("Could not open file")
+ERR_FILE_WRITE_FAILURE = _("Could not write file.")
+ERR_FILE_PARSE_FAILURE = _("Could not parse file")
+ERR_FILE_READ_FAILURE = _("Could not read file")
+ERR_FILE_CREATE_FAILURE = _("Could not create file")
+ERR_FILE_CHECKSUM_FAILURE = _("Checksum of file is incorrect")
+ERR_FILE_COMPRESS_FAILURE = _("File compression did not correctly")
+ERR_FILE_DECOMPRESS_FAILURE = \
+ _("File decompression did not complete correctly")
+ERR_FILE_MOVE_FAILURE = _("Move file did not complete successfully")
+ERR_FILE_DELETE_FAILURE = _("File could not be deleted")
+ERR_FILE_COPY_FAILURE = _("File did not copy correctly")
+ERR_FILE_POSITIONING_FAILURE = _("Could not find file seek position")
+ERR_FILE_TYPE_MISMATCH = _("Incorrect file type")
+ERR_FILE_CASE_MISMATCH = _("File name case mismatch")
+ERR_FILE_DUPLICATED = _("Duplicate file found")
+ERR_FILE_UNKNOWN_ERROR = _("Unknown error encountered on file")
+ERR_FILE_NAME_INVALIDE = _("This file name is invalid, it must not be an absolute path or "
+ "contain a period \".\" or \"..\": %s.")
+ERR_OPTION_UNKNOWN = _("Unknown option")
+ERR_OPTION_MISSING = _("Missing option")
+ERR_OPTION_CONFLICT = _("Options conflict")
+ERR_OPTION_VALUE_INVALID = _("Invalid option value")
+ERR_OPTION_DEPRECATED = _("Deprecated option")
+ERR_OPTION_NOT_SUPPORTED = _("Unsupported option")
+ERR_OPTION_UNKNOWN_ERROR = _("Unknown error when processing options")
+ERR_PARAMETER_INVALID = _("Invalid parameter")
+ERR_PARAMETER_MISSING = _("Missing parameter")
+ERR_PARAMETER_UNKNOWN_ERROR = _("Unknown error in parameters")
+ERR_FORMAT_INVALID = _("Invalid syntax/format")
+ERR_FORMAT_NOT_SUPPORTED = _("Syntax/format not supported")
+ERR_FORMAT_UNKNOWN = _("Unknown format")
+ERR_FORMAT_UNKNOWN_ERROR = _("Unknown error in syntax/format ")
+ERR_RESOURCE_NOT_AVAILABLE = _("Not available")
+ERR_RESOURCE_ALLOCATE_FAILURE = _("A resource allocation has failed")
+ERR_RESOURCE_FULL = _("Full")
+ERR_RESOURCE_OVERFLOW = _("Overflow")
+ERR_RESOURCE_UNDERRUN = _("Underrun")
+ERR_RESOURCE_UNKNOWN_ERROR = _("Unknown error")
+ERR_ATTRIBUTE_NOT_AVAILABLE = _("Not available")
+ERR_ATTRIBUTE_RETRIEVE_FAILURE = _("Unable to retrieve")
+ERR_ATTRIBUTE_SET_FAILURE = _("Unable to set")
+ERR_ATTRIBUTE_UPDATE_FAILURE = _("Unable to update")
+ERR_ATTRIBUTE_ACCESS_DENIED = _("Access denied")
+ERR_ATTRIBUTE_UNKNOWN_ERROR = _("Unknown error when accessing")
+ERR_COMMAND_FAILURE = _("Unable to execute command")
+ERR_IO_NOT_READY = _("Not ready")
+ERR_IO_BUSY = _("Busy")
+ERR_IO_TIMEOUT = _("Timeout")
+ERR_IO_UNKNOWN_ERROR = _("Unknown error in IO operation")
+ERR_UNKNOWN_ERROR = _("Unknown error")
+ERR_UPT_ALREADY_INSTALLED_ERROR = _("Already installed")
+ERR_UPT_ENVIRON_MISSING_ERROR = _("Environ missing")
+ERR_UPT_REPKG_ERROR = _("File not allowed for RePackage")
+ERR_UPT_INI_PARSE_ERROR = _("INI file parse error")
+ERR_COPYRIGHT_MISSING = \
+_("Header comment section must have copyright information")
+ERR_LICENSE_MISSING = \
+_("Header comment section must have license information")
+ERR_INVALID_COMMENT_FORMAT = _("Comment must start with #")
+ERR_USER_ABORT = _("User has stopped the application")
+ERR_DIST_EXT_ERROR = \
+_("Distribution file extension should be '.dist'. Current given: '%s'.")
+ERR_DIST_FILENAME_ONLY_FOR_REMOVE = \
+_("Only distribution filename without path allowed during remove. Current given: '%s'.")
+ERR_NOT_STANDALONE_MODULE_ERROR = \
+ _("Module %s is not a standalone module (found in Package %s)")
+ERR_UPT_ALREADY_RUNNING_ERROR = \
+ _("UPT is already running, only one instance is allowed")
+ERR_MUL_DEC_ERROR = _("Multiple DEC files found within one package directory tree %s: %s, %s")
+ERR_INSTALL_FILE_FROM_EMPTY_CONTENT = _("Error file to be installed is not found in content file: %s")
+ERR_INSTALL_FILE_DEC_FILE_ERROR = _("Could not obtain the TokenSpaceGuidCName and the PcdCName from the DEC files "
+"that the package depends on for this pcd entry: TokenValue: %s Token: %s")
+ERR_NOT_SUPPORTED_SA_MODULE = _("Stand-alone module distribution does not allow EDK 1 INF")
+ERR_INSTALL_DIST_NOT_FOUND = \
+_("Distribution file to be installed is not found in current working directory or workspace: %s")
+
+#
+# Expression error message
+#
+ERR_EXPR_RIGHT_PAREN = \
+_('Expected ")" in feature flag expression [%s]. Found: [%s].')
+ERR_EXPR_FACTOR = \
+_('Expected HEX, integer, macro, quoted string or PcdName in '
+ 'feature flag expression [%s]. Found: [%s].')
+ERR_EXPR_STRING_ITEM = \
+_('Expected quoted string, macro name or PcdName in feature flag '
+ 'expression [%s]. Found: [%s].')
+ERR_EXPR_EQUALITY = \
+_('Expected ==, EQ, != or NE in feature flag expression [%s]. Found: [%s].')
+ERR_EXPR_BOOLEAN = \
+_('The rest of string [%s] in feature flag '
+ 'expression [%s] cannot be evaluated.')
+ERR_EXPR_EMPTY = _('Boolean value cannot be empty.')
+ERR_EXPR_LOGICAL = \
+_('The following cannot be evaluated as a logical expression: [%s].')
+ERR_EXPR_OR = _('The expression must be encapsulated in open "(" and close ")" '
+ 'parenthesis when using | or ||.')
+
+#
+# DEC parser error message
+#
+ERR_DECPARSE_STATEMENT_EMPTY = \
+_('Must have at least one statement in section %s.')
+ERR_DECPARSE_DEFINE_DEFINED = \
+_('%s already defined in define section.')
+ERR_DECPARSE_DEFINE_SECNAME = \
+_('No arch and others can be followed for define section.')
+ERR_DECPARSE_DEFINE_MULTISEC = \
+_('The DEC file does not allow multiple define sections.')
+ERR_DECPARSE_DEFINE_REQUIRED = \
+_("Field [%s] is required in define section.")
+ERR_DECPARSE_DEFINE_FORMAT = \
+_("Wrong define section format, must be KEY = Value.")
+ERR_DECPARSE_DEFINE_UNKNOWKEY = \
+_("Unknown key [%s] in define section.")
+ERR_DECPARSE_DEFINE_SPEC = \
+_("Specification value must be HEX numbers.")
+ERR_DECPARSE_DEFINE_PKGNAME = \
+_("Package name must be AlphaNumeric characters.")
+ERR_DECPARSE_DEFINE_PKGGUID = \
+_("GUID format error, must be HEX value with form 8-4-4-4-12.")
+ERR_DECPARSE_DEFINE_PKGVERSION = \
+_("Version number must be decimal number.")
+ERR_DECPARSE_DEFINE_PKGVUNI = \
+_("UNI file name format error or file does not exist.")
+ERR_DECPARSE_INCLUDE = \
+_("Incorrect path: [%s].")
+ERR_DECPARSE_LIBCLASS_SPLIT = \
+_("Library class format error, must be Libraryclass|Headerpath.")
+ERR_DECPARSE_LIBCLASS_EMPTY = \
+_("Class name or file name must not be empty.")
+ERR_DECPARSE_LIBCLASS_LIB = \
+_("Class name format error, must start with upper case letter followed with "
+ "zero or more alphanumeric characters.")
+ERR_DECPARSE_LIBCLASS_PATH_EXT = _("File name must be end with .h.")
+ERR_DECPARSE_LIBCLASS_PATH_DOT = _("Path must not include '..'.")
+ERR_DECPARSE_LIBCLASS_PATH_EXIST = _("File name [%s] does not exist.")
+ERR_DECPARSE_PCD_CVAR_GUID = \
+_("TokenSpaceGuidCName must be valid C variable format.")
+ERR_DECPARSE_PCD_SPLIT = \
+_("Incorrect PcdName. The format must be TokenSpaceGuidCName.PcdCName"
+ "|PcdData|PcdType|Token.")
+ERR_DECPARSE_PCD_NAME = \
+_("Incorrect PCD name. The correct format must be "
+ "<TokenSpaceGuidCName>.<PcdCName>.")
+ERR_DECPARSE_PCD_CVAR_PCDCNAME = \
+_("PcdCName must be valid C variable format.")
+ERR_DECPARSE_PCD_TYPE = \
+_('Incorrect PCD data type. A PCD data type must be one of '
+ '"UINT8", "UINT16", "UINT32", "UINT64", "VOID*", "BOOLEAN".')
+ERR_DECPARSE_PCD_VOID = \
+_("Incorrect value [%s] of type [%s]. Value must be printable and in the "
+ "form of{...} for array, or ""..."" for string, or L""..."""
+ "for unicode string.")
+ERR_DECPARSE_PCD_BOOL = \
+_("Invalid value [%s] of type [%s]; must be expression, TRUE, FALSE, 0 or 1.")
+ERR_DECPARSE_PCD_INT = _("Incorrect value [%s] of type [%s]."\
+" Value must be a hexadecimal, decimal or octal in C language format.")
+ERR_DECPARSE_PCD_INT_NEGTIVE = _("Incorrect value [%s] of type [%s];"
+ " must not be signed number.")
+ERR_DECPARSE_PCD_INT_EXCEED = _("Incorrect value [%s] of type [%s]; "
+ "the number is too long for this type.")
+ERR_DECPARSE_PCD_FEATUREFLAG = \
+_("PcdFeatureFlag only allow BOOLEAN type.")
+ERR_DECPARSE_PCD_TOKEN = \
+_("An incorrect PCD token found: [%s]. "
+ "It must start with 0x followed by 1 - 8 hexadecimal. ")
+ERR_DECPARSE_PCD_TOKEN_INT = _("Incorrect token number [%s]. "
+ "This token number exceeds the maximal value of unsigned 32.")
+ERR_DECPARSE_PCD_TOKEN_UNIQUE = _("Token number must be unique to the token space: %s.")
+ERR_DECPARSE_CGUID = \
+_("No GUID name or value specified, must be <CName> = <GuidValueInCFormat>.")
+ERR_DECPARSE_CGUID_NAME = \
+_("No GUID name specified, must be <CName> = <GuidValueInCFormat>.")
+ERR_DECPARSE_CGUID_GUID = \
+_("No GUID value specified, must be <CName> = <GuidValueInCFormat>.")
+ERR_DECPARSE_CGUID_GUIDFORMAT = \
+_("Incorrect GUID value format, must be <GuidValueInCFormat:"
+ "{8,4,4,{2,2,2,2,2,2,2,2}}>.")
+ERR_DECPARSE_FILEOPEN = _("Unable to open: [%s].")
+ERR_DECPARSE_SECTION_EMPTY = _("Empty sections are not allowed.")
+ERR_DECPARSE_SECTION_UE = _("Incorrect UserExtentions format. "
+ "Must be UserExtenxions.UserId.IdString[.Arch]+.")
+ERR_DECPARSE_SECTION_UE_USERID = _("Invalid UserId, must be underscore"
+ "or alphanumeric characters.")
+ERR_DECPARSE_SECTION_UE_IDSTRING = \
+ _("Incorrect IdString, must be \" ... \".")
+ERR_DECPARSE_ARCH = \
+_("Unknown arch, must be 'common' or start with upper case letter followed by"
+ " zero or more upper case letters and numbers.")
+ERR_DECPARSE_SECTION_COMMA = _("Section cannot end with comma.")
+ERR_DECPARSE_SECTION_COMMON = \
+_("'COMMON' must not be used with specific ARCHs in the same section.")
+ERR_DECPARSE_SECTION_IDENTIFY = \
+_("Section header must start with and end with brackets[].")
+ERR_DECPARSE_SECTION_SUBEMPTY = \
+_("Missing a sub-section name in section: [%s]. "
+ "All sub-sections need to have names. ")
+ERR_DECPARSE_SECTION_SUBTOOMANY = _("Too many DOT splits in [%s].")
+ERR_DECPARSE_SECTION_UNKNOW = _("Section name [%s] unknown.")
+ERR_DECPARSE_SECTION_FEATUREFLAG = \
+_("[%s] must not be in the same section as other types of PCD.")
+ERR_DECPARSE_MACRO_PAIR = _("No macro name/value given.")
+ERR_DECPARSE_MACRO_NAME = _("No macro name given.")
+ERR_DECPARSE_MACRO_NAME_UPPER = \
+_("Macro name must start with upper case letter followed "
+"by zero or more upper case letters or numbers. Current macro name is: [%s].")
+ERR_DECPARSE_SECTION_NAME = \
+_('Cannot mix different section names %s.')
+ERR_DECPARSE_BACKSLASH = \
+_('Backslash must be the last character on a line and '
+ 'preceded by a space character.')
+ERR_DECPARSE_BACKSLASH_EMPTY = \
+_('Empty line after previous line that has backslash is not allowed.')
+ERR_DECPARSE_REDEFINE = _(
+ "\"%s\" already defined in line %d.")
+ERR_DECPARSE_MACRO_RESOLVE = _("Macro %s in %s cannot be resolved.")
+ERR_DECPARSE_UE_DUPLICATE = \
+ _("Duplicated UserExtensions header found.")
+
+#
+# Used to print the current line content which cause error raise.
+# Be attached to the end of every error message above.
+#
+ERR_DECPARSE_LINE = _(" Parsing line: \"%s\".")
+
+#
+# Warning related strings.
+#
+WRN_PACKAGE_EXISTED = _(
+ "A package with this GUID and Version already exists: "
+ "GUID %s, Version %s.")
+WRN_MODULE_EXISTED = _("This module already exists: %s")
+WRN_FILE_EXISTED = _("This file already exists: %s")
+WRN_FILE_NOT_OVERWRITTEN = \
+_("This file already exist and cannot be overwritten: %s")
+WRN_DIST_PKG_INSTALLED = _("This distribution package has been installed")
+WRN_DIST_NOT_FOUND = _(
+ "Distribution is not found at location %s")
+WRN_MULTI_PCD_RANGES = _(
+ "A PCD can only have one each of @ValidRange, @ValidList, "
+ "and @Expression comment")
+WRN_MISSING_USAGE = _("Missing usage")
+WRN_INVALID_GUID_TYPE = _("This is and incorrect Guid type: %s")
+WRN_MISSING_GUID_TYPE = _("Missing Guid Type")
+WRN_INVALID_USAGE = _("This is an incorrect Usage: %s")
+WRN_INF_PARSER_MODULE_INVALID_HOB_TYPE = \
+ _("This is an incorrect HOB type: %s")
+WRN_INF_PARSER_MODULE_INVALID_EVENT_TYPE = \
+ _("This is an incorrect EVENT type: %s")
+WRN_INF_PARSER_MODULE_INVALID_BOOTMODE_TYPE = \
+ _("This is an incorrect BOOTMODE type: %s")
+WRN_INVALID_MODULE_TYPE = \
+ _("This is an incorrect Module type: %s")
+WRN_MODULE_PARSE_FAILED = \
+ _("Parsing of this module did not complete correctly: %s.")
+WRN_EDK1_INF_FOUND = \
+ _("EDK 1 module file found: %s")
+WRN_INVALID_COPYRIGHT = \
+ _("Copyright information is not right")
+WARN_SPECIAL_SECTION_LOCATION_WRONG = _("Warning. A special section should be "
+ "at the end of a file or at the end of a section.")
+WARN_INSTALLED_PACKAGE_NOT_FOUND = \
+ _("File not found. The DEC file for a package cannot be found in GUID/Version/Install path: %s %s %s")
+
+#
+# Help related strings.
+#
+HLP_PRINT_DEBUG_INFO = _(
+ "Print DEBUG statements, where DEBUG_LEVEL is 0-9")
+HLP_PRINT_INFORMATIONAL_STATEMENT = _("Print informational statements")
+HLP_RETURN_NO_DISPLAY = _(
+ "Returns only the exit code, informational and error messages are"
+ " not displayed")
+HLP_RETURN_AND_DISPLAY = _(
+ "Returns the exit code and displays error messages only")
+HLP_SPECIFY_PACKAGE_NAME_INSTALL = _(
+ "Specify the UEFI Distribution Package filename to install")
+HLP_SPECIFY_PACKAGE_NAME_CREATE = _(
+ "Specify the UEFI Distribution Package filename to create")
+HLP_SPECIFY_PACKAGE_NAME_REMOVE = _(
+ "Specify the UEFI Distribution Package filename to remove")
+HLP_SPECIFY_TEMPLATE_NAME_CREATE = _(
+ "Specify Package Information Data filename to create package")
+HLP_SPECIFY_DEC_NAME_CREATE = _(
+ "Specify dec file names to create package")
+HLP_SPECIFY_INF_NAME_CREATE = _(
+ "Specify inf file names to create package")
+HLP_NO_SUPPORT_GUI = _(
+ "Starting the tool in graphical mode is not supported in this version")
+HLP_DISABLE_PROMPT = _(
+ "Disable all user prompts")
+HLP_CUSTOM_PATH_PROMPT = _(
+ "Enable user prompting for alternate installation directories")
+HLP_SKIP_LOCK_CHECK = _(
+ "Skip the check for multiple instances")
diff --git a/BaseTools/Source/Python/UPT/Logger/ToolError.py b/BaseTools/Source/Python/UPT/Logger/ToolError.py
new file mode 100644
index 0000000000..69600b2c01
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Logger/ToolError.py
@@ -0,0 +1,176 @@
+## @file
+# Standardized Error Hanlding infrastructures.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+ToolError
+'''
+
+import Logger.StringTable as ST
+
+FILE_OPEN_FAILURE = 1
+FILE_WRITE_FAILURE = 2
+FILE_PARSE_FAILURE = 3
+FILE_READ_FAILURE = 4
+FILE_CREATE_FAILURE = 5
+FILE_CHECKSUM_FAILURE = 6
+FILE_COMPRESS_FAILURE = 7
+FILE_DECOMPRESS_FAILURE = 8
+FILE_MOVE_FAILURE = 9
+FILE_DELETE_FAILURE = 10
+FILE_COPY_FAILURE = 11
+FILE_POSITIONING_FAILURE = 12
+FILE_ALREADY_EXIST = 13
+FILE_NOT_FOUND = 14
+FILE_TYPE_MISMATCH = 15
+FILE_CASE_MISMATCH = 16
+FILE_DUPLICATED = 17
+FILE_UNKNOWN_ERROR = 0x0FFF
+
+OPTION_UNKNOWN = 0x1000
+OPTION_MISSING = 0x1001
+OPTION_CONFLICT = 0x1002
+OPTION_VALUE_INVALID = 0x1003
+OPTION_DEPRECATED = 0x1004
+OPTION_NOT_SUPPORTED = 0x1005
+OPTION_UNKNOWN_ERROR = 0x1FFF
+
+PARAMETER_INVALID = 0x2000
+PARAMETER_MISSING = 0x2001
+PARAMETER_UNKNOWN_ERROR = 0x2FFF
+
+FORMAT_INVALID = 0x3000
+FORMAT_NOT_SUPPORTED = 0x3001
+FORMAT_UNKNOWN = 0x3002
+FORMAT_UNKNOWN_ERROR = 0x3FFF
+
+RESOURCE_NOT_AVAILABLE = 0x4000
+RESOURCE_ALLOCATE_FAILURE = 0x4001
+RESOURCE_FULL = 0x4002
+RESOURCE_OVERFLOW = 0x4003
+RESOURCE_UNDERRUN = 0x4004
+RESOURCE_UNKNOWN_ERROR = 0x4FFF
+
+ATTRIBUTE_NOT_AVAILABLE = 0x5000
+ATTRIBUTE_GET_FAILURE = 0x5001
+ATTRIBUTE_SET_FAILURE = 0x5002
+ATTRIBUTE_UPDATE_FAILURE = 0x5003
+ATTRIBUTE_ACCESS_DENIED = 0x5004
+ATTRIBUTE_RETRIEVE_FAILURE = 0x5005
+ATTRIBUTE_UNKNOWN_ERROR = 0x5FFF
+ATTRIBUTE_RETRIEVE_FAILURE = 0x5F00
+
+IO_NOT_READY = 0x6000
+IO_BUSY = 0x6001
+IO_TIMEOUT = 0x6002
+IO_UNKNOWN_ERROR = 0x6FFF
+
+COMMAND_FAILURE = 0x7000
+
+CODE_ERROR = 0xC0DE
+
+AUTOGEN_ERROR = 0xF000
+PARSER_ERROR = 0xF001
+BUILD_ERROR = 0xF002
+GENFDS_ERROR = 0xF003
+ECC_ERROR = 0xF004
+EOT_ERROR = 0xF005
+DDC_ERROR = 0xF009
+WARNING_AS_ERROR = 0xF006
+MIGRATION_ERROR = 0xF010
+EDK1_INF_ERROR = 0xF011
+ABORT_ERROR = 0xFFFE
+UNKNOWN_ERROR = 0xFFFF
+
+UPT_ALREADY_INSTALLED_ERROR = 0xD000
+UPT_ENVIRON_MISSING_ERROR = 0xD001
+UPT_REPKG_ERROR = 0xD002
+UPT_ALREADY_RUNNING_ERROR = 0xD003
+UPT_MUL_DEC_ERROR = 0xD004
+UPT_INI_PARSE_ERROR = 0xE000
+
+## Error message of each error code
+#
+gERROR_MESSAGE = {
+ FILE_NOT_FOUND : ST.ERR_FILE_NOT_FOUND,
+ FILE_OPEN_FAILURE : ST.ERR_FILE_OPEN_FAILURE,
+ FILE_WRITE_FAILURE : ST.ERR_FILE_WRITE_FAILURE,
+ FILE_PARSE_FAILURE : ST.ERR_FILE_PARSE_FAILURE,
+ FILE_READ_FAILURE : ST.ERR_FILE_READ_FAILURE,
+ FILE_CREATE_FAILURE : ST.ERR_FILE_CREATE_FAILURE,
+ FILE_CHECKSUM_FAILURE : ST.ERR_FILE_CHECKSUM_FAILURE,
+ FILE_COMPRESS_FAILURE : ST.ERR_FILE_COMPRESS_FAILURE,
+ FILE_DECOMPRESS_FAILURE : ST.ERR_FILE_DECOMPRESS_FAILURE,
+ FILE_MOVE_FAILURE : ST.ERR_FILE_MOVE_FAILURE,
+ FILE_DELETE_FAILURE : ST.ERR_FILE_DELETE_FAILURE,
+ FILE_COPY_FAILURE : ST.ERR_FILE_COPY_FAILURE,
+ FILE_POSITIONING_FAILURE: ST.ERR_FILE_POSITIONING_FAILURE,
+ FILE_ALREADY_EXIST : ST.ERR_FILE_ALREADY_EXIST,
+ FILE_TYPE_MISMATCH : ST.ERR_FILE_TYPE_MISMATCH ,
+ FILE_CASE_MISMATCH : ST.ERR_FILE_CASE_MISMATCH,
+ FILE_DUPLICATED : ST.ERR_FILE_DUPLICATED,
+ FILE_UNKNOWN_ERROR : ST.ERR_FILE_UNKNOWN_ERROR,
+
+ OPTION_UNKNOWN : ST.ERR_OPTION_UNKNOWN,
+ OPTION_MISSING : ST.ERR_OPTION_MISSING,
+ OPTION_CONFLICT : ST.ERR_OPTION_CONFLICT,
+ OPTION_VALUE_INVALID : ST.ERR_OPTION_VALUE_INVALID,
+ OPTION_DEPRECATED : ST.ERR_OPTION_DEPRECATED,
+ OPTION_NOT_SUPPORTED : ST.ERR_OPTION_NOT_SUPPORTED,
+ OPTION_UNKNOWN_ERROR : ST.ERR_OPTION_UNKNOWN_ERROR,
+
+ PARAMETER_INVALID : ST.ERR_PARAMETER_INVALID,
+ PARAMETER_MISSING : ST.ERR_PARAMETER_MISSING,
+ PARAMETER_UNKNOWN_ERROR : ST.ERR_PARAMETER_UNKNOWN_ERROR,
+
+ FORMAT_INVALID : ST.ERR_FORMAT_INVALID,
+ FORMAT_NOT_SUPPORTED : ST.ERR_FORMAT_NOT_SUPPORTED,
+ FORMAT_UNKNOWN : ST.ERR_FORMAT_UNKNOWN,
+ FORMAT_UNKNOWN_ERROR : ST.ERR_FORMAT_UNKNOWN_ERROR,
+
+ RESOURCE_NOT_AVAILABLE : ST.ERR_RESOURCE_NOT_AVAILABLE,
+ RESOURCE_ALLOCATE_FAILURE : ST.ERR_RESOURCE_ALLOCATE_FAILURE,
+ RESOURCE_FULL : ST.ERR_RESOURCE_FULL,
+ RESOURCE_OVERFLOW : ST.ERR_RESOURCE_OVERFLOW,
+ RESOURCE_UNDERRUN : ST.ERR_RESOURCE_UNDERRUN,
+ RESOURCE_UNKNOWN_ERROR : ST.ERR_RESOURCE_UNKNOWN_ERROR,
+
+ ATTRIBUTE_NOT_AVAILABLE : ST.ERR_ATTRIBUTE_NOT_AVAILABLE,
+ ATTRIBUTE_RETRIEVE_FAILURE : ST.ERR_ATTRIBUTE_RETRIEVE_FAILURE,
+ ATTRIBUTE_SET_FAILURE : ST.ERR_ATTRIBUTE_SET_FAILURE,
+ ATTRIBUTE_UPDATE_FAILURE: ST.ERR_ATTRIBUTE_UPDATE_FAILURE,
+ ATTRIBUTE_ACCESS_DENIED : ST.ERR_ATTRIBUTE_ACCESS_DENIED,
+ ATTRIBUTE_UNKNOWN_ERROR : ST.ERR_ATTRIBUTE_UNKNOWN_ERROR,
+
+ COMMAND_FAILURE : ST.ERR_COMMAND_FAILURE,
+
+ IO_NOT_READY : ST.ERR_IO_NOT_READY,
+ IO_BUSY : ST.ERR_IO_BUSY,
+ IO_TIMEOUT : ST.ERR_IO_TIMEOUT,
+ IO_UNKNOWN_ERROR : ST.ERR_IO_UNKNOWN_ERROR,
+
+ UNKNOWN_ERROR : ST.ERR_UNKNOWN_ERROR,
+
+ UPT_ALREADY_INSTALLED_ERROR : ST.ERR_UPT_ALREADY_INSTALLED_ERROR,
+ UPT_ENVIRON_MISSING_ERROR : ST.ERR_UPT_ENVIRON_MISSING_ERROR,
+ UPT_REPKG_ERROR : ST.ERR_UPT_REPKG_ERROR,
+ UPT_ALREADY_RUNNING_ERROR : ST.ERR_UPT_ALREADY_RUNNING_ERROR,
+ UPT_MUL_DEC_ERROR : ST.ERR_MUL_DEC_ERROR,
+ UPT_INI_PARSE_ERROR : ST.ERR_UPT_INI_PARSE_ERROR,
+}
+
+## Exception indicating a fatal error
+#
+class FatalError(Exception):
+ pass
+
diff --git a/BaseTools/Source/Python/UPT/Logger/__init__.py b/BaseTools/Source/Python/UPT/Logger/__init__.py
new file mode 100644
index 0000000000..2881ac7711
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Logger/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Logger' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Logger
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Makefile b/BaseTools/Source/Python/UPT/Makefile
new file mode 100644
index 0000000000..a6e3a6dd41
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Makefile
@@ -0,0 +1,41 @@
+## @file
+# Windows makefile for UPT tools build.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+!IFNDEF PYTHON_FREEZER_PATH
+!ERROR PYTHON_FREEZER_PATH must be defined!
+!ENDIF
+
+FREEZE=$(PYTHON_FREEZER_PATH)\FreezePython.exe
+
+MODULES=encodings.cp437,encodings.gbk,encodings.utf_16,encodings.utf_8,encodings.utf_16_le,encodings.latin_1,encodings.ascii
+
+BIN_DIR = .\Bin
+SOURCES_PATH = .
+
+APPLICATIONS=$(BIN_DIR)\UPT.exe
+
+COMMON_PYTHON=$(SOURCES_PATH)\UPT.py
+
+all: SetPythonPath $(APPLICATIONS)
+
+SetPythonPath:
+ set PYTHONPATH= $(SOURCES_PATH)
+
+$(BIN_DIR)\UPT.exe: $(SOURCES_PATH)\UPT.py $(COMMON_PYTHON)
+ @pushd . & @cd build & @$(FREEZE) --include-modules=$(MODULES) --install-dir=$(BIN_DIR) UPT.py & @popd
+ @pushd . & @copy .\Dll\sqlite3.dll .\Bin\Sqlite3.dll & @popd
+clean:
+cleanall:
+ @del /f /q $(BIN_DIR)\*.pyd $(BIN_DIR)\*.dll
+ @for %%i in ($(APPLICATIONS)) do @del /f /q %%i
+
diff --git a/BaseTools/Source/Python/UPT/MkPkg.py b/BaseTools/Source/Python/UPT/MkPkg.py
new file mode 100644
index 0000000000..b8b78e4515
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/MkPkg.py
@@ -0,0 +1,281 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+MkPkg
+'''
+
+##
+# Import Modules
+#
+from os import remove
+from os import getcwd
+from os import chdir
+import os.path
+from sys import stdin
+from sys import platform
+from traceback import format_exc
+from platform import python_version
+import md5
+from time import strftime
+from time import localtime
+from uuid import uuid4
+
+from Logger import StringTable as ST
+from Logger.ToolError import OPTION_UNKNOWN_ERROR
+from Logger.ToolError import OPTION_VALUE_INVALID
+from Logger.ToolError import ABORT_ERROR
+from Logger.ToolError import UPT_REPKG_ERROR
+from Logger.ToolError import CODE_ERROR
+from Logger.ToolError import FatalError
+from Logger.ToolError import FILE_NOT_FOUND
+import Logger.Log as Logger
+
+from Xml.XmlParser import DistributionPackageXml
+from Xml.IniToXml import IniToXml
+
+from Library.Misc import CheckEnvVariable
+from Library import GlobalData
+from Library.ParserValidate import IsValidPath
+
+from Core.DistributionPackageClass import DistributionPackageClass
+from Core.PackageFile import PackageFile
+
+## CheckForExistingDp
+#
+# Check if there is a same name DP file existing
+# @param Path: The path to be checked
+#
+def CheckForExistingDp(Path):
+ if os.path.exists(Path):
+ Logger.Info(ST.MSG_DISTRIBUTION_PACKAGE_FILE_EXISTS % Path)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != "Y":
+ Logger.Error("\nMkPkg", ABORT_ERROR, ST.ERR_USER_ABORT, RaiseError=True)
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+#
+def Main(Options = None):
+ if Options == None:
+ Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND)
+ try:
+ DataBase = GlobalData.gDB
+ ContentFileClosed = True
+ CheckEnvVariable()
+ WorkspaceDir = GlobalData.gWORKSPACE
+
+ #
+ # Init PackFileToCreate
+ #
+ if not Options.PackFileToCreate:
+ Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND)
+
+ #
+ # Handle if the distribution package file already exists
+ #
+ CheckForExistingDp(Options.PackFileToCreate)
+
+ #
+ # Check package file existing and valid
+ #
+ CheckFileList('.DEC', Options.PackageFileList, ST.ERR_INVALID_PACKAGE_NAME, ST.ERR_INVALID_PACKAGE_PATH)
+ #
+ # Check module file existing and valid
+ #
+ CheckFileList('.INF', Options.ModuleFileList, ST.ERR_INVALID_MODULE_NAME, ST.ERR_INVALID_MODULE_PATH)
+
+ #
+ # Get list of files that installed with RePackage attribute available
+ #
+ RePkgDict = DataBase.GetRePkgDict()
+
+ ContentFile = PackageFile(GlobalData.gCONTENT_FILE, "w")
+ ContentFileClosed = False
+
+ #
+ # Add temp distribution header
+ #
+ if Options.PackageInformationDataFile:
+ XmlFile = IniToXml(Options.PackageInformationDataFile)
+ DistPkg = DistributionPackageXml().FromXml(XmlFile)
+ remove(XmlFile)
+
+ #
+ # add distribution level tool/misc files
+ # before pack, current dir should be workspace dir, else the full
+ # path will be in the pack file
+ #
+ Cwd = getcwd()
+ chdir(WorkspaceDir)
+ ToolObject = DistPkg.Tools
+ MiscObject = DistPkg.MiscellaneousFiles
+ FileList = []
+ if ToolObject:
+ FileList += ToolObject.GetFileList()
+ if MiscObject:
+ FileList += MiscObject.GetFileList()
+ for FileObject in FileList:
+ #
+ # If you have unicode file names, please convert them to byte
+ # strings in your desired encoding before passing them to
+ # write().
+ #
+ FromFile = os.path.normpath(FileObject.GetURI()).encode('utf_8')
+ FileFullPath = os.path.normpath(os.path.join(WorkspaceDir, FromFile))
+ if FileFullPath in RePkgDict:
+ (DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath]
+ if not Repackage:
+ Logger.Error("\nMkPkg",
+ UPT_REPKG_ERROR,
+ ST.ERR_UPT_REPKG_ERROR,
+ ExtraData=ST.MSG_REPKG_CONFLICT %\
+ (FileFullPath, DpGuid, DpVersion, DpName)
+ )
+ else:
+ DistPkg.Header.RePackage = True
+ ContentFile.PackFile(FromFile)
+ chdir(Cwd)
+
+ #
+ # Add init dp information
+ #
+ else:
+ DistPkg = DistributionPackageClass()
+ DistPkg.Header.Name = 'Distribution Package'
+ DistPkg.Header.Guid = str(uuid4())
+ DistPkg.Header.Version = '1.0'
+
+ DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, \
+ Options.ModuleFileList)
+ FileList, MetaDataFileList = DistPkg.GetDistributionFileList()
+ for File in FileList + MetaDataFileList:
+ FileFullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
+ #
+ # check whether file was included in a distribution that can not
+ # be repackaged
+ #
+ if FileFullPath in RePkgDict:
+ (DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath]
+ if not Repackage:
+ Logger.Error("\nMkPkg",
+ UPT_REPKG_ERROR,
+ ST.ERR_UPT_REPKG_ERROR,
+ ExtraData = \
+ ST.MSG_REPKG_CONFLICT %(FileFullPath, DpName, \
+ DpGuid, DpVersion)
+ )
+ else:
+ DistPkg.Header.RePackage = True
+
+ Cwd = getcwd()
+ chdir(WorkspaceDir)
+ ContentFile.PackFiles(FileList)
+ chdir(Cwd)
+
+ Logger.Verbose(ST.MSG_COMPRESS_DISTRIBUTION_PKG)
+
+ ContentFile.Close()
+ ContentFileClosed = True
+
+ #
+ # Add Md5Sigature
+ #
+ DistPkg.Header.Signature = md5.new(open(str(ContentFile), 'rb').read()).hexdigest()
+ #
+ # Add current Date
+ #
+ DistPkg.Header.Date = str(strftime("%Y-%m-%dT%H:%M:%S", localtime()))
+
+ #
+ # Finish final dp file
+ #
+ DistPkgFile = PackageFile(Options.PackFileToCreate, "w")
+ DistPkgFile.PackFile(str(ContentFile))
+ DistPkgXml = DistributionPackageXml()
+ DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), GlobalData.gDESC_FILE)
+ DistPkgFile.Close()
+ Logger.Quiet(ST.MSG_FINISH)
+ ReturnCode = 0
+
+ except FatalError, XExcept:
+ ReturnCode = XExcept.args[0]
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % \
+ (python_version(), platform) + format_exc())
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % \
+ (python_version(), platform) + format_exc())
+ except OSError:
+ pass
+ except:
+ Logger.Error(
+ "\nMkPkg",
+ CODE_ERROR,
+ ST.ERR_UNKNOWN_FATAL_CREATING_ERR % \
+ Options.PackFileToCreate,
+ ExtraData=ST.MSG_SEARCH_FOR_HELP,
+ RaiseError=False
+ )
+ Logger.Quiet(ST.MSG_PYTHON_ON % \
+ (python_version(), platform) + format_exc())
+ ReturnCode = CODE_ERROR
+ finally:
+ if os.path.exists(GlobalData.gCONTENT_FILE):
+ if not ContentFileClosed:
+ ContentFile.Close()
+ os.remove(GlobalData.gCONTENT_FILE)
+
+ return ReturnCode
+
+
+## CheckFileList
+#
+# @param QualifiedExt: QualifiedExt
+# @param FileList: FileList
+# @param ErrorStringExt: ErrorStringExt
+# @param ErrorStringFullPath: ErrorStringFullPath
+#
+def CheckFileList(QualifiedExt, FileList, ErrorStringExt, ErrorStringFullPath):
+ if not FileList:
+ return
+ WorkspaceDir = GlobalData.gWORKSPACE
+ WorkspaceDir = os.path.normpath(WorkspaceDir)
+ for Item in FileList:
+ Ext = os.path.splitext(Item)[1]
+ if Ext.upper() != QualifiedExt.upper():
+ Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
+ ErrorStringExt % Item)
+
+ Item = os.path.normpath(Item)
+ Path = os.path.normpath(os.path.join(WorkspaceDir, Item))
+ if not os.path.exists(Path):
+ Logger.Error("\nMkPkg", FILE_NOT_FOUND, ST.ERR_NOT_FOUND % Item)
+ elif Item == Path:
+ Logger.Error("\nMkPkg", OPTION_VALUE_INVALID,
+ ErrorStringFullPath % Item)
+ elif not IsValidPath(Item, WorkspaceDir):
+ Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
+ ErrorStringExt % Item)
+
+ if not os.path.split(Item)[0]:
+ Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \
+ ST.ERR_INVALID_METAFILE_PATH % Item)
diff --git a/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py b/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py
new file mode 100644
index 0000000000..1418a2f4bd
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/POM/CommonObject.py
@@ -0,0 +1,789 @@
+## @file
+# This file is used to define common items of class object
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+Common Object
+'''
+from Library.DataType import LANGUAGE_EN_US
+
+## HelpTextObject
+#
+# @param object: Inherited from object class
+#
+class HelpTextObject(object):
+ def __init__(self):
+ self.HelpText = TextObject()
+
+ def SetHelpText(self, HelpText):
+ self.HelpText = HelpText
+
+ def GetHelpText(self):
+ return self.HelpText
+
+## HelpTextListObject
+#
+# @param object: Inherited from object class
+#
+class HelpTextListObject(object):
+ def __init__(self):
+ self.HelpTextList = []
+
+ def SetHelpTextList(self, HelpTextList):
+ self.HelpTextList = HelpTextList
+
+ def GetHelpTextList(self):
+ return self.HelpTextList
+
+## CommonPropertiesObject
+#
+# This class defined common attribution used in Module/Platform/Package files
+#
+# @param object: Inherited from object class
+# @param Usage: Input value for Usage, default is []
+# @param FeatureFlag: Input value for FeatureFalg, default is ''
+# @param SupArchList: Input value for SupArchList, default is []
+# @param HelpText: Input value for HelpText, default is ''
+# @param HelpTextList: Input value for HelpTextList, default is []
+#
+class CommonPropertiesObject(HelpTextObject, HelpTextListObject):
+ def __init__(self):
+ self.Usage = []
+ self.FeatureFlag = ''
+ self.SupArchList = []
+ HelpTextObject.__init__(self)
+ HelpTextListObject.__init__(self)
+
+ def SetUsage(self, Usage):
+ self.Usage = Usage
+
+ def GetUsage(self):
+ return self.Usage
+
+ def SetFeatureFlag(self, FeatureFlag):
+ self.FeatureFlag = FeatureFlag
+
+ def GetFeatureFlag(self):
+ return self.FeatureFlag
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+
+ def GetSupArchList(self):
+ return self.SupArchList
+
+## CommonHeaderObject
+#
+# This class defined common header items used in Module/Platform/Package files
+#
+# @param object: Inherited from object class
+#
+class CommonHeaderObject(object):
+ def __init__(self):
+ self.Abstract = ''
+ self.Description = ''
+ self.Copyright = ''
+ self.License = ''
+
+ def SetAbstract(self, Abstract):
+ self.Abstract = Abstract
+
+ def GetAbstract(self):
+ return self.Abstract
+
+ def SetDescription(self, Description):
+ self.Description = Description
+
+ def GetDescription(self):
+ return self.Description
+
+ def SetCopyright(self, Copyright):
+ self.Copyright = Copyright
+
+ def GetCopyright(self):
+ return self.Copyright
+
+ def SetLicense(self, License):
+ self.License = License
+
+ def GetLicense(self):
+ return self.License
+
+## ClonedRecordObject
+#
+# This class defined ClonedRecord items used in Module/Platform/Package files
+#
+# @param object: Inherited from object class
+#
+class ClonedRecordObject(object):
+ def __init__(self):
+ self.IdNum = 0
+ self.FarGuid = ''
+ self.PackageGuid = ''
+ self.PackageVersion = ''
+ self.ModuleGuid = ''
+ self.ModuleVersion = ''
+
+ def SetId(self, IdNo):
+ self.IdNum = IdNo
+
+ def GetId(self):
+ return self.IdNum
+
+ def SetFarGuid(self, FarGuid):
+ self.FarGuid = FarGuid
+
+ def GetFarGuid(self):
+ return self.FarGuid
+
+ def SetPackageGuid(self, PackageGuid):
+ self.PackageGuid = PackageGuid
+
+ def GetPackageGuid(self):
+ return self.PackageGuid
+
+ def SetPackageVersion(self, PackageVersion):
+ self.PackageVersion = PackageVersion
+
+ def GetPackageVersion(self):
+ return self.PackageVersion
+
+ def SetModuleGuid(self, ModuleGuid):
+ self.ModuleGuid = ModuleGuid
+
+ def GetModuleGuid(self):
+ return self.ModuleGuid
+
+ def SetModuleVersion(self, ModuleVersion):
+ self.ModuleVersion = ModuleVersion
+
+ def GetModuleVersion(self):
+ return self.ModuleVersion
+
+## TextObject
+#
+# This class defined Text item used in PKG file
+#
+# @param object: Inherited from object class
+#
+class TextObject(object):
+ def __init__(self):
+ self.Lang = LANGUAGE_EN_US
+ self.String = ''
+
+ def SetLang(self, Lang):
+ self.Lang = Lang
+
+ def GetLang(self):
+ return self.Lang
+
+ def SetString(self, String):
+ self.String = String
+
+ def GetString(self):
+ return self.String
+
+## FileNameObject
+#
+# This class defined File item used in module, for binary files
+#
+# @param CommonPropertiesObject: Inherited from CommonPropertiesObject class
+#
+class FileNameObject(CommonPropertiesObject):
+ def __init__(self):
+ self.FileType = ''
+ self.Filename = ''
+ CommonPropertiesObject.__init__(self)
+
+ def SetFileType(self, FileType):
+ self.FileType = FileType
+
+ def GetFileType(self):
+ return self.FileType
+
+ def SetFilename(self, Filename):
+ self.Filename = Filename
+
+ def GetFilename(self):
+ return self.Filename
+
+## FileObject
+#
+# This class defined File item used in PKG file
+#
+# @param object: Inherited from object class
+#
+class FileObject(object):
+ def __init__(self):
+ self.Executable = ''
+ self.Uri = ''
+ self.OsType = ''
+
+ def SetExecutable(self, Executable):
+ self.Executable = Executable
+
+ def GetExecutable(self):
+ return self.Executable
+
+ def SetURI(self, URI):
+ self.Uri = URI
+
+ def GetURI(self):
+ return self.Uri
+
+ def SetOS(self, OsType):
+ self.OsType = OsType
+
+ def GetOS(self):
+ return self.OsType
+
+##
+# MiscFileObject is used for xml
+#
+# @param CommonHeaderObject: Inherited from CommonHeaderObject class
+#
+class MiscFileObject(CommonHeaderObject):
+ def __init__(self):
+ self.Name = ''
+ self.FileList = []
+ CommonHeaderObject.__init__(self)
+
+ def SetName(self, Name):
+ self.Name = Name
+
+ def GetName(self):
+ return self.Name
+
+ def SetFileList(self, FileList):
+ self.FileList = FileList
+
+ def GetFileList(self):
+ return self.FileList
+
+##
+# ToolsObject
+#
+class ToolsObject(MiscFileObject):
+ pass
+
+## GuidVersionObject
+#
+# This class defined GUID/Version items used in PKG file
+#
+# @param object: Inherited from object class
+#
+class GuidVersionObject(object):
+ def __init__(self):
+ self.Guid = ''
+ self.Version = ''
+
+ def SetGuid(self, Guid):
+ self.Guid = Guid
+
+ def GetGuid(self):
+ return self.Guid
+
+ def SetVersion(self, Version):
+ self.Version = Version
+
+ def GetVersion(self):
+ return self.Version
+
+## IdentificationObject
+#
+# This class defined Identification items used in Module/Platform/Package files
+#
+# @param object: Inherited from object class
+#
+class IdentificationObject(GuidVersionObject):
+ def __init__(self):
+ self.Name = ''
+ self.BaseName = ''
+ self.FileName = ''
+ self.FullPath = ''
+ self.RelaPath = ''
+ self.PackagePath = ''
+ self.ModulePath = ''
+ self.CombinePath = ''
+ GuidVersionObject.__init__(self)
+
+ def SetName(self, Name):
+ self.Name = Name
+
+ def GetName(self):
+ return self.Name
+
+ def SetBaseName(self, BaseName):
+ self.BaseName = BaseName
+
+ def GetBaseName(self):
+ return self.BaseName
+
+ def SetFileName(self, FileName):
+ self.FileName = FileName
+
+ def GetFileName(self):
+ return self.FileName
+
+ def SetFullPath(self, FullPath):
+ self.FullPath = FullPath
+
+ def GetFullPath(self):
+ return self.FullPath
+
+ def SetRelaPath(self, RelaPath):
+ self.RelaPath = RelaPath
+
+ def GetRelaPath(self):
+ return self.RelaPath
+
+ def SetPackagePath(self, PackagePath):
+ self.PackagePath = PackagePath
+
+ def GetPackagePath(self):
+ return self.PackagePath
+
+ def SetModulePath(self, ModulePath):
+ self.ModulePath = ModulePath
+
+ def GetModulePath(self):
+ return self.ModulePath
+
+ def SetCombinePath(self, CombinePath):
+ self.CombinePath = CombinePath
+
+ def GetCombinePath(self):
+ return self.CombinePath
+
+## GuidProtocolPpiCommonObject
+#
+# This class defined Guid, Protocol and Ppi like items used in
+# Module/Platform/Package files
+#
+# @param CommonPropertiesObject: Inherited from CommonPropertiesObject class
+#
+class GuidProtocolPpiCommonObject(CommonPropertiesObject):
+ def __init__(self):
+ self.Name = ''
+ self.CName = ''
+ self.Guid = ''
+ self.SupModuleList = []
+ CommonPropertiesObject.__init__(self)
+
+ def SetName(self, Name):
+ self.Name = Name
+
+ def GetName(self):
+ return self.Name
+
+ def SetCName(self, CName):
+ self.CName = CName
+
+ def GetCName(self):
+ return self.CName
+
+ def SetGuid(self, Guid):
+ self.Guid = Guid
+
+ def GetGuid(self):
+ return self.Guid
+
+ def SetSupModuleList(self, SupModuleList):
+ self.SupModuleList = SupModuleList
+
+ def GetSupModuleList(self):
+ return self.SupModuleList
+
+## GuidObject
+#
+# This class defined Guid item used in Module/Platform/Package files
+#
+# @param GuidProtocolPpiCommonObject: GuidProtocolPpiCommonObject
+#
+class GuidObject(GuidProtocolPpiCommonObject):
+ def __init__(self):
+ self.VariableName = ''
+ self.GuidTypeList = []
+ GuidProtocolPpiCommonObject.__init__(self)
+ def SetVariableName(self, VariableName):
+ self.VariableName = VariableName
+
+ def GetVariableName(self):
+ return self.VariableName
+
+ def SetGuidTypeList(self, GuidTypeList):
+ self.GuidTypeList = GuidTypeList
+
+ def GetGuidTypeList(self):
+ return self.GuidTypeList
+
+## ProtocolObject
+#
+# This class defined Protocol item used in Module/Platform/Package files
+#
+# @param GuidProtocolPpiCommonObject: Inherited from
+# GuidProtocolPpiCommonObject
+#
+class ProtocolObject(GuidProtocolPpiCommonObject):
+ def __init__(self):
+ self.Notify = False
+ GuidProtocolPpiCommonObject.__init__(self)
+ def SetNotify(self, Notify):
+ self.Notify = Notify
+
+ def GetNotify(self):
+ return self.Notify
+
+## PpiObject
+#
+# This class defined Ppi item used in Module/Platform/Package files
+#
+# @param GuidProtocolPpiCommonObject: Inherited from
+# GuidProtocolPpiCommonObject
+#
+class PpiObject(GuidProtocolPpiCommonObject):
+ def __init__(self):
+ self.Notify = False
+ GuidProtocolPpiCommonObject.__init__(self)
+ def SetNotify(self, Notify):
+ self.Notify = Notify
+
+ def GetNotify(self):
+ return self.Notify
+
+## DefineObject
+#
+# This class defined item DEFINE used in Module/Platform/Package files
+#
+# @param object: Inherited from object class
+#
+class DefineClass(object):
+ def __init__(self):
+ self.Define = {}
+
+## UserExtensionObject
+#
+# @param object: Inherited from object class
+#
+class UserExtensionObject(object):
+ def __init__(self):
+ self.UserID = ''
+ self.Identifier = ''
+ #
+ # { Statement : Arch , ... }
+ #
+ self.DefinesDict = {}
+ #
+ # { Arch : Statement , ... }
+ #
+ self.BuildOptionDict = {}
+ self.IncludesDict = {}
+ self.SourcesDict = {}
+ self.BinariesDict = {}
+ #
+ # UserExtension statement from meta-data file [UserExtension] section
+ #
+ self.Statement = ''
+ self.SupArchList = []
+
+ def SetStatement(self, Statement):
+ self.Statement = Statement
+
+ def GetStatement(self):
+ return self.Statement
+
+ def SetSupArchList(self, ArchList):
+ self.SupArchList = ArchList
+
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ def SetUserID(self, UserID):
+ self.UserID = UserID
+
+ def GetUserID(self):
+ return self.UserID
+
+ def SetIdentifier(self, Identifier):
+ self.Identifier = Identifier
+
+ def GetIdentifier(self):
+ return self.Identifier
+
+ def SetDefinesDict(self, DefinesDict):
+ self.DefinesDict = DefinesDict
+
+ def GetDefinesDict(self):
+ return self.DefinesDict
+
+ def SetBuildOptionDict(self, BuildOptionDict):
+ self.BuildOptionDict = BuildOptionDict
+
+ def GetBuildOptionDict(self):
+ return self.BuildOptionDict
+
+ def SetIncludesDict(self, IncludesDict):
+ self.IncludesDict = IncludesDict
+
+ def GetIncludesDict(self):
+ return self.IncludesDict
+
+ def SetSourcesDict(self, SourcesDict):
+ self.SourcesDict = SourcesDict
+
+ def GetSourcesDict(self):
+ return self.SourcesDict
+
+ def SetBinariesDict(self, BinariesDict):
+ self.BinariesDict = BinariesDict
+
+ def GetBinariesDict(self):
+ return self.BinariesDict
+
+## LibraryClassObject
+#
+# This class defined Library item used in Module/Platform/Package files
+#
+# @param CommonPropertiesObject: Inherited from CommonPropertiesObject class
+#
+class LibraryClassObject(CommonPropertiesObject):
+ def __init__(self):
+ self.LibraryClass = ''
+ self.IncludeHeader = ''
+ self.SupModuleList = []
+ self.RecommendedInstance = GuidVersionObject()
+ CommonPropertiesObject.__init__(self)
+
+ def SetLibraryClass(self, LibraryClass):
+ self.LibraryClass = LibraryClass
+
+ def GetLibraryClass(self):
+ return self.LibraryClass
+
+ def SetSupModuleList(self, SupModuleList):
+ self.SupModuleList = SupModuleList
+
+ def GetSupModuleList(self):
+ return self.SupModuleList
+
+ def SetIncludeHeader(self, IncludeHeader):
+ self.IncludeHeader = IncludeHeader
+
+ def GetIncludeHeader(self):
+ return self.IncludeHeader
+
+ def SetRecommendedInstance(self, RecommendedInstance):
+ self.RecommendedInstance = RecommendedInstance
+
+ def GetRecommendedInstance(self):
+ return self.RecommendedInstance
+
+
+## PcdErrorObject
+#
+# @param object: Inherited from object class
+#
+class PcdErrorObject(object):
+ def __init__(self):
+ self.ValidValue = ''
+ self.ValidValueLang = ''
+ self.ValidValueRange = ''
+ self.Expression = ''
+ self.ErrorNumber = ''
+ self.ErrorMessageList = []
+
+ def SetValidValue(self, ValidValue):
+ self.ValidValue = ValidValue
+
+ def GetValidValue(self):
+ return self.ValidValue
+
+ def SetValidValueLang(self, ValidValueLang):
+ self.ValidValueLang = ValidValueLang
+
+ def GetValidValueLang(self):
+ return self.ValidValueLang
+
+ def SetValidValueRange(self, ValidValueRange):
+ self.ValidValueRange = ValidValueRange
+
+ def GetValidValueRange(self):
+ return self.ValidValueRange
+
+ def SetExpression(self, Expression):
+ self.Expression = Expression
+
+ def GetExpression(self):
+ return self.Expression
+
+ def SetErrorNumber(self, ErrorNumber):
+ self.ErrorNumber = ErrorNumber
+
+ def GetErrorNumber(self):
+ return self.ErrorNumber
+
+ def SetErrorMessageList(self, ErrorMessageList):
+ self.ErrorMessageList = ErrorMessageList
+
+ def GetErrorMessageList(self):
+ return self.ErrorMessageList
+
+
+## IncludeObject
+#
+# This class defined Include item used in Module/Platform/Package files
+#
+# @param CommonPropertiesObject: Inherited from CommonPropertiesObject class
+#
+class IncludeObject(CommonPropertiesObject):
+ def __init__(self):
+ self.FilePath = ''
+ self.ModuleType = ''
+ self.SupModuleList = []
+ self.Comment = ''
+ CommonPropertiesObject.__init__(self)
+
+ def SetFilePath(self, FilePath):
+ self.FilePath = FilePath
+
+ def GetFilePath(self):
+ return self.FilePath
+
+ def SetModuleType(self, ModuleType):
+ self.ModuleType = ModuleType
+
+ def GetModuleType(self):
+ return self.ModuleType
+
+ def SetSupModuleList(self, SupModuleList):
+ self.SupModuleList = SupModuleList
+
+ def GetSupModuleList(self):
+ return self.SupModuleList
+
+ def SetComment(self, Comment):
+ self.Comment = Comment
+
+ def GetComment(self):
+ return self.Comment
+
+## PcdObject
+#
+# This class defined Pcd item used in Module/Platform/Package files
+#
+# @param CName: Input value for CName, default is ''
+# @param Token: Input value for Token, default is ''
+# @param TokenSpaceGuidCName: Input value for TokenSpaceGuidCName, default is
+# ''
+# @param DatumType: Input value for DatumType, default is ''
+# @param MaxDatumSize: Input value for MaxDatumSize, default is ''
+# @param DefaultValue: Input value for DefaultValue, default is ''
+# @param ItemType: Input value for ItemType, default is ''
+# @param ValidUsage: Input value for ValidUsage, default is []
+# @param SkuInfoList: Input value for SkuInfoList, default is {}
+# @param SupModuleList: Input value for SupModuleList, default is []
+#
+class PcdObject(CommonPropertiesObject, HelpTextListObject):
+ def __init__(self):
+ self.PcdCName = ''
+ self.CName = ''
+ self.Token = ''
+ self.TokenSpaceGuidCName = ''
+ self.TokenSpaceGuidValue = ''
+ self.DatumType = ''
+ self.MaxDatumSize = ''
+ self.DefaultValue = ''
+ self.Offset = ''
+ self.ValidUsage = ''
+ self.ItemType = ''
+ self.PcdErrorsList = []
+ self.SupModuleList = []
+ CommonPropertiesObject.__init__(self)
+ HelpTextListObject.__init__(self)
+
+ def SetPcdCName(self, PcdCName):
+ self.PcdCName = PcdCName
+
+ def GetPcdCName(self):
+ return self.PcdCName
+
+ def SetCName(self, CName):
+ self.CName = CName
+
+ def GetCName(self):
+ return self.CName
+
+ def SetToken(self, Token):
+ self.Token = Token
+
+ def GetOffset(self):
+ return self.Offset
+
+ def SetOffset(self, Offset):
+ self.Offset = Offset
+
+ def GetToken(self):
+ return self.Token
+
+ def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName):
+ self.TokenSpaceGuidCName = TokenSpaceGuidCName
+
+ def GetTokenSpaceGuidCName(self):
+ return self.TokenSpaceGuidCName
+
+ def SetTokenSpaceGuidValue(self, TokenSpaceGuidValue):
+ self.TokenSpaceGuidValue = TokenSpaceGuidValue
+
+ def GetTokenSpaceGuidValue(self):
+ return self.TokenSpaceGuidValue
+
+ def SetDatumType(self, DatumType):
+ self.DatumType = DatumType
+
+ def GetDatumType(self):
+ return self.DatumType
+
+ def SetMaxDatumSize(self, MaxDatumSize):
+ self.MaxDatumSize = MaxDatumSize
+
+ def GetMaxDatumSize(self):
+ return self.MaxDatumSize
+
+ def SetDefaultValue(self, DefaultValue):
+ self.DefaultValue = DefaultValue
+
+ def GetDefaultValue(self):
+ return self.DefaultValue
+
+ def SetValidUsage(self, ValidUsage):
+ self.ValidUsage = ValidUsage
+
+ def GetValidUsage(self):
+ return self.ValidUsage
+
+ def SetPcdErrorsList(self, PcdErrorsList):
+ self.PcdErrorsList = PcdErrorsList
+
+ def GetPcdErrorsList(self):
+ return self.PcdErrorsList
+
+ def SetItemType(self, ItemType):
+ self.ItemType = ItemType
+
+ def GetItemType(self):
+ return self.ItemType
+
+ def SetSupModuleList(self, SupModuleList):
+ self.SupModuleList = SupModuleList
+
+ def GetSupModuleList(self):
+ return self.SupModuleList
diff --git a/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py b/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py
new file mode 100644
index 0000000000..620bbb411f
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py
@@ -0,0 +1,645 @@
+## @file
+# This file is used to define a class object to describe a module
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+ModuleObject
+'''
+
+##
+# Import Modules
+#
+from Object.POM.CommonObject import CommonPropertiesObject
+from Object.POM.CommonObject import IdentificationObject
+from Object.POM.CommonObject import CommonHeaderObject
+from Object.POM.CommonObject import HelpTextListObject
+from Object.POM.CommonObject import GuidVersionObject
+
+
+##
+# BootModeObject
+#
+class BootModeObject(CommonPropertiesObject, HelpTextListObject):
+ def __init__(self):
+ self.SupportedBootModes = ''
+ CommonPropertiesObject.__init__(self)
+ HelpTextListObject.__init__(self)
+
+ def SetSupportedBootModes(self, SupportedBootModes):
+ self.SupportedBootModes = SupportedBootModes
+
+ def GetSupportedBootModes(self):
+ return self.SupportedBootModes
+
+##
+# EventObject
+#
+class EventObject(CommonPropertiesObject, HelpTextListObject):
+ def __init__(self):
+ self.EventType = ''
+ CommonPropertiesObject.__init__(self)
+ HelpTextListObject.__init__(self)
+
+ def SetEventType(self, EventType):
+ self.EventType = EventType
+
+ def GetEventType(self):
+ return self.EventType
+
+##
+# HobObject
+#
+class HobObject(CommonPropertiesObject, HelpTextListObject):
+ def __init__(self):
+ self.HobType = ''
+ CommonPropertiesObject.__init__(self)
+ HelpTextListObject.__init__(self)
+
+ def SetHobType(self, HobType):
+ self.HobType = HobType
+
+ def GetHobType(self):
+ return self.HobType
+
+##
+# SpecObject
+#
+class SpecObject(object):
+ def __init__(self):
+ self.Spec = ''
+ self.Version = ''
+
+ def SetSpec(self, Spec):
+ self.Spec = Spec
+
+ def GetSpec(self):
+ return self.Spec
+
+ def SetVersion(self, Version):
+ self.Version = Version
+
+ def GetVersion(self):
+ return self.Version
+
+## ModuleHeaderObject
+#
+# This class defined header items used in Module file
+#
+class ModuleHeaderObject(IdentificationObject, CommonHeaderObject):
+ def __init__(self):
+ self.IsLibrary = False
+ self.IsLibraryModList = []
+ self.ModuleType = ''
+ self.BinaryModule = False
+ self.PcdIsDriver = ''
+ self.PiSpecificationVersion = ''
+ self.UefiSpecificationVersion = ''
+ #
+ # SpecObject
+ #
+ self.SpecList = []
+ #
+ # BootModeObject
+ #
+ self.BootModeList = []
+ #
+ # EventObject
+ #
+ self.EventList = []
+ #
+ # HobObject
+ #
+ self.HobList = []
+ #
+ # LibraryClassObject
+ #
+ self.LibraryClassList = []
+ self.SupArchList = []
+ IdentificationObject.__init__(self)
+ CommonHeaderObject.__init__(self)
+
+ def SetIsLibrary(self, IsLibrary):
+ self.IsLibrary = IsLibrary
+
+ def GetIsLibrary(self):
+ return self.IsLibrary
+
+ def SetIsLibraryModList(self, IsLibraryModList):
+ self.IsLibraryModList = IsLibraryModList
+
+ def GetIsLibraryModList(self):
+ return self.IsLibraryModList
+
+ def SetModuleType(self, ModuleType):
+ self.ModuleType = ModuleType
+
+ def GetModuleType(self):
+ return self.ModuleType
+
+ def SetBinaryModule(self, BinaryModule):
+ self.BinaryModule = BinaryModule
+
+ def GetBinaryModule(self):
+ return self.BinaryModule
+
+ def SetPcdIsDriver(self, PcdIsDriver):
+ self.PcdIsDriver = PcdIsDriver
+
+ def GetPcdIsDriver(self):
+ return self.PcdIsDriver
+
+ def SetPiSpecificationVersion(self, PiSpecificationVersion):
+ self.PiSpecificationVersion = PiSpecificationVersion
+
+ def GetPiSpecificationVersion(self):
+ return self.PiSpecificationVersion
+
+ def SetUefiSpecificationVersion(self, UefiSpecificationVersion):
+ self.UefiSpecificationVersion = UefiSpecificationVersion
+
+ def GetUefiSpecificationVersion(self):
+ return self.UefiSpecificationVersion
+
+ def SetSpecList(self, SpecList):
+ self.SpecList = SpecList
+
+ def GetSpecList(self):
+ return self.SpecList
+
+ def SetBootModeList(self, BootModeList):
+ self.BootModeList = BootModeList
+
+ def GetBootModeList(self):
+ return self.BootModeList
+
+ def SetEventList(self, EventList):
+ self.EventList = EventList
+
+ def GetEventList(self):
+ return self.EventList
+
+ def SetHobList(self, HobList):
+ self.HobList = HobList
+
+ def GetHobList(self):
+ return self.HobList
+
+ def SetLibraryClassList(self, LibraryClassList):
+ self.LibraryClassList = LibraryClassList
+
+ def GetLibraryClassList(self):
+ return self.LibraryClassList
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+
+ def GetSupArchList(self):
+ return self.SupArchList
+
+##
+# SourceFileObject
+#
+class SourceFileObject(CommonPropertiesObject):
+ def __init__(self):
+ CommonPropertiesObject.__init__(self)
+ self.SourceFile = ''
+ self.TagName = ''
+ self.ToolCode = ''
+ self.Family = ''
+ self.FileType = ''
+
+ def SetSourceFile(self, SourceFile):
+ self.SourceFile = SourceFile
+
+ def GetSourceFile(self):
+ return self.SourceFile
+
+ def SetTagName(self, TagName):
+ self.TagName = TagName
+
+ def GetTagName(self):
+ return self.TagName
+
+ def SetToolCode(self, ToolCode):
+ self.ToolCode = ToolCode
+
+ def GetToolCode(self):
+ return self.ToolCode
+
+ def SetFamily(self, Family):
+ self.Family = Family
+
+ def GetFamily(self):
+ return self.Family
+
+ def SetFileType(self, FileType):
+ self.FileType = FileType
+
+ def GetFileType(self):
+ return self.FileType
+
+
+##
+# BinaryFileObject
+#
+class BinaryFileObject(CommonPropertiesObject):
+ def __init__(self):
+ self.FileNamList = []
+ self.AsBuiltList = []
+ CommonPropertiesObject.__init__(self)
+
+ def SetFileNameList(self, FileNamList):
+ self.FileNamList = FileNamList
+
+ def GetFileNameList(self):
+ return self.FileNamList
+
+ def SetAsBuiltList(self, AsBuiltList):
+ self.AsBuiltList = AsBuiltList
+
+ def GetAsBuiltList(self):
+ return self.AsBuiltList
+
+
+##
+# AsBuildLibraryClassObject
+#
+class AsBuildLibraryClassObject(object):
+ def __init__(self):
+ self.LibGuid = ''
+ self.LibVersion = ''
+
+ def SetLibGuid(self, LibGuid):
+ self.LibGuid = LibGuid
+ def GetLibGuid(self):
+ return self.LibGuid
+
+ def SetLibVersion(self, LibVersion):
+ self.LibVersion = LibVersion
+ def GetLibVersion(self):
+ return self.LibVersion
+
+##
+# AsBuiltObject
+#
+class AsBuiltObject(object):
+ def __init__(self):
+ #
+ # list of PcdObject
+ #
+ self.PatchPcdList = []
+ #
+ # list of PcdObject
+ #
+ self.PcdExValueList = []
+ #
+ # list of GuidVersionObject
+ #
+ self.LibraryInstancesList = []
+ #
+ # List of BinaryBuildFlag object
+ #
+ self.BinaryBuildFlagList = ''
+
+ def SetPatchPcdList(self, PatchPcdList):
+ self.PatchPcdList = PatchPcdList
+
+ def GetPatchPcdList(self):
+ return self.PatchPcdList
+
+ def SetPcdExList(self, PcdExValueList):
+ self.PcdExValueList = PcdExValueList
+
+ def GetPcdExList(self):
+ return self.PcdExValueList
+
+ def SetLibraryInstancesList(self, LibraryInstancesList):
+ self.LibraryInstancesList = LibraryInstancesList
+
+ def GetLibraryInstancesList(self):
+ return self.LibraryInstancesList
+
+ def SetBuildFlagsList(self, BinaryBuildFlagList):
+ self.BinaryBuildFlagList = BinaryBuildFlagList
+
+ def GetBuildFlagsList(self):
+ return self.BinaryBuildFlagList
+
+##
+# BinaryBuildFlag, this object will include those fields that are not
+# covered by the UPT Spec BinaryFile field
+#
+class BinaryBuildFlagObject(object):
+ def __init__(self):
+ self.Target = ''
+ self.TagName = ''
+ self.Family = ''
+ self.AsBuiltOptionFlags = ''
+
+ def SetTarget(self, Target):
+ self.Target = Target
+
+ def GetTarget(self):
+ return self.Target
+
+ def SetTagName(self, TagName):
+ self.TagName = TagName
+
+ def GetTagName(self):
+ return self.TagName
+
+ def SetFamily(self, Family):
+ self.Family = Family
+
+ def GetFamily(self):
+ return self.Family
+
+ def SetAsBuiltOptionFlags(self, AsBuiltOptionFlags):
+ self.AsBuiltOptionFlags = AsBuiltOptionFlags
+ def GetAsBuiltOptionFlags(self):
+ return self.AsBuiltOptionFlags
+
+##
+# ExternObject
+#
+class ExternObject(CommonPropertiesObject):
+ def __init__(self):
+ self.EntryPoint = ''
+ self.UnloadImage = ''
+ self.Constructor = ''
+ self.Destructor = ''
+ self.SupModList = []
+ CommonPropertiesObject.__init__(self)
+
+ def SetEntryPoint(self, EntryPoint):
+ self.EntryPoint = EntryPoint
+
+ def GetEntryPoint(self):
+ return self.EntryPoint
+
+ def SetUnloadImage(self, UnloadImage):
+ self.UnloadImage = UnloadImage
+
+ def GetUnloadImage(self):
+ return self.UnloadImage
+
+ def SetConstructor(self, Constructor):
+ self.Constructor = Constructor
+
+ def GetConstructor(self):
+ return self.Constructor
+
+ def SetDestructor(self, Destructor):
+ self.Destructor = Destructor
+
+ def GetDestructor(self):
+ return self.Destructor
+
+ def SetSupModList(self, SupModList):
+ self.SupModList = SupModList
+ def GetSupModList(self):
+ return self.SupModList
+
+##
+# DepexObject
+#
+class DepexObject(CommonPropertiesObject):
+ def __init__(self):
+ self.Depex = ''
+ self.ModuelType = ''
+ CommonPropertiesObject.__init__(self)
+
+ def SetDepex(self, Depex):
+ self.Depex = Depex
+
+ def GetDepex(self):
+ return self.Depex
+
+ def SetModuleType(self, ModuleType):
+ self.ModuelType = ModuleType
+
+ def GetModuleType(self):
+ return self.ModuelType
+
+##
+# PackageDependencyObject
+#
+class PackageDependencyObject(GuidVersionObject, CommonPropertiesObject):
+ def __init__(self):
+ self.Package = ''
+ self.PackageFilePath = ''
+ GuidVersionObject.__init__(self)
+ CommonPropertiesObject.__init__(self)
+
+ def SetPackageFilePath(self, PackageFilePath):
+ self.PackageFilePath = PackageFilePath
+
+ def GetPackageFilePath(self):
+ return self.PackageFilePath
+
+ def SetPackage(self, Package):
+ self.Package = Package
+
+ def GetPackage(self):
+ return self.Package
+
+##
+# BuildOptionObject
+#
+class BuildOptionObject(CommonPropertiesObject):
+ def __init__(self):
+ CommonPropertiesObject.__init__(self)
+ self.BuildOption = ''
+
+ def SetBuildOption(self, BuildOption):
+ self.BuildOption = BuildOption
+
+ def GetBuildOption(self):
+ return self.BuildOption
+
+##
+# ModuleObject
+#
+class ModuleObject(ModuleHeaderObject):
+ def __init__(self):
+ #
+ # {Arch : ModuleHeaderObject}
+ #
+ self.HeaderDict = {}
+ #
+ # LibraryClassObject
+ #
+ self.LibraryClassList = []
+ #
+ # SourceFileObject
+ #
+ self.SourceFileList = []
+ #
+ # BinaryFileObject
+ #
+ self.BinaryFileList = []
+ #
+ # PackageDependencyObject
+ #
+ self.PackageDependencyList = []
+ #
+ # DepexObject
+ #
+ self.PeiDepex = []
+ #
+ # DepexObject
+ #
+ self.DxeDepex = []
+ #
+ # DepexObject
+ #
+ self.SmmDepex = []
+ #
+ # ProtocolObject
+ #
+ self.ProtocolList = []
+ #
+ # PpiObject
+ #
+ self.PpiList = []
+ #
+ # GuidObject
+ #
+ self.GuidList = []
+ #
+ # PcdObject
+ #
+ self.PcdList = []
+ #
+ # ExternObject
+ #
+ self.ExternList = []
+ #
+ # BuildOptionObject
+ #
+ self.BuildOptionList = []
+ #
+ # UserExtensionObject
+ #
+ self.UserExtensionList = []
+ #
+ # MiscFileObject
+ #
+ self.MiscFileList = []
+ #
+ # ClonedFromObject
+ #
+ self.ClonedFrom = None
+
+ ModuleHeaderObject.__init__(self)
+
+ def SetHeaderDict(self, HeaderDict):
+ self.HeaderDict = HeaderDict
+
+ def GetHeaderDict(self):
+ return self.HeaderDict
+
+ def SetLibraryClassList(self, LibraryClassList):
+ self.LibraryClassList = LibraryClassList
+
+ def GetLibraryClassList(self):
+ return self.LibraryClassList
+
+ def SetSourceFileList(self, SourceFileList):
+ self.SourceFileList = SourceFileList
+
+ def GetSourceFileList(self):
+ return self.SourceFileList
+
+ def SetBinaryFileList(self, BinaryFileList):
+ self.BinaryFileList = BinaryFileList
+
+ def GetBinaryFileList(self):
+ return self.BinaryFileList
+
+ def SetPackageDependencyList(self, PackageDependencyList):
+ self.PackageDependencyList = PackageDependencyList
+
+ def GetPackageDependencyList(self):
+ return self.PackageDependencyList
+
+ def SetPeiDepex(self, PeiDepex):
+ self.PeiDepex = PeiDepex
+
+ def GetPeiDepex(self):
+ return self.PeiDepex
+
+ def SetDxeDepex(self, DxeDepex):
+ self.DxeDepex = DxeDepex
+
+ def GetDxeDepex(self):
+ return self.DxeDepex
+
+ def SetSmmDepex(self, SmmDepex):
+ self.SmmDepex = SmmDepex
+
+ def GetSmmDepex(self):
+ return self.SmmDepex
+
+ def SetPpiList(self, PpiList):
+ self.PpiList = PpiList
+
+ def GetPpiList(self):
+ return self.PpiList
+
+ def SetProtocolList(self, ProtocolList):
+ self.ProtocolList = ProtocolList
+
+ def GetProtocolList(self):
+ return self.ProtocolList
+
+ def SetPcdList(self, PcdList):
+ self.PcdList = PcdList
+
+ def GetPcdList(self):
+ return self.PcdList
+
+ def SetGuidList(self, GuidList):
+ self.GuidList = GuidList
+
+ def GetGuidList(self):
+ return self.GuidList
+
+ def SetExternList(self, ExternList):
+ self.ExternList = ExternList
+
+ def GetExternList(self):
+ return self.ExternList
+
+ def SetBuildOptionList(self, BuildOptionList):
+ self.BuildOptionList = BuildOptionList
+
+ def GetBuildOptionList(self):
+ return self.BuildOptionList
+
+ def SetUserExtensionList(self, UserExtensionList):
+ self.UserExtensionList = UserExtensionList
+
+ def GetUserExtensionList(self):
+ return self.UserExtensionList
+
+ def SetMiscFileList(self, MiscFileList):
+ self.MiscFileList = MiscFileList
+
+ def GetMiscFileList(self):
+ return self.MiscFileList
+
+ def SetClonedFrom(self, ClonedFrom):
+ self.ClonedFrom = ClonedFrom
+
+ def GetClonedFrom(self):
+ return self.ClonedFrom
diff --git a/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py b/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py
new file mode 100644
index 0000000000..098954d4ed
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/POM/PackageObject.py
@@ -0,0 +1,190 @@
+## @file
+# This file is used to define a class object to describe a package
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+PackageObject
+'''
+
+##
+# Import Modules
+#
+from Object.POM.CommonObject import CommonPropertiesObject
+from Object.POM.CommonObject import IdentificationObject
+from Object.POM.CommonObject import CommonHeaderObject
+from Library.Misc import Sdict
+
+## StandardIncludeFileObject
+#
+class StandardIncludeFileObject(CommonPropertiesObject):
+ def __init__(self):
+ CommonPropertiesObject.__init__(self)
+ self.IncludeFile = ''
+
+ def SetIncludeFile(self, IncludeFile):
+ self.IncludeFile = IncludeFile
+
+ def GetIncludeFile(self):
+ return self.IncludeFile
+
+## PackageIncludeFileObject
+#
+class PackageIncludeFileObject(StandardIncludeFileObject):
+ pass
+
+##
+# PackageObject
+#
+class PackageObject(IdentificationObject, CommonHeaderObject):
+ def __init__(self):
+ IdentificationObject.__init__(self)
+ CommonHeaderObject.__init__(self)
+ #
+ # LibraryClassObject
+ #
+ self.LibraryClassList = []
+ #
+ # FileObject
+ #
+ self.IncludePathList = []
+ #
+ # StandardIncludeFileObject
+ #
+ self.StandardIncludeFileList = []
+ #
+ # PackageIncludeFileObject
+ #
+ self.PackageIncludeFileList = []
+ #
+ # Include and Arch List, item is (IncludePath, SupArchList-List of Arch), used during install package
+ #
+ self.IncludeArchList = []
+ #
+ # ProtocolObject
+ #
+ self.ProtocolList = []
+ #
+ # PpiObject
+ #
+ self.PpiList = []
+ #
+ # GuidObject
+ #
+ self.GuidList = []
+ #
+ # (PcdObject, PcdErrorObject)
+ #
+ self.PcdList = []
+ #
+ # UserExtensionObject
+ #
+ self.UserExtensionList = []
+ #
+ # MiscFileObject
+ #
+ self.MiscFileList = []
+ self.ModuleDict = Sdict()
+ #
+ # ClonedRecordObject
+ #
+ self.ClonedFromList = []
+ #
+ # string object
+ #
+ self.ModuleFileList = []
+
+ self.PcdChecks = []
+
+ def SetLibraryClassList(self, LibraryClassList):
+ self.LibraryClassList = LibraryClassList
+
+ def GetLibraryClassList(self):
+ return self.LibraryClassList
+
+ def SetIncludePathList(self, IncludePathList):
+ self.IncludePathList = IncludePathList
+
+ def GetIncludePathList(self):
+ return self.IncludePathList
+
+ def SetIncludeArchList(self, IncludeArchList):
+ self.IncludeArchList = IncludeArchList
+
+ def GetIncludeArchList(self):
+ return self.IncludeArchList
+
+ def SetStandardIncludeFileList(self, StandardIncludeFileList):
+ self.StandardIncludeFileList = StandardIncludeFileList
+
+ def GetStandardIncludeFileList(self):
+ return self.StandardIncludeFileList
+
+ def SetPackageIncludeFileList(self, PackageIncludeFileList):
+ self.PackageIncludeFileList = PackageIncludeFileList
+
+ def GetPackageIncludeFileList(self):
+ return self.PackageIncludeFileList
+
+ def SetProtocolList(self, ProtocolList):
+ self.ProtocolList = ProtocolList
+
+ def GetProtocolList(self):
+ return self.ProtocolList
+
+ def SetPpiList(self, PpiList):
+ self.PpiList = PpiList
+
+ def GetPpiList(self):
+ return self.PpiList
+
+ def SetGuidList(self, GuidList):
+ self.GuidList = GuidList
+
+ def GetGuidList(self):
+ return self.GuidList
+
+ def SetPcdList(self, PcdList):
+ self.PcdList = PcdList
+
+ def GetPcdList(self):
+ return self.PcdList
+
+ def SetUserExtensionList(self, UserExtensionList):
+ self.UserExtensionList = UserExtensionList
+
+ def GetUserExtensionList(self):
+ return self.UserExtensionList
+
+ def SetMiscFileList(self, MiscFileList):
+ self.MiscFileList = MiscFileList
+
+ def GetMiscFileList(self):
+ return self.MiscFileList
+
+ def SetModuleDict(self, ModuleDict):
+ self.ModuleDict = ModuleDict
+
+ def GetModuleDict(self):
+ return self.ModuleDict
+
+ def SetClonedFromList(self, ClonedFromList):
+ self.ClonedFromList = ClonedFromList
+
+ def GetClonedFromList(self):
+ return self.ClonedFromList
+
+ def SetModuleFileList(self, ModuleFileList):
+ self.ModuleFileList = ModuleFileList
+
+ def GetModuleFileList(self):
+ return self.ModuleFileList
+
diff --git a/BaseTools/Source/Python/UPT/Object/POM/__init__.py b/BaseTools/Source/Python/UPT/Object/POM/__init__.py
new file mode 100644
index 0000000000..e2235f1bf0
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/POM/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Object' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+POM
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py b/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py
new file mode 100644
index 0000000000..6336a90fb9
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/DecObject.py
@@ -0,0 +1,611 @@
+## @file
+# This file is used to define class objects for DEC file. It will consumed by
+#DecParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+DecObject
+'''
+
+## Import modules
+#
+import os.path
+
+from Library.Misc import Sdict
+from Library.DataType import TAB_GUIDS
+from Library.DataType import TAB_PPIS
+from Library.DataType import TAB_PROTOCOLS
+from Library.DataType import TAB_DEC_DEFINES
+from Library.DataType import TAB_INCLUDES
+from Library.DataType import TAB_LIBRARY_CLASSES
+from Library.DataType import TAB_USER_EXTENSIONS
+from Library.DataType import TAB_PCDS
+from Library.DataType import TAB_ARCH_COMMON
+
+## _DecComments
+#
+# Base class for all data objects which have head and tail comments
+#
+class _DecComments:
+
+ ##constructor
+ #
+ def __init__(self):
+ self._HeadComment = []
+ self._TailComment = []
+
+ ## GetComments
+ #
+ def GetComments(self):
+ return self._HeadComment, self._TailComment
+
+ ## GetHeadComment
+ #
+ def GetHeadComment(self):
+ return self._HeadComment
+
+ ## SetHeadComment
+ #
+ # @param Comment: comment content
+ #
+ def SetHeadComment(self, Comment):
+ self._HeadComment = Comment
+
+ ## GetTailComment
+ #
+ def GetTailComment(self):
+ return self._TailComment
+
+ ## SetTailComment
+ #
+ # @param Comment: comment content
+ #
+ def SetTailComment(self, Comment):
+ self._TailComment = Comment
+
+## _DecBaseObject
+#
+# Base class that hold common info
+#
+class _DecBaseObject(_DecComments):
+ def __init__(self, PkgFullName):
+ _DecComments.__init__(self)
+ #
+ # Key is combined with (Arch, SectionType)
+ # Default is common
+ #
+ self.ValueDict = Sdict()
+ self._PkgFullName = PkgFullName
+ self._PackagePath, self._FileName = os.path.split(PkgFullName)
+ self._SecName = ''
+
+ ## GetSectionName
+ #
+ def GetSectionName(self):
+ return self._SecName
+
+ ## GetPackagePath
+ #
+ def GetPackagePath(self):
+ return self._PackagePath
+
+ ## GetPackageFile
+ #
+ def GetPackageFile(self):
+ return self._FileName
+
+ ## GetPackageFullName
+ #
+ def GetPackageFullName(self):
+ return self._PkgFullName
+
+ ## AddItem
+ # Add sub-item to current object, sub-class should override it if needed
+ #
+ # @param Item: Sub-item to be added
+ # @param Scope: A list store section name and arch info
+ #
+ def AddItem(self, Item, Scope):
+ if not Scope:
+ return
+ if not Item:
+ return
+ ArchModule = []
+ for Ele in Scope:
+ if Ele[1] in self.ValueDict:
+ self.ValueDict[Ele[1]].append(Item)
+ else:
+ self.ValueDict[Ele[1]] = [Item]
+ ArchModule.append(Ele[1])
+ Item.ArchAndModuleType = ArchModule
+
+ ## _GetItemByArch
+ # Helper class used by sub-class
+ # @param Arch: arch
+ #
+ def _GetItemByArch(self, Arch):
+ Arch = Arch.upper()
+ if Arch not in self.ValueDict:
+ return []
+ return self.ValueDict[Arch]
+
+ ## _GetAllItems
+ # Get all items, union all arches, items in returned list are unique
+ #
+ def _GetAllItems(self):
+ Retlst = []
+ for Arch in self.ValueDict:
+ for Item in self.ValueDict[Arch]:
+ if Item not in Retlst:
+ Retlst.append(Item)
+ return Retlst
+
+## _DecItemBaseObject
+#
+# Module type and arch the item belongs to
+#
+class _DecItemBaseObject(_DecComments):
+ def __init__(self):
+ _DecComments.__init__(self)
+ #
+ # Item's arch, if PCD, also include PCD type
+ #
+ self.ArchAndModuleType = []
+
+ ## GetArchList
+ #
+ def GetArchList(self):
+ ArchSet = set()
+ for Arch in self.ArchAndModuleType:
+ ArchSet.add(Arch)
+ return list(ArchSet)
+
+## DecDefineObject
+#
+# Class to hold define section infomation
+#
+class DecDefineObject(_DecBaseObject):
+ def __init__(self, PkgFullName):
+ _DecBaseObject.__init__(self, PkgFullName)
+ self._SecName = TAB_DEC_DEFINES.upper()
+ self._DecSpec = ''
+ self._PkgName = ''
+ self._PkgGuid = ''
+ self._PkgVersion = ''
+ self._PkgUniFile = ''
+
+ ## GetPackageSpecification
+ #
+ def GetPackageSpecification(self):
+ return self._DecSpec
+
+ def SetPackageSpecification(self, DecSpec):
+ self._DecSpec = DecSpec
+
+ ## GetPackageName
+ #
+ def GetPackageName(self):
+ return self._PkgName
+
+ def SetPackageName(self, PkgName):
+ self._PkgName = PkgName
+
+ ## GetPackageGuid
+ #
+ def GetPackageGuid(self):
+ return self._PkgGuid
+
+ def SetPackageGuid(self, PkgGuid):
+ self._PkgGuid = PkgGuid
+
+ ## GetPackageVersion
+ #
+ def GetPackageVersion(self):
+ return self._PkgVersion
+
+ def SetPackageVersion(self, PkgVersion):
+ self._PkgVersion = PkgVersion
+
+ ## GetPackageUniFile
+ #
+ def GetPackageUniFile(self):
+ return self._PkgUniFile
+
+ def SetPackageUniFile(self, PkgUniFile):
+ self._PkgUniFile = PkgUniFile
+
+ ## GetDefines
+ #
+ def GetDefines(self):
+ return self._GetItemByArch(TAB_ARCH_COMMON)
+
+ ## GetAllDefines
+ #
+ def GetAllDefines(self):
+ return self._GetAllItems()
+
+## DecDefineItemObject
+#
+# Each item of define section
+#
+class DecDefineItemObject(_DecItemBaseObject):
+ def __init__(self):
+ _DecItemBaseObject.__init__(self)
+ self.Key = ''
+ self.Value = ''
+
+ ## __hash__
+ #
+ def __hash__(self):
+ return hash(self.Key + self.Value)
+
+ ## __eq__
+ #
+ def __eq__(self, Other):
+ return id(self) == id(Other)
+
+ ## __str__
+ #
+ def __str__(self):
+ return str(self.ArchAndModuleType) + '\n' + self.Key + \
+ ' = ' + self.Value
+
+## DecIncludeObject
+#
+# Class to hold include section info
+#
+class DecIncludeObject(_DecBaseObject):
+ def __init__(self, PkgFullName):
+ _DecBaseObject.__init__(self, PkgFullName)
+ self._SecName = TAB_INCLUDES.upper()
+
+ ## GetIncludes
+ #
+ def GetIncludes(self, Arch=TAB_ARCH_COMMON):
+ return self._GetItemByArch(Arch)
+
+ ## GetAllIncludes
+ #
+ def GetAllIncludes(self):
+ return self._GetAllItems()
+
+## DecIncludeItemObject
+#
+# Item of include section
+#
+class DecIncludeItemObject(_DecItemBaseObject):
+ def __init__(self, File, Root):
+ self.File = File
+ self.Root = Root
+ _DecItemBaseObject.__init__(self)
+
+ ## __hash__
+ #
+ def __hash__(self):
+ return hash(self.File)
+
+ ## __eq__
+ #
+ def __eq__(self, Other):
+ return id(self) == id(Other)
+
+ ## __str__
+ #
+ def __str__(self):
+ return self.File
+
+## DecLibraryclassObject
+#
+# Class to hold library class section info
+#
+class DecLibraryclassObject(_DecBaseObject):
+ def __init__(self, PkgFullName):
+ _DecBaseObject.__init__(self, PkgFullName)
+ self._PackagePath, self._FileName = os.path.split(PkgFullName)
+ self._SecName = TAB_LIBRARY_CLASSES.upper()
+
+ ## GetLibraryclasses
+ #
+ def GetLibraryclasses(self, Arch=TAB_ARCH_COMMON):
+ return self._GetItemByArch(Arch)
+
+ ## GetAllLibraryclasses
+ #
+ def GetAllLibraryclasses(self):
+ return self._GetAllItems()
+
+## DecLibraryclassItemObject
+# Item of library class section
+#
+class DecLibraryclassItemObject(_DecItemBaseObject):
+ def __init__(self, Libraryclass, File, Root):
+ _DecItemBaseObject.__init__(self)
+ self.File = File
+ self.Root = Root
+ self.Libraryclass = Libraryclass
+
+ ## __hash__
+ #
+ def __hash__(self):
+ return hash(self.Libraryclass + self.File)
+
+ ## __eq__
+ #
+ def __eq__(self, Other):
+ return id(self) == id(Other)
+
+ ## __str__
+ #
+ def __str__(self):
+ return self.Libraryclass + '|' + self.File
+
+## DecPcdObject
+# Class to hold PCD section
+#
+class DecPcdObject(_DecBaseObject):
+ def __init__(self, PkgFullName):
+ _DecBaseObject.__init__(self, PkgFullName)
+ self._SecName = TAB_PCDS.upper()
+
+ ## AddItem
+ #
+ # Diff from base class
+ #
+ # @param Item: Item
+ # @param Scope: Scope
+ #
+ def AddItem(self, Item, Scope):
+ if not Scope:
+ return
+ if not Item:
+ return
+ ArchModule = []
+ for Type, Arch in Scope:
+ if (Type, Arch) in self.ValueDict:
+ self.ValueDict[Type, Arch].append(Item)
+ else:
+ self.ValueDict[Type, Arch] = [Item]
+ ArchModule.append([Type, Arch])
+ Item.ArchAndModuleType = ArchModule
+
+ ## GetPcds
+ #
+ # @param PcdType: PcdType
+ # @param Arch: Arch
+ #
+ def GetPcds(self, PcdType, Arch=TAB_ARCH_COMMON):
+ PcdType = PcdType.upper()
+ Arch = Arch.upper()
+ if (PcdType, Arch) not in self.ValueDict:
+ return []
+ return self.ValueDict[PcdType, Arch]
+
+ ## GetPcdsByType
+ #
+ # @param PcdType: PcdType
+ #
+ def GetPcdsByType(self, PcdType):
+ PcdType = PcdType.upper()
+ Retlst = []
+ for TypeInDict, Arch in self.ValueDict:
+ if TypeInDict != PcdType:
+ continue
+ for Item in self.ValueDict[PcdType, Arch]:
+ if Item not in Retlst:
+ Retlst.append(Item)
+ return Retlst
+
+## DecPcdItemObject
+#
+# Item of PCD section
+#
+# @param _DecItemBaseObject: _DecItemBaseObject object
+#
+class DecPcdItemObject(_DecItemBaseObject):
+ def __init__(self, Guid, Name, Value, DatumType,
+ Token, MaxDatumSize=''):
+ _DecItemBaseObject.__init__(self)
+ self.TokenCName = Name
+ self.TokenSpaceGuidCName = Guid
+ self.DatumType = DatumType
+ self.DefaultValue = Value
+ self.TokenValue = Token
+ self.MaxDatumSize = MaxDatumSize
+
+ ## __hash__
+ #
+ def __hash__(self):
+ return hash(self.TokenSpaceGuidCName + self.TokenCName)
+
+ ## __eq__
+ #
+ def __eq__(self, Other):
+ return id(self) == id(Other)
+
+ ## GetArchListOfType
+ #
+ # @param PcdType: PcdType
+ #
+ def GetArchListOfType(self, PcdType):
+ ItemSet = set()
+ PcdType = PcdType.upper()
+ for Type, Arch in self.ArchAndModuleType:
+ if Type != PcdType:
+ continue
+ ItemSet.add(Arch)
+ return list(ItemSet)
+
+## DecGuidObjectBase
+#
+# Base class for PPI, Protocol, and GUID.
+# Hold same data but has different method for clarification in sub-class
+#
+# @param _DecBaseObject: Dec Base Object
+#
+class DecGuidObjectBase(_DecBaseObject):
+ def __init__(self, PkgFullName):
+ _DecBaseObject.__init__(self, PkgFullName)
+
+ ## GetGuidStyleItems
+ #
+ # @param Arch: Arch
+ #
+ def GetGuidStyleItems(self, Arch=TAB_ARCH_COMMON):
+ return self._GetItemByArch(Arch)
+
+ ## GetGuidStyleAllItems
+ #
+ def GetGuidStyleAllItems(self):
+ return self._GetAllItems()
+
+## DecGuidItemObject
+#
+# Item of GUID, PPI and Protocol section
+#
+# @param _DecItemBaseObject: Dec Item Base Object
+#
+class DecGuidItemObject(_DecItemBaseObject):
+ def __init__(self, CName, GuidCValue, GuidString):
+ _DecItemBaseObject.__init__(self)
+ self.GuidCName = CName
+ self.GuidCValue = GuidCValue
+ self.GuidString = GuidString
+
+ ## __hash__
+ #
+ def __hash__(self):
+ return hash(self.GuidCName)
+
+ ## __eq__
+ #
+ def __eq__(self, Other):
+ return id(self) == id(Other)
+
+ ## __str__
+ #
+ def __str__(self):
+ return self.GuidCName + ' = ' + self.GuidCValue
+
+## DecGuidObject
+#
+# Class for GUID section
+#
+# @param DecGuidObjectBase: Dec Guid Object Base
+#
+class DecGuidObject(DecGuidObjectBase):
+ def __init__(self, PkgFullName):
+ DecGuidObjectBase.__init__(self, PkgFullName)
+ self._SecName = TAB_GUIDS.upper()
+
+ ## GetGuids
+ #
+ # @param Arch: Arch
+ #
+ def GetGuids(self, Arch=TAB_ARCH_COMMON):
+ return self._GetItemByArch(Arch)
+
+ ## GetAllGuids
+ #
+ def GetAllGuids(self):
+ return self._GetAllItems()
+
+## DecPpiObject
+#
+# Class for PPI seciont
+#
+# @param DecGuidObjectBase: Dec Guid Object Base
+#
+class DecPpiObject(DecGuidObjectBase):
+ def __init__(self, PkgFullName):
+ DecGuidObjectBase.__init__(self, PkgFullName)
+ self._SecName = TAB_PPIS.upper()
+
+ ## GetPpis
+ #
+ # @param Arch: Arch
+ #
+ def GetPpis(self, Arch=TAB_ARCH_COMMON):
+ return self._GetItemByArch(Arch)
+
+ ## GetAllPpis
+ #
+ def GetAllPpis(self):
+ return self._GetAllItems()
+
+## DecProtocolObject
+#
+# Class for protocol section
+#
+# @param DecGuidObjectBase: Dec Guid Object Base
+#
+class DecProtocolObject(DecGuidObjectBase):
+ def __init__(self, PkgFullName):
+ DecGuidObjectBase.__init__(self, PkgFullName)
+ self._SecName = TAB_PROTOCOLS.upper()
+
+ ## GetProtocols
+ #
+ # @param Arch: Arch
+ #
+ def GetProtocols(self, Arch=TAB_ARCH_COMMON):
+ return self._GetItemByArch(Arch)
+
+ ## GetAllProtocols
+ #
+ def GetAllProtocols(self):
+ return self._GetAllItems()
+
+## DecUserExtensionObject
+#
+# Class for user extension section
+#
+# @param _DecBaseObject: Dec Guid Object Base
+#
+class DecUserExtensionObject(_DecBaseObject):
+ def __init__(self, PkgFullName):
+ _DecBaseObject.__init__(self, PkgFullName)
+ self._SecName = TAB_USER_EXTENSIONS.upper()
+ self.ItemList = []
+
+ ## GetProtocols
+ #
+ # @param Item: Item
+ # @param Scope: Scope
+ #
+ def AddItem(self, Item, Scope):
+ if not Scope:
+ pass
+ if not Item:
+ return
+ self.ItemList.append(Item)
+
+ ## GetAllUserExtensions
+ #
+ def GetAllUserExtensions(self):
+ return self.ItemList
+
+
+## DecUserExtensionItemObject
+# Item for user extension section
+#
+# @param _DecItemBaseObject: Dec Item Base Object
+#
+class DecUserExtensionItemObject(_DecItemBaseObject):
+ def __init__(self):
+ _DecItemBaseObject.__init__(self)
+ self.UserString = ''
+ self.UserId = ''
+ self.IdString = ''
+
+
+
+
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py
new file mode 100644
index 0000000000..3685fedd5c
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfBinaryObject.py
@@ -0,0 +1,621 @@
+## @file
+# This file is used to define class objects of INF file [Binaries] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfBinaryObject
+'''
+
+import os
+
+from copy import deepcopy
+from Library import DataType as DT
+from Library import GlobalData
+import Logger.Log as Logger
+from Logger import ToolError
+from Logger import StringTable as ST
+from Library.Misc import Sdict
+
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+from Object.Parser.InfCommonObject import CurrentLine
+from Library.Misc import ConvPathFromAbsToRel
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+from Library.Misc import ValidFile
+from Library.ParserValidate import IsValidPath
+
+
+class InfBianryItem():
+ def __init__(self):
+ self.FileName = ''
+ self.Target = ''
+ self.FeatureFlagExp = ''
+ self.HelpString = ''
+ self.Type = ''
+ self.SupArchList = []
+
+ def SetFileName(self, FileName):
+ self.FileName = FileName
+ def GetFileName(self):
+ return self.FileName
+
+ def SetTarget(self, Target):
+ self.Target = Target
+ def GetTarget(self):
+ return self.Target
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+ def SetType(self, Type):
+ self.Type = Type
+ def GetType(self):
+ return self.Type
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+class InfBianryVerItem(InfBianryItem, CurrentLine):
+ def __init__(self):
+ InfBianryItem.__init__(self)
+ CurrentLine.__init__(self)
+ self.VerTypeName = ''
+
+ def SetVerTypeName(self, VerTypeName):
+ self.VerTypeName = VerTypeName
+ def GetVerTypeName(self):
+ return self.VerTypeName
+
+class InfBianryUiItem(InfBianryItem, CurrentLine):
+ def __init__(self):
+ InfBianryItem.__init__(self)
+ CurrentLine.__init__(self)
+ self.UiTypeName = ''
+
+ def SetUiTypeName(self, UiTypeName):
+ self.UiTypeName = UiTypeName
+ def GetVerTypeName(self):
+ return self.UiTypeName
+
+class InfBianryCommonItem(InfBianryItem, CurrentLine):
+ def __init__(self):
+ self.CommonType = ''
+ self.TagName = ''
+ self.Family = ''
+ InfBianryItem.__init__(self)
+ CurrentLine.__init__(self)
+
+ def SetCommonType(self, CommonType):
+ self.CommonType = CommonType
+ def GetCommonType(self):
+ return self.CommonType
+
+ def SetTagName(self, TagName):
+ self.TagName = TagName
+ def GetTagName(self):
+ return self.TagName
+
+ def SetFamily(self, Family):
+ self.Family = Family
+ def GetFamily(self):
+ return self.Family
+
+##
+#
+#
+#
+class InfBinariesObject(InfSectionCommonDef):
+ def __init__(self):
+ self.Binaries = Sdict()
+ #
+ # Macro defined in this section should be only used in this section.
+ #
+ self.Macros = {}
+ InfSectionCommonDef.__init__(self)
+
+ ## CheckVer
+ #
+ #
+ def CheckVer(self, Ver, __SupArchList):
+ #
+ # Check Ver
+ #
+ for VerItem in Ver:
+ IsValidFileFlag = False
+ VerContent = VerItem[0]
+ VerComment = VerItem[1]
+ VerCurrentLine = VerItem[2]
+ GlobalData.gINF_CURRENT_LINE = VerCurrentLine
+ InfBianryVerItemObj = None
+ #
+ # Should not less than 2 elements
+ #
+ if len(VerContent) < 2:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (VerContent[0]),
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+ return False
+ if len(VerContent) > 4:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX % (VerContent[0], 4),
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+ return False
+ if len(VerContent) >= 2:
+ #
+ # Create a Ver Object.
+ #
+ InfBianryVerItemObj = InfBianryVerItem()
+
+ if VerContent[0] != DT.BINARY_FILE_TYPE_VER:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_VER_TYPE % DT.BINARY_FILE_TYPE_VER,
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+
+ InfBianryVerItemObj.SetVerTypeName(VerContent[0])
+ InfBianryVerItemObj.SetType(VerContent[0])
+ #
+ # Verify File exist or not
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gINF_MODULE_DIR,
+ VerContent[1])))
+ if not (ValidFile(FullFileName) or ValidFile(VerContent[1])):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST % (VerContent[1]),
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+ #
+ # Validate file exist/format.
+ #
+ if IsValidPath(VerContent[1], GlobalData.gINF_MODULE_DIR):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (VerContent[1]),
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+ return False
+ if IsValidFileFlag:
+ VerContent[0] = ConvPathFromAbsToRel(VerContent[0],
+ GlobalData.gINF_MODULE_DIR)
+ InfBianryVerItemObj.SetFileName(VerContent[1])
+ if len(VerContent) >= 3:
+ #
+ # Add Target information
+ #
+ InfBianryVerItemObj.SetTarget(VerContent[2])
+ if len(VerContent) == 4:
+ if VerContent[3].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+ #
+ # Validate Feature Flag Express
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(VerContent[3].\
+ strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
+ File=VerCurrentLine.GetFileName(),
+ Line=VerCurrentLine.GetLineNo(),
+ ExtraData=VerCurrentLine.GetLineString())
+ InfBianryVerItemObj.SetFeatureFlagExp(VerContent[3])
+
+ InfBianryVerItemObj.SetSupArchList(__SupArchList)
+
+ #
+ # Determine binary file name duplicate. Follow below rule:
+ #
+ # A binary filename must not be duplicated within
+ # a [Binaries] section. A binary filename may appear in
+ # multiple architectural [Binaries] sections. A binary
+ # filename listed in an architectural [Binaries] section
+ # must not be listed in the common architectural
+ # [Binaries] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+ for Item in self.Binaries:
+ if Item.GetFileName() == InfBianryVerItemObj.GetFileName():
+ ItemSupArchList = Item.GetSupArchList()
+ for ItemArch in ItemSupArchList:
+ for VerItemObjArch in __SupArchList:
+ if ItemArch == VerItemObjArch:
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+ #
+ pass
+ if ItemArch.upper() == 'COMMON' or VerItemObjArch.upper() == 'COMMON':
+ #
+ # ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+ #
+ pass
+
+ if InfBianryVerItemObj != None:
+ if self.Binaries.has_key((InfBianryVerItemObj)):
+ BinariesList = self.Binaries[InfBianryVerItemObj]
+ BinariesList.append((InfBianryVerItemObj, VerComment))
+ self.Binaries[InfBianryVerItemObj] = BinariesList
+ else:
+ BinariesList = []
+ BinariesList.append((InfBianryVerItemObj, VerComment))
+ self.Binaries[InfBianryVerItemObj] = BinariesList
+
+ ## ParseCommonBinary
+ #
+ # ParseCommonBinary
+ #
+ def ParseCommonBinary(self, CommonBinary, __SupArchList):
+ #
+ # Check common binary definitions
+ # Type | FileName | Target | Family | TagName | FeatureFlagExp
+ #
+ for Item in CommonBinary:
+ IsValidFileFlag = False
+ ItemContent = Item[0]
+ ItemComment = Item[1]
+ CurrentLineOfItem = Item[2]
+ GlobalData.gINF_CURRENT_LINE = CurrentLineOfItem
+ InfBianryCommonItemObj = None
+ if len(ItemContent) < 2:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (ItemContent[0]),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ return False
+ if len(ItemContent) > 6:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX % (ItemContent[0], 6),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ return False
+ if len(ItemContent) >= 2:
+ #
+ # Create a Common Object.
+ #
+ InfBianryCommonItemObj = InfBianryCommonItem()
+ #
+ # Convert Binary type.
+ #
+ BinaryFileType = ItemContent[0].strip()
+ if BinaryFileType == 'RAW' or BinaryFileType == 'ACPI' or BinaryFileType == 'ASL':
+ BinaryFileType = 'BIN'
+
+ if BinaryFileType not in DT.BINARY_FILE_TYPE_LIST:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_INVALID_FILETYPE % \
+ (DT.BINARY_FILE_TYPE_LIST.__str__()),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+
+ if BinaryFileType == 'SUBTYPE_GUID':
+ BinaryFileType = 'FREEFORM'
+
+ if BinaryFileType == 'LIB' or BinaryFileType == 'UEFI_APP':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_INVALID_FILETYPE % \
+ (DT.BINARY_FILE_TYPE_LIST.__str__()),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+
+ InfBianryCommonItemObj.SetType(BinaryFileType)
+ InfBianryCommonItemObj.SetCommonType(ItemContent[0])
+ #
+ # Verify File exist or not
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gINF_MODULE_DIR,
+ ItemContent[1])))
+ if not (ValidFile(FullFileName) or ValidFile(ItemContent[1])):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST % (ItemContent[1]),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ #
+ # Validate file exist/format.
+ #
+ if IsValidPath(ItemContent[1], GlobalData.gINF_MODULE_DIR):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (ItemContent[1]),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ return False
+ if IsValidFileFlag:
+ ItemContent[0] = ConvPathFromAbsToRel(ItemContent[0], GlobalData.gINF_MODULE_DIR)
+ InfBianryCommonItemObj.SetFileName(ItemContent[1])
+ if len(ItemContent) >= 3:
+ #
+ # Add Target information
+ #
+ InfBianryCommonItemObj.SetTarget(ItemContent[2])
+ if len(ItemContent) >= 4:
+ #
+ # Add Family information
+ #
+ InfBianryCommonItemObj.SetFamily(ItemContent[3])
+ if len(ItemContent) >= 5:
+ #
+ # TagName entries are build system specific. If there
+ # is content in the entry, the tool must exit
+ # gracefully with an error message that indicates build
+ # system specific content cannot be distributed using
+ # the UDP
+ #
+ if ItemContent[4].strip() != '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_TAGNAME_NOT_PERMITTED % (ItemContent[4]),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ if len(ItemContent) == 6:
+ #
+ # Add FeatureFlagExp
+ #
+ if ItemContent[5].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ #
+ # Validate Feature Flag Express
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(ItemContent[5].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
+ File=CurrentLineOfItem.GetFileName(),
+ Line=CurrentLineOfItem.GetLineNo(),
+ ExtraData=CurrentLineOfItem.GetLineString())
+ InfBianryCommonItemObj.SetFeatureFlagExp(ItemContent[5])
+
+ InfBianryCommonItemObj.SetSupArchList(__SupArchList)
+
+ #
+ # Determine binary file name duplicate. Follow below rule:
+ #
+ # A binary filename must not be duplicated within
+ # a [Binaries] section. A binary filename may appear in
+ # multiple architectural [Binaries] sections. A binary
+ # filename listed in an architectural [Binaries] section
+ # must not be listed in the common architectural
+ # [Binaries] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+# for Item in self.Binaries:
+# if Item.GetFileName() == InfBianryCommonItemObj.GetFileName():
+# ItemSupArchList = Item.GetSupArchList()
+# for ItemArch in ItemSupArchList:
+# for ComItemObjArch in __SupArchList:
+# if ItemArch == ComItemObjArch:
+# #
+# # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+# #
+# pass
+#
+# if ItemArch.upper() == 'COMMON' or ComItemObjArch.upper() == 'COMMON':
+# #
+# # ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+# #
+# pass
+
+ if InfBianryCommonItemObj != None:
+ if self.Binaries.has_key((InfBianryCommonItemObj)):
+ BinariesList = self.Binaries[InfBianryCommonItemObj]
+ BinariesList.append((InfBianryCommonItemObj, ItemComment))
+ self.Binaries[InfBianryCommonItemObj] = BinariesList
+ else:
+ BinariesList = []
+ BinariesList.append((InfBianryCommonItemObj, ItemComment))
+ self.Binaries[InfBianryCommonItemObj] = BinariesList
+
+ def SetBinary(self, UiInf=None, Ver=None, CommonBinary=None, ArchList=None):
+
+ __SupArchList = []
+ for ArchItem in ArchList:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+ __SupArchList.append(ArchItem)
+
+ if UiInf != None:
+ if len(UiInf) > 0:
+ #
+ # Check UI
+ #
+ for UiItem in UiInf:
+ IsValidFileFlag = False
+ InfBianryUiItemObj = None
+ UiContent = UiItem[0]
+ UiComment = UiItem[1]
+ UiCurrentLine = UiItem[2]
+ GlobalData.gINF_CURRENT_LINE = deepcopy(UiItem[2])
+ #
+ # Should not less than 2 elements
+ #
+ if len(UiContent) < 2:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID % (UiContent[0]),
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ return False
+
+ if len(UiContent) > 4:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FORMAT_INVALID_MAX % (UiContent[0], 4),
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ return False
+ if len(UiContent) >= 2:
+ #
+ # Create an Ui Object.
+ #
+ InfBianryUiItemObj = InfBianryUiItem()
+ if UiContent[0] != 'UI':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_VER_TYPE % ('UI'),
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ InfBianryUiItemObj.SetUiTypeName(UiContent[0])
+ InfBianryUiItemObj.SetType(UiContent[0])
+ #
+ # Verify File exist or not
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gINF_MODULE_DIR,
+ UiContent[1])))
+ if not (ValidFile(FullFileName) or ValidFile(UiContent[1])):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BINARY_ITEM_FILE_NOT_EXIST % (UiContent[1]),
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ #
+ # Validate file exist/format.
+ #
+ if IsValidPath(UiContent[1], GlobalData.gINF_MODULE_DIR):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID % (UiContent[1]),
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ return False
+ if IsValidFileFlag:
+ UiContent[0] = ConvPathFromAbsToRel(UiContent[0], GlobalData.gINF_MODULE_DIR)
+ InfBianryUiItemObj.SetFileName(UiContent[1])
+ if len(UiContent) >= 3:
+ #
+ # Add Target information
+ #
+ InfBianryUiItemObj.SetTarget(UiContent[2])
+ if len(UiContent) == 4:
+ if UiContent[3].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ #
+ # Validate Feature Flag Express
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(UiContent[3].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
+ File=UiCurrentLine.GetFileName(),
+ Line=UiCurrentLine.GetLineNo(),
+ ExtraData=UiCurrentLine.GetLineString())
+ InfBianryUiItemObj.SetFeatureFlagExp(UiContent[3])
+
+ InfBianryUiItemObj.SetSupArchList(__SupArchList)
+
+ #
+ # Determine binary file name duplicate. Follow below rule:
+ #
+ # A binary filename must not be duplicated within
+ # a [Binaries] section. A binary filename may appear in
+ # multiple architectural [Binaries] sections. A binary
+ # filename listed in an architectural [Binaries] section
+ # must not be listed in the common architectural
+ # [Binaries] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+# for Item in self.Binaries:
+# if Item.GetFileName() == InfBianryUiItemObj.GetFileName():
+# ItemSupArchList = Item.GetSupArchList()
+# for ItemArch in ItemSupArchList:
+# for UiItemObjArch in __SupArchList:
+# if ItemArch == UiItemObjArch:
+# #
+# # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+# #
+# pass
+# if ItemArch.upper() == 'COMMON' or UiItemObjArch.upper() == 'COMMON':
+# #
+# # ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+# #
+# pass
+
+ if InfBianryUiItemObj != None:
+ if self.Binaries.has_key((InfBianryUiItemObj)):
+ BinariesList = self.Binaries[InfBianryUiItemObj]
+ BinariesList.append((InfBianryUiItemObj, UiComment))
+ self.Binaries[InfBianryUiItemObj] = BinariesList
+ else:
+ BinariesList = []
+ BinariesList.append((InfBianryUiItemObj, UiComment))
+ self.Binaries[InfBianryUiItemObj] = BinariesList
+ if Ver != None and len(Ver) > 0:
+ self.CheckVer(Ver, __SupArchList)
+ if CommonBinary and len(CommonBinary) > 0:
+ self.ParseCommonBinary(CommonBinary, __SupArchList)
+
+ return True
+
+ def GetBinary(self):
+ return self.Binaries
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py
new file mode 100644
index 0000000000..5549525a6c
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfBuildOptionObject.py
@@ -0,0 +1,93 @@
+## @file
+# This file is used to define class objects of INF file [BuildOptions] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfBuildOptionObject
+'''
+
+from Library import GlobalData
+
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+
+class InfBuildOptionItem():
+ def __init__(self):
+ self.Content = ''
+ self.SupArchList = []
+ self.AsBuildList = []
+
+ def SetContent(self, Content):
+ self.Content = Content
+ def GetContent(self):
+ return self.Content
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ #
+ # AsBuild Information
+ #
+ def SetAsBuildList(self, AsBuildList):
+ self.AsBuildList = AsBuildList
+ def GetAsBuildList(self):
+ return self.AsBuildList
+
+
+## INF BuildOption section
+# Macro define is not permitted for this section.
+#
+#
+class InfBuildOptionsObject(InfSectionCommonDef):
+ def __init__(self):
+ self.BuildOptions = []
+ InfSectionCommonDef.__init__(self)
+ ## SetBuildOptions function
+ #
+ # For BuildOptionName, need to validate it's format
+ # For BuildOptionValue, just ignore it.
+ #
+ # @param Arch Indicated which arch of build options belong to.
+ # @param BuildOptCont A list contain BuildOption related information.
+ # The element in the list contain 3 members.
+ # BuildOptionName, BuildOptionValue and IsReplace
+ # flag.
+ #
+ # @return True Build options set/validate successfully
+ # @return False Build options set/validate failed
+ #
+ def SetBuildOptions(self, BuildOptCont, ArchList = None, SectionContent = ''):
+
+ if not GlobalData.gIS_BINARY_INF:
+
+ if SectionContent.strip() != '':
+ InfBuildOptionItemObj = InfBuildOptionItem()
+ InfBuildOptionItemObj.SetContent(SectionContent)
+ InfBuildOptionItemObj.SetSupArchList(ArchList)
+
+ self.BuildOptions.append(InfBuildOptionItemObj)
+ else:
+ #
+ # For AsBuild INF file
+ #
+ if len(BuildOptCont) >= 1:
+ InfBuildOptionItemObj = InfBuildOptionItem()
+ InfBuildOptionItemObj.SetAsBuildList(BuildOptCont)
+ self.BuildOptions.append(InfBuildOptionItemObj)
+
+
+ return True
+
+ def GetBuildOptions(self):
+ return self.BuildOptions \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfCommonObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfCommonObject.py
new file mode 100644
index 0000000000..217b0941da
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfCommonObject.py
@@ -0,0 +1,162 @@
+## @file
+# This file is used to define common class objects for INF file.
+# It will consumed by InfParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfCommonObject
+'''
+
+## InfLineCommentObject
+#
+# Comment Object for any line in the INF file
+#
+# #
+# # HeaderComment
+# #
+# Line # TailComment
+#
+class InfLineCommentObject():
+ def __init__(self):
+ self.HeaderComments = ''
+ self.TailComments = ''
+
+ def SetHeaderComments(self, HeaderComments):
+ self.HeaderComments = HeaderComments
+
+ def GetHeaderComments(self):
+ return self.HeaderComments
+
+ def SetTailComments(self, TailComments):
+ self.TailComments = TailComments
+
+ def GetTailComments(self):
+ return self.TailComments
+
+## CurrentLine
+#
+class CurrentLine():
+ def __init__(self):
+ self.LineNo = ''
+ self.LineString = ''
+ self.FileName = ''
+
+ ## SetLineNo
+ #
+ # @param LineNo: LineNo
+ #
+ def SetLineNo(self, LineNo):
+ self.LineNo = LineNo
+
+ ## GetLineNo
+ #
+ def GetLineNo(self):
+ return self.LineNo
+
+ ## SetLineString
+ #
+ # @param LineString: Line String content
+ #
+ def SetLineString(self, LineString):
+ self.LineString = LineString
+
+ ## GetLineString
+ #
+ def GetLineString(self):
+ return self.LineString
+
+ ## SetFileName
+ #
+ # @param FileName: File Name
+ #
+ def SetFileName(self, FileName):
+ self.FileName = FileName
+
+ ## GetFileName
+ #
+ def GetFileName(self):
+ return self.FileName
+
+##
+# Inf Section common data
+#
+class InfSectionCommonDef():
+ def __init__(self):
+ #
+ # #
+ # # HeaderComments at here
+ # #
+ # [xxSection] TailComments at here
+ # data
+ #
+ self.HeaderComments = ''
+ self.TailComments = ''
+ #
+ # The support arch list of this section
+ #
+ self.SupArchList = []
+
+ #
+ # Store all section content
+ # Key is supported Arch
+ #
+ self.AllContent = {}
+
+ ## SetHeaderComments
+ #
+ # @param HeaderComments: HeaderComments
+ #
+ def SetHeaderComments(self, HeaderComments):
+ self.HeaderComments = HeaderComments
+
+ ## GetHeaderComments
+ #
+ def GetHeaderComments(self):
+ return self.HeaderComments
+
+ ## SetTailComments
+ #
+ # @param TailComments: TailComments
+ #
+ def SetTailComments(self, TailComments):
+ self.TailComments = TailComments
+
+ ## GetTailComments
+ #
+ def GetTailComments(self):
+ return self.TailComments
+
+ ## SetSupArchList
+ #
+ # @param Arch: Arch
+ #
+ def SetSupArchList(self, Arch):
+ if Arch not in self.SupArchList:
+ self.SupArchList.append(Arch)
+
+ ## GetSupArchList
+ #
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ ## SetAllContent
+ #
+ # @param ArchList: ArchList
+ # @param Content: Content
+ #
+ def SetAllContent(self, Content):
+ self.AllContent = Content
+
+ ## GetAllContent
+ #
+ def GetAllContent(self):
+ return self.AllContent
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py
new file mode 100644
index 0000000000..d565e65a65
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfDefineCommonObject.py
@@ -0,0 +1,89 @@
+## @file
+# This file is used to define common class objects of [Defines] section for INF file.
+# It will consumed by InfParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfDefineCommonObject
+'''
+
+from Object.Parser.InfCommonObject import InfLineCommentObject
+
+## InfDefineImageExeParamItem
+#
+class InfDefineImageExeParamItem():
+ def __init__(self):
+ self.CName = ''
+ self.FeatureFlagExp = ''
+ self.Comments = InfLineCommentObject()
+
+ def SetCName(self, CName):
+ self.CName = CName
+ def GetCName(self):
+ return self.CName
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+## InfDefineEntryPointItem
+#
+class InfDefineEntryPointItem(InfDefineImageExeParamItem):
+ def __init__(self):
+ InfDefineImageExeParamItem.__init__(self)
+
+## InfDefineUnloadImageItem
+#
+class InfDefineUnloadImageItem(InfDefineImageExeParamItem):
+ def __init__(self):
+ InfDefineImageExeParamItem.__init__(self)
+
+## InfDefineConstructorItem
+#
+class InfDefineConstructorItem(InfDefineImageExeParamItem):
+ def __init__(self):
+ InfDefineImageExeParamItem.__init__(self)
+ self.SupModList = []
+
+ def SetSupModList(self, SupModList):
+ self.SupModList = SupModList
+ def GetSupModList(self):
+ return self.SupModList
+
+## InfDefineDestructorItem
+#
+class InfDefineDestructorItem(InfDefineImageExeParamItem):
+ def __init__(self):
+ InfDefineImageExeParamItem.__init__(self)
+ self.SupModList = []
+
+ def SetSupModList(self, SupModList):
+ self.SupModList = SupModList
+ def GetSupModList(self):
+ return self.SupModList
+
+## InfDefineLibraryItem
+#
+class InfDefineLibraryItem():
+ def __init__(self):
+ self.LibraryName = ''
+ self.Types = []
+ self.Comments = InfLineCommentObject()
+
+ def SetLibraryName(self, Name):
+ self.LibraryName = Name
+ def GetLibraryName(self):
+ return self.LibraryName
+ def SetTypes(self, Type):
+ self.Types = Type
+ def GetTypes(self):
+ return self.Types \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py
new file mode 100644
index 0000000000..7645ba202b
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfDefineObject.py
@@ -0,0 +1,994 @@
+## @file
+# This file is used to define class objects of [Defines] section for INF file.
+# It will consumed by InfParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfDefineObject
+'''
+
+import os
+import re
+
+from Logger import StringTable as ST
+from Logger import ToolError
+from Library import GlobalData
+from Library import DataType as DT
+from Library.String import GetSplitValueList
+from Library.Misc import CheckGuidRegFormat
+from Library.Misc import Sdict
+from Library.Misc import ConvPathFromAbsToRel
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+from Library.ParserValidate import IsValidWord
+from Library.ParserValidate import IsValidInfMoudleType
+from Library.ParserValidate import IsValidHex
+from Library.ParserValidate import IsValidHexVersion
+from Library.ParserValidate import IsValidDecVersion
+from Library.ParserValidate import IsValidCVariableName
+from Library.ParserValidate import IsValidBoolType
+from Library.ParserValidate import IsValidPath
+from Library.ParserValidate import IsValidFamily
+from Library.ParserValidate import IsValidIdentifier
+from Library.ParserValidate import IsValidDecVersionVal
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Object.Parser.InfCommonObject import CurrentLine
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+from Object.Parser.InfMisc import ErrorInInf
+from Object.Parser.InfDefineCommonObject import InfDefineLibraryItem
+from Object.Parser.InfDefineCommonObject import InfDefineEntryPointItem
+from Object.Parser.InfDefineCommonObject import InfDefineUnloadImageItem
+from Object.Parser.InfDefineCommonObject import InfDefineConstructorItem
+from Object.Parser.InfDefineCommonObject import InfDefineDestructorItem
+
+class InfDefSectionOptionRomInfo():
+ def __init__(self):
+ self.PciVendorId = None
+ self.PciDeviceId = None
+ self.PciClassCode = None
+ self.PciRevision = None
+ self.PciCompress = None
+ self.CurrentLine = ['', -1, '']
+ def SetPciVendorId(self, PciVendorId, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PciVendorId != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_VENDOR_ID),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The PciVendorId should be hex string.
+ #
+ if (IsValidHex(PciVendorId)):
+ self.PciVendorId = InfDefMember()
+ self.PciVendorId.SetValue(PciVendorId)
+ self.PciVendorId.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciVendorId),
+ LineInfo=self.CurrentLine)
+ return False
+
+ def GetPciVendorId(self):
+ return self.PciVendorId
+
+ def SetPciDeviceId(self, PciDeviceId, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PciDeviceId != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_DEVICE_ID),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The PciDeviceId should be hex string.
+ #
+ if (IsValidHex(PciDeviceId)):
+ self.PciDeviceId = InfDefMember()
+ self.PciDeviceId.SetValue(PciDeviceId)
+ self.PciDeviceId.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciDeviceId),
+ LineInfo=self.CurrentLine)
+ return False
+
+ def GetPciDeviceId(self):
+ return self.PciDeviceId
+
+ def SetPciClassCode(self, PciClassCode, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PciClassCode != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_CLASS_CODE),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The PciClassCode should be 4 bytes hex string.
+ #
+ if (IsValidHex(PciClassCode)):
+ self.PciClassCode = InfDefMember()
+ self.PciClassCode.SetValue(PciClassCode)
+ self.PciClassCode.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
+ (PciClassCode),
+ LineInfo=self.CurrentLine)
+ return False
+
+ def GetPciClassCode(self):
+ return self.PciClassCode
+
+ def SetPciRevision(self, PciRevision, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PciRevision != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_REVISION),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The PciRevision should be 4 bytes hex string.
+ #
+ if (IsValidHex(PciRevision)):
+ self.PciRevision = InfDefMember()
+ self.PciRevision.SetValue(PciRevision)
+ self.PciRevision.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciRevision),
+ LineInfo=self.CurrentLine)
+ return False
+
+ def GetPciRevision(self):
+ return self.PciRevision
+
+ def SetPciCompress(self, PciCompress, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PciCompress != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_PCI_COMPRESS),
+ LineInfo=self.CurrentLine)
+ return False
+
+ #
+ # The PciCompress should be 'TRUE' or 'FALSE'.
+ #
+ if (PciCompress == 'TRUE' or PciCompress == 'FALSE'):
+ self.PciCompress = InfDefMember()
+ self.PciCompress.SetValue(PciCompress)
+ self.PciCompress.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PciCompress),
+ LineInfo=self.CurrentLine)
+ return False
+ def GetPciCompress(self):
+ return self.PciCompress
+##
+# INF [Define] section Object
+#
+class InfDefSection(InfDefSectionOptionRomInfo):
+ def __init__(self):
+ self.BaseName = None
+ self.FileGuid = None
+ self.ModuleType = None
+ self.InfVersion = None
+ self.EdkReleaseVersion = None
+ self.UefiSpecificationVersion = None
+ self.PiSpecificationVersion = None
+ self.LibraryClass = []
+ self.Package = None
+ self.VersionString = None
+ self.PcdIsDriver = None
+ self.EntryPoint = []
+ self.UnloadImages = []
+ self.Constructor = []
+ self.Destructor = []
+ self.Shadow = None
+ self.CustomMakefile = []
+ self.Specification = []
+ self.UefiHiiResourceSection = None
+ self.DpxSource = []
+ self.CurrentLine = ['', -1, '']
+ InfDefSectionOptionRomInfo.__init__(self)
+
+ ## SetHeadComment
+ #
+ # @param BaseName: BaseName
+ #
+ def SetBaseName(self, BaseName, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.BaseName != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_BASE_NAME),
+ LineInfo=self.CurrentLine)
+ return False
+
+ if not (BaseName == '' or BaseName == None):
+ if IsValidWord(BaseName) and not BaseName.startswith("_"):
+ self.BaseName = InfDefMember()
+ self.BaseName.SetValue(BaseName)
+ self.BaseName.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_NAME_INVALID%(BaseName),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetBaseName
+ #
+ def GetBaseName(self):
+ return self.BaseName
+
+ ## SetFileGuid
+ #
+ # @param FileGuid: FileGuid
+ #
+ def SetFileGuid(self, FileGuid, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.FileGuid != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_FILE_GUID),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # Do verification of GUID content/format
+ #
+ if (CheckGuidRegFormat(FileGuid)):
+ self.FileGuid = InfDefMember()
+ self.FileGuid.SetValue(FileGuid)
+ self.FileGuid.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_GUID_INVALID%(FileGuid),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetFileGuid
+ #
+ def GetFileGuid(self):
+ return self.FileGuid
+
+ ## SetModuleType
+ #
+ # @param ModuleType: ModuleType
+ #
+ def SetModuleType(self, ModuleType, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.ModuleType != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_MODULE_TYPE),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # Valid Module Type or not
+ #
+ if (IsValidInfMoudleType(ModuleType)):
+ self.ModuleType = InfDefMember()
+ self.ModuleType.SetValue(ModuleType)
+ self.ModuleType.CurrentLine = CurrentLine()
+ self.ModuleType.CurrentLine.SetLineNo(self.CurrentLine[1])
+ self.ModuleType.CurrentLine.SetLineString(self.CurrentLine[2])
+ self.ModuleType.CurrentLine.SetFileName(self.CurrentLine[0])
+ self.ModuleType.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%\
+ (ModuleType),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetModuleType
+ #
+ def GetModuleType(self):
+ return self.ModuleType
+
+ ## SetInfVersion
+ #
+ # @param InfVersion: InfVersion
+ #
+ def SetInfVersion(self, InfVersion, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.InfVersion != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_INF_VERSION),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The InfVersion should be 4 bytes hex string.
+ #
+ if (IsValidHex(InfVersion)):
+ if (InfVersion < '0x00010005'):
+ ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
+ ErrorCode=ToolError.EDK1_INF_ERROR,
+ LineInfo=self.CurrentLine)
+
+ self.InfVersion = InfDefMember()
+ self.InfVersion.SetValue(InfVersion)
+ self.InfVersion.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(InfVersion),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetInfVersion
+ #
+ def GetInfVersion(self):
+ return self.InfVersion
+
+ ## SetEdkReleaseVersion
+ #
+ # @param EdkReleaseVersion: EdkReleaseVersion
+ #
+ def SetEdkReleaseVersion(self, EdkReleaseVersion, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.EdkReleaseVersion != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The EdkReleaseVersion should be 4 bytes hex string.
+ #
+ if IsValidHexVersion(EdkReleaseVersion) or \
+ IsValidDecVersionVal(EdkReleaseVersion):
+ self.EdkReleaseVersion = InfDefMember()
+ self.EdkReleaseVersion.SetValue(EdkReleaseVersion)
+ self.EdkReleaseVersion.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
+ %(EdkReleaseVersion),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetEdkReleaseVersion
+ #
+ def GetEdkReleaseVersion(self):
+ return self.EdkReleaseVersion
+
+ ## SetUefiSpecificationVersion
+ #
+ # @param UefiSpecificationVersion: UefiSpecificationVersion
+ #
+ def SetUefiSpecificationVersion(self, UefiSpecificationVersion, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.UefiSpecificationVersion != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The EdkReleaseVersion should be 4 bytes hex string.
+ #
+ if IsValidHexVersion(UefiSpecificationVersion) or \
+ IsValidDecVersionVal(UefiSpecificationVersion):
+ self.UefiSpecificationVersion = InfDefMember()
+ self.UefiSpecificationVersion.SetValue(UefiSpecificationVersion)
+ self.UefiSpecificationVersion.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
+ %(UefiSpecificationVersion),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetUefiSpecificationVersion
+ #
+ def GetUefiSpecificationVersion(self):
+ return self.UefiSpecificationVersion
+
+ ## SetPiSpecificationVersion
+ #
+ # @param PiSpecificationVersion: PiSpecificationVersion
+ #
+ def SetPiSpecificationVersion(self, PiSpecificationVersion, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PiSpecificationVersion != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The EdkReleaseVersion should be 4 bytes hex string.
+ #
+ if IsValidHexVersion(PiSpecificationVersion) or \
+ IsValidDecVersionVal(PiSpecificationVersion):
+ self.PiSpecificationVersion = InfDefMember()
+ self.PiSpecificationVersion.SetValue(PiSpecificationVersion)
+ self.PiSpecificationVersion.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
+ %(PiSpecificationVersion),
+ LineInfo=self.CurrentLine)
+ return False
+
+ ## GetPiSpecificationVersion
+ #
+ def GetPiSpecificationVersion(self):
+ return self.PiSpecificationVersion
+
+ ## SetLibraryClass
+ #
+ # @param LibraryClass: LibraryClass
+ #
+ def SetLibraryClass(self, LibraryClass, Comments):
+ ValueList = GetSplitValueList(LibraryClass)
+ Name = ValueList[0]
+ if IsValidWord(Name):
+ InfDefineLibraryItemObj = InfDefineLibraryItem()
+ InfDefineLibraryItemObj.SetLibraryName(Name)
+ InfDefineLibraryItemObj.Comments = Comments
+ if len(ValueList) == 2:
+ Type = ValueList[1]
+ TypeList = GetSplitValueList(Type, ' ')
+ for Item in TypeList:
+ if Item not in DT.MODULE_LIST:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Item),
+ LineInfo=self.CurrentLine)
+ return False
+ InfDefineLibraryItemObj.SetTypes(TypeList)
+ self.LibraryClass.append(InfDefineLibraryItemObj)
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name),
+ LineInfo=self.CurrentLine)
+ return False
+
+ return True
+
+ def GetLibraryClass(self):
+ return self.LibraryClass
+
+ def SetVersionString(self, VersionString, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.VersionString != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_VERSION_STRING),
+ LineInfo=self.CurrentLine)
+ return False
+ if not IsValidDecVersion(VersionString):
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID\
+ %(VersionString),
+ LineInfo=self.CurrentLine)
+ self.VersionString = InfDefMember()
+ self.VersionString.SetValue(VersionString)
+ self.VersionString.Comments = Comments
+ return True
+
+
+ def GetVersionString(self):
+ return self.VersionString
+
+ def SetPcdIsDriver(self, PcdIsDriver, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.PcdIsDriver != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND\
+ %(DT.TAB_INF_DEFINES_PCD_IS_DRIVER),
+ LineInfo=self.CurrentLine)
+ return False
+ if PcdIsDriver == 'PEI_PCD_DRIVER' or PcdIsDriver == 'DXE_PCD_DRIVER':
+ self.PcdIsDriver = InfDefMember()
+ self.PcdIsDriver.SetValue(PcdIsDriver)
+ self.PcdIsDriver.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(PcdIsDriver),
+ LineInfo=self.CurrentLine)
+ return False
+
+ def GetPcdIsDriver(self):
+ return self.PcdIsDriver
+
+ #
+ # SetEntryPoint
+ #
+ def SetEntryPoint(self, EntryPoint, Comments):
+ #
+ # It can be a list
+ #
+ ValueList = []
+
+ TokenList = GetSplitValueList(EntryPoint, DT.TAB_VALUE_SPLIT)
+ ValueList[0:len(TokenList)] = TokenList
+
+ InfDefineEntryPointItemObj = InfDefineEntryPointItem()
+ if not IsValidCVariableName(ValueList[0]):
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
+ (ValueList[0]),
+ LineInfo=self.CurrentLine)
+ InfDefineEntryPointItemObj.SetCName(ValueList[0])
+ if len(ValueList) == 2:
+ if ValueList[1].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%\
+ (ValueList[1]),
+ LineInfo=self.CurrentLine)
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[1].strip())
+ if not FeatureFlagRtv[0]:
+ ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%\
+ (FeatureFlagRtv[1]),
+ LineInfo=self.CurrentLine)
+
+ InfDefineEntryPointItemObj.SetFeatureFlagExp(ValueList[1])
+ if len(ValueList) > 2:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(EntryPoint),
+ LineInfo=self.CurrentLine)
+
+ InfDefineEntryPointItemObj.Comments = Comments
+ self.EntryPoint.append(InfDefineEntryPointItemObj)
+
+ def GetEntryPoint(self):
+ return self.EntryPoint
+
+ #
+ # SetUnloadImages
+ #
+ def SetUnloadImages(self, UnloadImages, Comments):
+ #
+ # It can be a list
+ #
+ ValueList = []
+
+ TokenList = GetSplitValueList(UnloadImages, DT.TAB_VALUE_SPLIT)
+ ValueList[0:len(TokenList)] = TokenList
+
+ InfDefineUnloadImageItemObj = InfDefineUnloadImageItem()
+ if not IsValidCVariableName(ValueList[0]):
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
+ LineInfo=self.CurrentLine)
+ InfDefineUnloadImageItemObj.SetCName(ValueList[0])
+ if len(ValueList) == 2:
+ if ValueList[1].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
+ LineInfo=self.CurrentLine)
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[1].strip())
+ if not FeatureFlagRtv[0]:
+ ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ LineInfo=self.CurrentLine)
+ InfDefineUnloadImageItemObj.SetFeatureFlagExp(ValueList[1])
+
+ if len(ValueList) > 2:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UnloadImages),
+ LineInfo=self.CurrentLine)
+
+ InfDefineUnloadImageItemObj.Comments = Comments
+ self.UnloadImages.append(InfDefineUnloadImageItemObj)
+
+ def GetUnloadImages(self):
+ return self.UnloadImages
+
+ #
+ # SetConstructor
+ #
+ def SetConstructor(self, Constructor, Comments):
+ #
+ # It can be a list
+ #
+ ValueList = []
+
+ TokenList = GetSplitValueList(Constructor, DT.TAB_VALUE_SPLIT)
+ ValueList[0:len(TokenList)] = TokenList
+
+ InfDefineConstructorItemObj = InfDefineConstructorItem()
+ if not IsValidCVariableName(ValueList[0]):
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
+ LineInfo=self.CurrentLine)
+ InfDefineConstructorItemObj.SetCName(ValueList[0])
+ if len(ValueList) >= 2:
+ ModList = GetSplitValueList(ValueList[1], ' ')
+ if ValueList[1].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
+ LineInfo=self.CurrentLine)
+ for ModItem in ModList:
+ if ModItem not in DT.MODULE_LIST:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%(ModItem),
+ LineInfo=self.CurrentLine)
+ InfDefineConstructorItemObj.SetSupModList(ModList)
+ if len(ValueList) == 3:
+ if ValueList[2].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[2]),
+ LineInfo=self.CurrentLine)
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[2].strip())
+ if not FeatureFlagRtv[0]:
+ ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[2]),
+ LineInfo=self.CurrentLine)
+ InfDefineConstructorItemObj.SetFeatureFlagExp(ValueList[2])
+
+ if len(ValueList) > 3:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Constructor),
+ LineInfo=self.CurrentLine)
+
+ InfDefineConstructorItemObj.Comments = Comments
+ self.Constructor.append(InfDefineConstructorItemObj)
+
+ def GetConstructor(self):
+ return self.Constructor
+
+ #
+ # SetDestructor
+ #
+ def SetDestructor(self, Destructor, Comments):
+ #
+ # It can be a list and only 1 set to TRUE
+ #
+ ValueList = []
+
+ TokenList = GetSplitValueList(Destructor, DT.TAB_VALUE_SPLIT)
+ ValueList[0:len(TokenList)] = TokenList
+
+ InfDefineDestructorItemObj = InfDefineDestructorItem()
+ if not IsValidCVariableName(ValueList[0]):
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[0]),
+ LineInfo=self.CurrentLine)
+ InfDefineDestructorItemObj.SetCName(ValueList[0])
+ if len(ValueList) >= 2:
+ ModList = GetSplitValueList(ValueList[1].strip(), ' ')
+ if ValueList[1].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[1]),
+ LineInfo=self.CurrentLine)
+ for ModItem in ModList:
+ if ModItem not in DT.MODULE_LIST:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID%(ModItem),
+ LineInfo=self.CurrentLine)
+ InfDefineDestructorItemObj.SetSupModList(ModList)
+ if len(ValueList) == 3:
+ if ValueList[2].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ValueList[2]),
+ LineInfo=self.CurrentLine)
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(ValueList[2].strip())
+ if not FeatureFlagRtv[0]:
+ ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ LineInfo=self.CurrentLine)
+ InfDefineDestructorItemObj.SetFeatureFlagExp(ValueList[2])
+
+ if len(ValueList) > 3:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Destructor),
+ LineInfo=self.CurrentLine)
+
+ InfDefineDestructorItemObj.Comments = Comments
+ self.Destructor.append(InfDefineDestructorItemObj)
+
+ def GetDestructor(self):
+ return self.Destructor
+
+ def SetShadow(self, Shadow, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.Shadow != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND%(DT.TAB_INF_DEFINES_SHADOW),
+ LineInfo=self.CurrentLine)
+ return False
+ if (IsValidBoolType(Shadow)):
+ self.Shadow = InfDefMember()
+ self.Shadow.SetValue(Shadow)
+ self.Shadow.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Shadow),
+ LineInfo=self.CurrentLine)
+ return False
+ def GetShadow(self):
+ return self.Shadow
+
+
+
+ #
+ # <Family> ::= {"MSFT"} {"GCC"}
+ # <CustomMake> ::= [<Family> "|"] <Filename>
+ #
+ def SetCustomMakefile(self, CustomMakefile, Comments):
+ if not (CustomMakefile == '' or CustomMakefile == None):
+ ValueList = GetSplitValueList(CustomMakefile)
+ if len(ValueList) == 1:
+ FileName = ValueList[0]
+ Family = ''
+ else:
+ Family = ValueList[0]
+ FileName = ValueList[1]
+ Family = Family.strip()
+ if Family != '':
+ if not IsValidFamily(Family):
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Family),
+ LineInfo=self.CurrentLine)
+ return False
+ #
+ # The MakefileName specified file should exist
+ #
+ IsValidFileFlag = False
+ ModulePath = os.path.split(self.CurrentLine[0])[0]
+ if IsValidPath(FileName, ModulePath):
+ IsValidFileFlag = True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(FileName),
+ LineInfo=self.CurrentLine)
+ return False
+ if IsValidFileFlag:
+ FileName = ConvPathFromAbsToRel(FileName, GlobalData.gINF_MODULE_DIR)
+ self.CustomMakefile.append((Family, FileName, Comments))
+ IsValidFileFlag = False
+ return True
+ else:
+ return False
+
+ def GetCustomMakefile(self):
+ return self.CustomMakefile
+
+ #
+ # ["SPEC" <Spec> <EOL>]*{0,}
+ # <Spec> ::= <Word> "=" <VersionVal>
+ # <VersionVal> ::= {<HexVersion>] {<DecVersion>}
+ # <HexNumber> ::= "0x" [<HexDigit>]{1,}
+ # <DecVersion> ::= (0-9){1,} ["." (0-9){1,2}]
+ #
+ def SetSpecification(self, Specification, Comments):
+ #
+ # Valid the value of Specification
+ #
+ __ValueList = []
+ TokenList = GetSplitValueList(Specification, DT.TAB_EQUAL_SPLIT, 1)
+ __ValueList[0:len(TokenList)] = TokenList
+ if len(__ValueList) != 2:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_NAME + ' Or ' + ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
+ LineInfo=self.CurrentLine)
+ Name = __ValueList[0].strip()
+ Version = __ValueList[1].strip()
+ if IsValidIdentifier(Name):
+ if IsValidDecVersion(Version):
+ self.Specification.append((Name, Version, Comments))
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Version),
+ LineInfo=self.CurrentLine)
+ return False
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(Name),
+ LineInfo=self.CurrentLine)
+ return False
+
+ return True
+
+ def GetSpecification(self):
+ return self.Specification
+
+ #
+ # [<UefiHiiResource> <EOL>]{0,1}
+ # <UefiHiiResource> ::= "UEFI_HII_RESOURCE_SECTION" "=" <BoolType>
+ #
+ def SetUefiHiiResourceSection(self, UefiHiiResourceSection, Comments):
+ #
+ # Value has been set before.
+ #
+ if self.UefiHiiResourceSection != None:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_MORE_THAN_ONE_FOUND
+ %(DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION),
+ LineInfo=self.CurrentLine)
+ return False
+ if not (UefiHiiResourceSection == '' or UefiHiiResourceSection == None):
+ if (IsValidBoolType(UefiHiiResourceSection)):
+ self.UefiHiiResourceSection = InfDefMember()
+ self.UefiHiiResourceSection.SetValue(UefiHiiResourceSection)
+ self.UefiHiiResourceSection.Comments = Comments
+ return True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(UefiHiiResourceSection),
+ LineInfo=self.CurrentLine)
+ return False
+ else:
+ return False
+
+ def GetUefiHiiResourceSection(self):
+ return self.UefiHiiResourceSection
+
+ def SetDpxSource(self, DpxSource, Comments):
+ #
+ # The MakefileName specified file should exist
+ #
+ IsValidFileFlag = False
+ ModulePath = os.path.split(self.CurrentLine[0])[0]
+ if IsValidPath(DpxSource, ModulePath):
+ IsValidFileFlag = True
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(DpxSource),
+ LineInfo=self.CurrentLine)
+ return False
+ if IsValidFileFlag:
+ DpxSource = ConvPathFromAbsToRel(DpxSource,
+ GlobalData.gINF_MODULE_DIR)
+ self.DpxSource.append((DpxSource, Comments))
+ IsValidFileFlag = False
+ return True
+
+ def GetDpxSource(self):
+ return self.DpxSource
+
+gFUNCTION_MAPPING_FOR_DEFINE_SECTION = {
+ #
+ # Required Fields
+ #
+ DT.TAB_INF_DEFINES_BASE_NAME : InfDefSection.SetBaseName,
+ DT.TAB_INF_DEFINES_FILE_GUID : InfDefSection.SetFileGuid,
+ DT.TAB_INF_DEFINES_MODULE_TYPE : InfDefSection.SetModuleType,
+ #
+ # Required by EDKII style INF file
+ #
+ DT.TAB_INF_DEFINES_INF_VERSION : InfDefSection.SetInfVersion,
+ #
+ # Optional Fields
+ #
+ DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION : InfDefSection.SetEdkReleaseVersion,
+ DT.TAB_INF_DEFINES_UEFI_SPECIFICATION_VERSION : InfDefSection.SetUefiSpecificationVersion,
+ DT.TAB_INF_DEFINES_PI_SPECIFICATION_VERSION : InfDefSection.SetPiSpecificationVersion,
+ DT.TAB_INF_DEFINES_LIBRARY_CLASS : InfDefSection.SetLibraryClass,
+ DT.TAB_INF_DEFINES_VERSION_STRING : InfDefSection.SetVersionString,
+ DT.TAB_INF_DEFINES_PCD_IS_DRIVER : InfDefSection.SetPcdIsDriver,
+ DT.TAB_INF_DEFINES_ENTRY_POINT : InfDefSection.SetEntryPoint,
+ DT.TAB_INF_DEFINES_UNLOAD_IMAGE : InfDefSection.SetUnloadImages,
+ DT.TAB_INF_DEFINES_CONSTRUCTOR : InfDefSection.SetConstructor,
+ DT.TAB_INF_DEFINES_DESTRUCTOR : InfDefSection.SetDestructor,
+ DT.TAB_INF_DEFINES_SHADOW : InfDefSection.SetShadow,
+ DT.TAB_INF_DEFINES_PCI_VENDOR_ID : InfDefSection.SetPciVendorId,
+ DT.TAB_INF_DEFINES_PCI_DEVICE_ID : InfDefSection.SetPciDeviceId,
+ DT.TAB_INF_DEFINES_PCI_CLASS_CODE : InfDefSection.SetPciClassCode,
+ DT.TAB_INF_DEFINES_PCI_REVISION : InfDefSection.SetPciRevision,
+ DT.TAB_INF_DEFINES_PCI_COMPRESS : InfDefSection.SetPciCompress,
+ DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE : InfDefSection.SetCustomMakefile,
+ DT.TAB_INF_DEFINES_SPEC : InfDefSection.SetSpecification,
+ DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION : InfDefSection.SetUefiHiiResourceSection,
+ DT.TAB_INF_DEFINES_DPX_SOURCE : InfDefSection.SetDpxSource
+}
+
+## InfDefMember
+#
+#
+class InfDefMember():
+ def __init__(self, Name='', Value=''):
+ self.Comments = InfLineCommentObject()
+ self.Name = Name
+ self.Value = Value
+ self.CurrentLine = CurrentLine()
+
+ def GetName(self):
+ return self.Name
+ def SetName(self, Name):
+ self.Name = Name
+ def GetValue(self):
+ return self.Value
+ def SetValue(self, Value):
+ self.Value = Value
+
+## InfDefObject
+#
+#
+class InfDefObject(InfSectionCommonDef):
+ def __init__(self):
+ self.Defines = Sdict()
+ InfSectionCommonDef.__init__(self)
+ def SetDefines(self, DefineContent, Arch = None):
+ #
+ # Validate Arch
+ #
+ HasFoundInfVersionFalg = False
+ LineInfo = ['', -1, '']
+ ArchListString = ' '.join(Arch)
+
+ #
+ # Parse Define items.
+ #
+ for InfDefMemberObj in DefineContent:
+ ProcessFunc = None
+ Name = InfDefMemberObj.GetName()
+ Value = InfDefMemberObj.GetValue()
+ InfLineCommentObj = InfLineCommentObject()
+ InfLineCommentObj.SetHeaderComments(InfDefMemberObj.Comments.GetHeaderComments())
+ InfLineCommentObj.SetTailComments(InfDefMemberObj.Comments.GetTailComments())
+ if Name == 'COMPONENT_TYPE':
+ ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
+ ErrorCode=ToolError.EDK1_INF_ERROR,
+ RaiseError=True)
+ if Name == DT.TAB_INF_DEFINES_INF_VERSION:
+ HasFoundInfVersionFalg = True
+
+ if not (Name == '' or Name == None):
+ #
+ # Process "SPEC" Keyword definition.
+ #
+ ReName = re.compile(r"SPEC ", re.DOTALL)
+ if ReName.match(Name):
+ SpecValue = Name[Name.find("SPEC") + len("SPEC"):].strip()
+ Name = "SPEC"
+ Value = SpecValue + " = " + Value
+ if self.Defines.has_key(ArchListString):
+ DefineList = self.Defines[ArchListString]
+ LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
+ LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
+ LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
+ DefineList.CurrentLine = LineInfo
+ #
+ # Found the process function from mapping table.
+ #
+ if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys():
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name),
+ LineInfo=LineInfo)
+
+ else:
+ ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name]
+ if (ProcessFunc != None):
+ ProcessFunc(DefineList, Value, InfLineCommentObj)
+ self.Defines[ArchListString] = DefineList
+ else:
+ DefineList = InfDefSection()
+ LineInfo[0] = InfDefMemberObj.CurrentLine.GetFileName()
+ LineInfo[1] = InfDefMemberObj.CurrentLine.GetLineNo()
+ LineInfo[2] = InfDefMemberObj.CurrentLine.GetLineString()
+ DefineList.CurrentLine = LineInfo
+ #
+ # Found the process function from mapping table.
+ #
+ if Name not in gFUNCTION_MAPPING_FOR_DEFINE_SECTION.keys():
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_SECTION_KEYWORD_INVALID%(Name),
+ LineInfo=LineInfo)
+ #
+ # Found the process function from mapping table.
+ #
+ else:
+ ProcessFunc = gFUNCTION_MAPPING_FOR_DEFINE_SECTION[Name]
+ if (ProcessFunc != None):
+ ProcessFunc(DefineList, Value, InfLineCommentObj)
+ self.Defines[ArchListString] = DefineList
+
+ #
+ # After set, check whether INF_VERSION defined.
+ #
+ if not HasFoundInfVersionFalg:
+ ErrorInInf(ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF,
+ ErrorCode=ToolError.EDK1_INF_ERROR,
+ RaiseError=True)
+ return True
+
+ def GetDefines(self):
+ return self.Defines
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py
new file mode 100644
index 0000000000..55d6bbc69e
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfDepexObject.py
@@ -0,0 +1,166 @@
+## @file
+# This file is used to define class objects of INF file [Depex] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfDepexObject
+'''
+
+from Library import DataType as DT
+from Library import GlobalData
+import Logger.Log as Logger
+from Logger import ToolError
+from Logger import StringTable as ST
+
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+from Library.ParserValidate import IsValidArch
+
+class InfDepexContentItem():
+ def __init__(self):
+ self.SectionType = ''
+ self.SectionString = ''
+
+ def SetSectionType(self, SectionType):
+ self.SectionType = SectionType
+ def GetSectionType(self):
+ return self.SectionType
+
+ def SetSectionString(self, SectionString):
+ self.SectionString = SectionString
+ def GetSectionString(self):
+ return self.SectionString
+
+
+class InfDepexItem():
+ def __init__(self):
+ self.DepexContent = ''
+ self.ModuleType = ''
+ self.SupArch = ''
+ self.HelpString = ''
+ self.FeatureFlagExp = ''
+ self.InfDepexContentItemList = []
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetSupArch(self, Arch):
+ self.SupArch = Arch
+ def GetSupArch(self):
+ return self.SupArch
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+ def SetModuleType(self, Type):
+ self.ModuleType = Type
+ def GetModuleType(self):
+ return self.ModuleType
+
+ def SetDepexConent(self, Content):
+ self.DepexContent = Content
+ def GetDepexContent(self):
+ return self.DepexContent
+
+ def SetInfDepexContentItemList(self, InfDepexContentItemList):
+ self.InfDepexContentItemList = InfDepexContentItemList
+ def GetInfDepexContentItemList(self):
+ return self.InfDepexContentItemList
+
+## InfDepexObject
+#
+#
+#
+class InfDepexObject(InfSectionCommonDef):
+ def __init__(self):
+ self.Depex = []
+ self.AllContent = ''
+ self.SectionContent = ''
+ InfSectionCommonDef.__init__(self)
+
+ def SetDepex(self, DepexContent, KeyList=None, CommentList=None):
+ for KeyItem in KeyList:
+ Arch = KeyItem[0]
+ ModuleType = KeyItem[1]
+ InfDepexItemIns = InfDepexItem()
+
+ #
+ # Validate Arch
+ #
+ if IsValidArch(Arch.strip().upper()):
+ InfDepexItemIns.SetSupArch(Arch)
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_NAME_INVALID % (Arch),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=KeyItem[2])
+
+ #
+ # Validate Module Type
+ #
+ if ModuleType and ModuleType != 'COMMON':
+ if ModuleType in DT.VALID_DEPEX_MODULE_TYPE_LIST:
+ InfDepexItemIns.SetModuleType(ModuleType)
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEPEX_SECTION_MODULE_TYPE_ERROR % (ModuleType),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=KeyItem[2])
+
+ #
+ # Parser content in [Depex] section.
+ #
+ DepexString = ''
+ HelpString = ''
+ #
+ # Get Depex Expression
+ #
+ for Line in DepexContent:
+ LineContent = Line[0].strip()
+ if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ LineContent = LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
+ if LineContent:
+ DepexString = DepexString + LineContent + DT.END_OF_LINE
+ continue
+
+ if DepexString.endswith(DT.END_OF_LINE):
+ DepexString = DepexString[:-1]
+
+ if not DepexString.strip():
+ continue
+
+ #
+ # Get Help Text
+ #
+ for HelpLine in CommentList:
+ HelpString = HelpString + HelpLine + DT.END_OF_LINE
+ if HelpString.endswith(DT.END_OF_LINE):
+ HelpString = HelpString[:-1]
+
+ InfDepexItemIns.SetDepexConent(DepexString)
+ InfDepexItemIns.SetHelpString(HelpString)
+
+ self.Depex.append(InfDepexItemIns)
+
+ return True
+
+ def GetDepex(self):
+ return self.Depex
+
+ def GetAllContent(self):
+ return self.AllContent
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py
new file mode 100644
index 0000000000..4f1a3f4e81
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfGuidObject.py
@@ -0,0 +1,350 @@
+## @file
+# This file is used to define class objects of INF file [Guids] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfGuidObject
+'''
+
+from Library.ParserValidate import IsValidCVariableName
+from Library.CommentParsing import ParseComment
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+
+from Library.Misc import Sdict
+from Library import DataType as DT
+import Logger.Log as Logger
+from Logger import ToolError
+from Logger import StringTable as ST
+
+class InfGuidItemCommentContent():
+ def __init__(self):
+ #
+ # ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation"
+ # TailString.
+ #
+ #
+ # SOMETIMES_CONSUMES
+ #
+ self.UsageItem = ''
+ #
+ # Variable
+ #
+ self.GuidTypeItem = ''
+ #
+ # MemoryTypeInformation
+ #
+ self.VariableNameItem = ''
+ #
+ # TailString
+ #
+ self.HelpStringItem = ''
+
+ def SetUsageItem(self, UsageItem):
+ self.UsageItem = UsageItem
+ def GetUsageItem(self):
+ return self.UsageItem
+
+ def SetGuidTypeItem(self, GuidTypeItem):
+ self.GuidTypeItem = GuidTypeItem
+ def GetGuidTypeItem(self):
+ return self.GuidTypeItem
+
+ def SetVariableNameItem(self, VariableNameItem):
+ self.VariableNameItem = VariableNameItem
+ def GetVariableNameItem(self):
+ return self.VariableNameItem
+
+ def SetHelpStringItem(self, HelpStringItem):
+ self.HelpStringItem = HelpStringItem
+ def GetHelpStringItem(self):
+ return self.HelpStringItem
+
+class InfGuidItem():
+ def __init__(self):
+ self.Name = ''
+ self.FeatureFlagExp = ''
+ #
+ # A list contain instance of InfGuidItemCommentContent
+ #
+ self.CommentList = []
+ self.SupArchList = []
+
+ def SetName(self, Name):
+ self.Name = Name
+ def GetName(self):
+ return self.Name
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetCommentList(self, CommentList):
+ self.CommentList = CommentList
+ def GetCommentList(self):
+ return self.CommentList
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+## ParseComment
+#
+# ParseComment
+#
+def ParseGuidComment(CommentsList, InfGuidItemObj):
+ #
+ # Get/Set Usage and HelpString
+ #
+ if CommentsList != None and len(CommentsList) != 0 :
+ CommentInsList = []
+ PreUsage = None
+ PreGuidType = None
+ PreHelpText = ''
+ BlockFlag = -1
+ Count = 0
+ for CommentItem in CommentsList:
+ Count = Count + 1
+ CommentItemUsage, \
+ CommentItemGuidType, \
+ CommentItemVarString, \
+ CommentItemHelpText = \
+ ParseComment(CommentItem,
+ DT.ALL_USAGE_TOKENS,
+ DT.GUID_TYPE_TOKENS,
+ [],
+ True)
+
+ if CommentItemHelpText == None:
+ CommentItemHelpText = ''
+ if Count == len(CommentsList) and CommentItemUsage == CommentItemGuidType == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = DT.END_OF_LINE
+
+ if Count == len(CommentsList):
+ if BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == CommentItemGuidType == DT.ITEM_UNDEFINED:
+ BlockFlag = 4
+ else:
+ BlockFlag = 3
+ if BlockFlag == -1:
+ BlockFlag = 4
+ if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == CommentItemGuidType == DT.ITEM_UNDEFINED:
+ if BlockFlag == -1:
+ BlockFlag = 1
+ elif BlockFlag == 1:
+ BlockFlag = 2
+ else:
+ if BlockFlag == 1 or BlockFlag == 2:
+ BlockFlag = 3
+ elif BlockFlag == -1:
+ BlockFlag = 4
+
+ #
+ # Combine two comment line if they are generic comment
+ #
+ if CommentItemUsage == CommentItemGuidType == PreUsage == PreGuidType == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
+
+ PreHelpText = CommentItemHelpText
+
+ if BlockFlag == 4:
+ CommentItemIns = InfGuidItemCommentContent()
+ CommentItemIns.SetUsageItem(CommentItemUsage)
+ CommentItemIns.SetGuidTypeItem(CommentItemGuidType)
+ CommentItemIns.SetVariableNameItem(CommentItemVarString)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreGuidType = None
+ PreHelpText = ''
+
+ elif BlockFlag == 3:
+ #
+ # Add previous help string
+ #
+ CommentItemIns = InfGuidItemCommentContent()
+ CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
+ CommentItemIns.SetGuidTypeItem(DT.ITEM_UNDEFINED)
+ if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
+ PreHelpText += DT.END_OF_LINE
+ CommentItemIns.SetHelpStringItem(PreHelpText)
+ CommentInsList.append(CommentItemIns)
+ #
+ # Add Current help string
+ #
+ CommentItemIns = InfGuidItemCommentContent()
+ CommentItemIns.SetUsageItem(CommentItemUsage)
+ CommentItemIns.SetGuidTypeItem(CommentItemGuidType)
+ CommentItemIns.SetVariableNameItem(CommentItemVarString)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreGuidType = None
+ PreHelpText = ''
+
+ else:
+ PreUsage = CommentItemUsage
+ PreGuidType = CommentItemGuidType
+ PreHelpText = CommentItemHelpText
+
+ InfGuidItemObj.SetCommentList(CommentInsList)
+ else:
+ #
+ # Still need to set the USAGE/GUIDTYPE to undefined.
+ #
+ CommentItemIns = InfGuidItemCommentContent()
+ CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
+ CommentItemIns.SetGuidTypeItem(DT.ITEM_UNDEFINED)
+ InfGuidItemObj.SetCommentList([CommentItemIns])
+
+ return InfGuidItemObj
+
+## InfGuidObject
+#
+# InfGuidObject
+#
+class InfGuidObject():
+ def __init__(self):
+ self.Guids = Sdict()
+ #
+ # Macro defined in this section should be only used in this section.
+ #
+ self.Macros = {}
+
+ def SetGuid(self, GuidList, Arch = None):
+ __SupportArchList = []
+ for ArchItem in Arch:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+
+ __SupportArchList.append(ArchItem)
+
+ for Item in GuidList:
+ #
+ # Get Comment content of this protocol
+ #
+ CommentsList = None
+ if len(Item) == 3:
+ CommentsList = Item[1]
+ CurrentLineOfItem = Item[2]
+ Item = Item[0]
+ InfGuidItemObj = InfGuidItem()
+ if len(Item) >= 1 and len(Item) <= 2:
+ #
+ # Only GuildName contained
+ #
+ if not IsValidCVariableName(Item[0]):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ if (Item[0] != ''):
+ InfGuidItemObj.SetName(Item[0])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_CNAME_MISSING,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ if len(Item) == 2:
+ #
+ # Contained CName and Feature Flag Express
+ # <statements> ::= <CName> ["|" <FeatureFlagExpress>]
+ # For GUID entry.
+ #
+ if Item[1].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ #
+ # Validate Feature Flag Express
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ InfGuidItemObj.SetFeatureFlagExp(Item[1])
+ if len(Item) != 1 and len(Item) != 2:
+ #
+ # Invalid format of GUID statement
+ #
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+
+ InfGuidItemObj = ParseGuidComment(CommentsList, InfGuidItemObj)
+ InfGuidItemObj.SetSupArchList(__SupportArchList)
+
+ #
+ # Determine GUID name duplicate. Follow below rule:
+ #
+ # A GUID must not be duplicated within a [Guids] section.
+ # A GUID may appear in multiple architectural [Guids]
+ # sections. A GUID listed in an architectural [Guids]
+ # section must not be listed in the common architectural
+ # [Guids] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+ for Item in self.Guids:
+ if Item.GetName() == InfGuidItemObj.GetName():
+ ItemSupArchList = Item.GetSupArchList()
+ for ItemArch in ItemSupArchList:
+ for GuidItemObjArch in __SupportArchList:
+ if ItemArch == GuidItemObjArch:
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+ #
+ pass
+
+ if ItemArch.upper() == 'COMMON' or GuidItemObjArch.upper() == 'COMMON':
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+ #
+ pass
+
+ if self.Guids.has_key((InfGuidItemObj)):
+ GuidList = self.Guids[InfGuidItemObj]
+ GuidList.append(InfGuidItemObj)
+ self.Guids[InfGuidItemObj] = GuidList
+ else:
+ GuidList = []
+ GuidList.append(InfGuidItemObj)
+ self.Guids[InfGuidItemObj] = GuidList
+
+ return True
+
+ def GetGuid(self):
+ return self.Guids \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfHeaderObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfHeaderObject.py
new file mode 100644
index 0000000000..45fba31aaa
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfHeaderObject.py
@@ -0,0 +1,119 @@
+## @file
+# This file is used to define class objects of INF file header.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfHeaderObject
+'''
+
+## INF file header object
+#
+# A sample file header
+#
+# ## @file xxx.inf FileName
+# # Abstract
+# #
+# # Description
+# #
+# # Copyright
+# #
+# # License
+# #
+#
+class InfHeaderObject():
+ def __init__(self):
+ self.FileName = ''
+ self.Abstract = ''
+ self.Description = ''
+ self.Copyright = ''
+ self.License = ''
+
+ ## SetFileName
+ #
+ # @param FileName: File Name
+ #
+ def SetFileName(self, FileName):
+ if not (FileName == '' or FileName == None):
+ self.FileName = FileName
+ return True
+ else:
+ return False
+
+ ## GetFileName
+ #
+ def GetFileName(self):
+ return self.FileName
+
+ ## SetAbstract
+ #
+ # @param Abstract: Abstract
+ #
+ def SetAbstract(self, Abstract):
+ if not (Abstract == '' or Abstract == None):
+ self.Abstract = Abstract
+ return True
+ else:
+ return False
+
+ ## GetAbstract
+ #
+ def GetAbstract(self):
+ return self.Abstract
+
+ ## SetDescription
+ #
+ # @param Description: Description content
+ #
+ def SetDescription(self, Description):
+ if not (Description == '' or Description == None):
+ self.Description = Description
+ return True
+ else:
+ return False
+
+ ## GetAbstract
+ #
+ def GetDescription(self):
+ return self.Description
+
+ ## SetCopyright
+ #
+ # @param Copyright: Copyright content
+ #
+ def SetCopyright(self, Copyright):
+ if not (Copyright == '' or Copyright == None):
+ self.Copyright = Copyright
+ return True
+ else:
+ return False
+
+ ## GetCopyright
+ #
+ def GetCopyright(self):
+ return self.Copyright
+
+ ## SetCopyright
+ #
+ # @param License: License content
+ #
+ def SetLicense(self, License):
+ if not (License == '' or License == None):
+ self.License = License
+ return True
+ else:
+ return False
+
+ ## GetLicense
+ #
+ def GetLicense(self):
+ return self.License \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py
new file mode 100644
index 0000000000..a37692ee23
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfLibraryClassesObject.py
@@ -0,0 +1,252 @@
+## @file
+# This file is used to define class objects of INF file [LibraryClasses] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfLibraryClassesObject
+'''
+
+from Logger import StringTable as ST
+from Logger import ToolError
+import Logger.Log as Logger
+from Library import GlobalData
+
+from Library.Misc import Sdict
+from Object.Parser.InfCommonObject import CurrentLine
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+from Library.ParserValidate import IsValidLibName
+
+## GetArchModuleType
+#
+# Get Arch List and ModuleType List
+#
+def GetArchModuleType(KeyList):
+ __SupArchList = []
+ __SupModuleList = []
+
+ for (ArchItem, ModuleItem) in KeyList:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+
+ if (ModuleItem == '' or ModuleItem == None):
+ ModuleItem = 'COMMON'
+
+ if ArchItem not in __SupArchList:
+ __SupArchList.append(ArchItem)
+
+ List = ModuleItem.split('|')
+ for Entry in List:
+ if Entry not in __SupModuleList:
+ __SupModuleList.append(Entry)
+
+ return (__SupArchList, __SupModuleList)
+
+
+class InfLibraryClassItem():
+ def __init__(self, LibName='', FeatureFlagExp='', HelpString=None):
+ self.LibName = LibName
+ self.FeatureFlagExp = FeatureFlagExp
+ self.HelpString = HelpString
+ self.CurrentLine = CurrentLine()
+ self.SupArchList = []
+ self.SupModuleList = []
+ self.FileGuid = ''
+ self.Version = ''
+
+ def SetLibName(self, LibName):
+ self.LibName = LibName
+ def GetLibName(self):
+ return self.LibName
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ def SetSupModuleList(self, SupModuleList):
+ self.SupModuleList = SupModuleList
+ def GetSupModuleList(self):
+ return self.SupModuleList
+
+ #
+ # As Build related information
+ #
+ def SetFileGuid(self, FileGuid):
+ self.FileGuid = FileGuid
+ def GetFileGuid(self):
+ return self.FileGuid
+
+ def SetVersion(self, Version):
+ self.Version = Version
+ def GetVersion(self):
+ return self.Version
+
+## INF LibraryClass Section
+#
+#
+#
+class InfLibraryClassObject():
+ def __init__(self):
+ self.LibraryClasses = Sdict()
+ #
+ # Macro defined in this section should be only used in this section.
+ #
+ self.Macros = {}
+
+ ##SetLibraryClasses
+ #
+ #
+ # @param HelpString: It can be a common comment or contain a recommend
+ # instance.
+ #
+ def SetLibraryClasses(self, LibContent, KeyList=None):
+ #
+ # Validate Arch
+ #
+ (__SupArchList, __SupModuleList) = GetArchModuleType(KeyList)
+
+ for LibItem in LibContent:
+ LibItemObj = InfLibraryClassItem()
+ if not GlobalData.gIS_BINARY_INF:
+ HelpStringObj = LibItem[1]
+ LibItemObj.CurrentLine.SetFileName(LibItem[2][2])
+ LibItemObj.CurrentLine.SetLineNo(LibItem[2][1])
+ LibItemObj.CurrentLine.SetLineString(LibItem[2][0])
+ LibItem = LibItem[0]
+ if HelpStringObj != None:
+ LibItemObj.SetHelpString(HelpStringObj)
+ if len(LibItem) >= 1:
+ if LibItem[0].strip() != '':
+ if IsValidLibName(LibItem[0].strip()):
+ if LibItem[0].strip() != 'NULL':
+ LibItemObj.SetLibName(LibItem[0])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_LIB_NAME_INVALID,
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LibItemObj.CurrentLine.GetLineNo(),
+ ExtraData=LibItemObj.CurrentLine.GetLineString())
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (LibItem[0]),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LibItemObj.CurrentLine.GetLineNo(),
+ ExtraData=LibItemObj.CurrentLine.GetLineString())
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_LIBRARY_SECTION_LIBNAME_MISSING,
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LibItemObj.CurrentLine.GetLineNo(),
+ ExtraData=LibItemObj.CurrentLine.GetLineString())
+ if len(LibItem) == 2:
+ if LibItem[1].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LibItemObj.CurrentLine.GetLineNo(),
+ ExtraData=LibItemObj.CurrentLine.GetLineString())
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(LibItem[1].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID % (FeatureFlagRtv[1]),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LibItemObj.CurrentLine.GetLineNo(),
+ ExtraData=LibItemObj.CurrentLine.GetLineString())
+ LibItemObj.SetFeatureFlagExp(LibItem[1].strip())
+
+ #
+ # Invalid strings
+ #
+ if len(LibItem) < 1 or len(LibItem) > 2:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_LIBRARY_SECTION_CONTENT_ERROR,
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LibItemObj.CurrentLine.GetLineNo(),
+ ExtraData=LibItemObj.CurrentLine.GetLineString())
+
+ LibItemObj.SetSupArchList(__SupArchList)
+ LibItemObj.SetSupModuleList(__SupModuleList)
+
+ #
+ # Determine Library class duplicate. Follow below rule:
+ #
+ # A library class keyword must not be duplicated within a
+ # [LibraryClasses] section. Library class keywords may appear in
+ # multiple architectural and module type [LibraryClasses] sections.
+ # A library class keyword listed in an architectural or module type
+ # [LibraryClasses] section must not be listed in the common
+ # architectural or module type [LibraryClasses] section.
+ #
+ # NOTE: This check will not report error now. But keep code for future enhancement.
+ #
+# for Item in self.LibraryClasses:
+# if Item.GetLibName() == LibItemObj.GetLibName():
+# ItemSupArchList = Item.GetSupArchList()
+# ItemSupModuleList = Item.GetSupModuleList()
+# for ItemArch in ItemSupArchList:
+# for ItemModule in ItemSupModuleList:
+# for LibItemObjArch in __SupArchList:
+# for LibItemObjModule in __SupModuleList:
+# if ItemArch == LibItemObjArch and LibItemObjModule == ItemModule:
+# #
+# # ERR_INF_PARSER_ITEM_DUPLICATE
+# #
+# pass
+# if (ItemArch.upper() == 'COMMON' or LibItemObjArch.upper() == 'COMMON') \
+# and LibItemObjModule == ItemModule:
+# #
+# # ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+# #
+# pass
+ else:
+ #
+ # Assume the file GUID is well formatted.
+ #
+ LibItemObj.SetFileGuid(LibItem[0])
+ LibItemObj.SetVersion(LibItem[1])
+
+ if self.LibraryClasses.has_key((LibItemObj)):
+ LibraryList = self.LibraryClasses[LibItemObj]
+ LibraryList.append(LibItemObj)
+ self.LibraryClasses[LibItemObj] = LibraryList
+ else:
+ LibraryList = []
+ LibraryList.append(LibItemObj)
+ self.LibraryClasses[LibItemObj] = LibraryList
+
+ return True
+
+ def GetLibraryClasses(self):
+ return self.LibraryClasses
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py b/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py
new file mode 100644
index 0000000000..74099e2088
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfMisc.py
@@ -0,0 +1,148 @@
+## @file
+# This file is used to define class objects of INF file miscellaneous.
+# Include BootMode/HOB/Event and others. It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfMisc
+'''
+
+import Logger.Log as Logger
+from Logger import ToolError
+
+from Library import DataType as DT
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+from Library.Misc import Sdict
+
+##
+# BootModeObject
+#
+class InfBootModeObject():
+ def __init__(self):
+ self.SupportedBootModes = ''
+ self.HelpString = ''
+ self.Usage = ''
+
+ def SetSupportedBootModes(self, SupportedBootModes):
+ self.SupportedBootModes = SupportedBootModes
+ def GetSupportedBootModes(self):
+ return self.SupportedBootModes
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+ def SetUsage(self, Usage):
+ self.Usage = Usage
+ def GetUsage(self):
+ return self.Usage
+##
+# EventObject
+#
+class InfEventObject():
+ def __init__(self):
+ self.EventType = ''
+ self.HelpString = ''
+ self.Usage = ''
+
+ def SetEventType(self, EventType):
+ self.EventType = EventType
+
+ def GetEventType(self):
+ return self.EventType
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+ def SetUsage(self, Usage):
+ self.Usage = Usage
+ def GetUsage(self):
+ return self.Usage
+##
+# HobObject
+#
+class InfHobObject():
+ def __init__(self):
+ self.HobType = ''
+ self.Usage = ''
+ self.SupArchList = []
+ self.HelpString = ''
+
+ def SetHobType(self, HobType):
+ self.HobType = HobType
+
+ def GetHobType(self):
+ return self.HobType
+
+ def SetUsage(self, Usage):
+ self.Usage = Usage
+ def GetUsage(self):
+ return self.Usage
+
+ def SetSupArchList(self, ArchList):
+ self.SupArchList = ArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+##
+# InfSpecialCommentObject
+#
+class InfSpecialCommentObject(InfSectionCommonDef):
+ def __init__(self):
+ self.SpecialComments = Sdict()
+ InfSectionCommonDef.__init__(self)
+
+ def SetSpecialComments(self, SepcialSectionList = None, Type = ''):
+ if Type == DT.TYPE_HOB_SECTION or \
+ Type == DT.TYPE_EVENT_SECTION or \
+ Type == DT.TYPE_BOOTMODE_SECTION:
+ for Item in SepcialSectionList:
+ if self.SpecialComments.has_key(Type):
+ ObjList = self.SpecialComments[Type]
+ ObjList.append(Item)
+ self.SpecialComments[Type] = ObjList
+ else:
+ ObjList = []
+ ObjList.append(Item)
+ self.SpecialComments[Type] = ObjList
+
+ return True
+
+ def GetSpecialComments(self):
+ return self.SpecialComments
+
+
+
+## ErrorInInf
+#
+# An encapsulate of Error for INF parser.
+#
+def ErrorInInf(Message=None, ErrorCode=None, LineInfo=None, RaiseError=True):
+ if ErrorCode == None:
+ ErrorCode = ToolError.FORMAT_INVALID
+ if LineInfo == None:
+ LineInfo = ['', -1, '']
+ Logger.Error("InfParser",
+ ErrorCode,
+ Message=Message,
+ File=LineInfo[0],
+ Line=LineInfo[1],
+ ExtraData=LineInfo[2],
+ RaiseError=RaiseError) \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py
new file mode 100644
index 0000000000..37399134db
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfPackagesObject.py
@@ -0,0 +1,187 @@
+## @file
+# This file is used to define class objects of INF file [Packages] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfPackageObject
+'''
+
+from Logger import StringTable as ST
+from Logger import ToolError
+import Logger.Log as Logger
+from Library import GlobalData
+
+from Library.Misc import Sdict
+from Library.ParserValidate import IsValidPath
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+
+class InfPackageItem():
+ def __init__(self,
+ PackageName = '',
+ FeatureFlagExp = '',
+ HelpString = ''):
+ self.PackageName = PackageName
+ self.FeatureFlagExp = FeatureFlagExp
+ self.HelpString = HelpString
+ self.SupArchList = []
+
+ def SetPackageName(self, PackageName):
+ self.PackageName = PackageName
+ def GetPackageName(self):
+ return self.PackageName
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetHelpString(self, HelpString):
+ self.HelpString = HelpString
+ def GetHelpString(self):
+ return self.HelpString
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+
+## INF package section
+#
+#
+#
+class InfPackageObject():
+ def __init__(self):
+ self.Packages = Sdict()
+ #
+ # Macro defined in this section should be only used in this section.
+ #
+ self.Macros = {}
+
+ def SetPackages(self, PackageData, Arch = None):
+ IsValidFileFlag = False
+ SupArchList = []
+ for ArchItem in Arch:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+ SupArchList.append(ArchItem)
+
+ for PackageItem in PackageData:
+ PackageItemObj = InfPackageItem()
+ HelpStringObj = PackageItem[1]
+ CurrentLineOfPackItem = PackageItem[2]
+ PackageItem = PackageItem[0]
+ if HelpStringObj != None:
+ HelpString = HelpStringObj.HeaderComments + HelpStringObj.TailComments
+ PackageItemObj.SetHelpString(HelpString)
+ if len(PackageItem) >= 1:
+ #
+ # Validate file exist/format.
+ #
+ if IsValidPath(PackageItem[0], ''):
+ IsValidFileFlag = True
+ elif IsValidPath(PackageItem[0], GlobalData.gINF_MODULE_DIR):
+ IsValidFileFlag = True
+ elif IsValidPath(PackageItem[0], GlobalData.gWORKSPACE):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(PackageItem[0]),
+ File=CurrentLineOfPackItem[2],
+ Line=CurrentLineOfPackItem[1],
+ ExtraData=CurrentLineOfPackItem[0])
+ return False
+ if IsValidFileFlag:
+ PackageItemObj.SetPackageName(PackageItem[0])
+ if len(PackageItem) == 2:
+ #
+ # Validate Feature Flag Express
+ #
+ if PackageItem[1].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=CurrentLineOfPackItem[2],
+ Line=CurrentLineOfPackItem[1],
+ ExtraData=CurrentLineOfPackItem[0])
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(PackageItem[1].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ File=CurrentLineOfPackItem[2],
+ Line=CurrentLineOfPackItem[1],
+ ExtraData=CurrentLineOfPackItem[0])
+
+ PackageItemObj.SetFeatureFlagExp(PackageItem[1].strip())
+
+ if len(PackageItem) > 2:
+ #
+ # Invalid format of Package statement
+ #
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PACKAGE_SECTION_CONTENT_ERROR,
+ File=CurrentLineOfPackItem[2],
+ Line=CurrentLineOfPackItem[1],
+ ExtraData=CurrentLineOfPackItem[0])
+ PackageItemObj.SetSupArchList(SupArchList)
+
+ #
+ # Determine package file name duplicate. Follow below rule:
+ #
+ # A package filename must not be duplicated within a [Packages]
+ # section. Package filenames may appear in multiple architectural
+ # [Packages] sections. A package filename listed in an
+ # architectural [Packages] section must not be listed in the common
+ # architectural [Packages] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+ for Item in self.Packages:
+ if Item.GetPackageName() == PackageItemObj.GetPackageName():
+ ItemSupArchList = Item.GetSupArchList()
+ for ItemArch in ItemSupArchList:
+ for PackageItemObjArch in SupArchList:
+ if ItemArch == PackageItemObjArch:
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+ #
+ pass
+ if ItemArch.upper() == 'COMMON' or PackageItemObjArch.upper() == 'COMMON':
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+ #
+ pass
+
+ if self.Packages.has_key((PackageItemObj)):
+ PackageList = self.Packages[PackageItemObj]
+ PackageList.append(PackageItemObj)
+ self.Packages[PackageItemObj] = PackageList
+ else:
+ PackageList = []
+ PackageList.append(PackageItemObj)
+ self.Packages[PackageItemObj] = PackageList
+
+ return True
+
+ def GetPackages(self, Arch = None):
+ if Arch == None:
+ return self.Packages \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py
new file mode 100644
index 0000000000..fc5227451a
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfPcdObject.py
@@ -0,0 +1,640 @@
+## @file
+# This file is used to define class objects of INF file [Pcds] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfPcdObject
+'''
+import os
+import re
+
+from Logger import StringTable as ST
+from Logger import ToolError
+import Logger.Log as Logger
+from Library import GlobalData
+from Library import DataType as DT
+
+from Library.Misc import Sdict
+from Library.Misc import GetHelpStringByRemoveHashKey
+from Library.ParserValidate import IsValidPcdType
+from Library.ParserValidate import IsValidCVariableName
+from Library.ParserValidate import IsValidPcdValue
+from Library.ParserValidate import IsValidArch
+from Library.CommentParsing import ParseComment
+from Library.String import GetSplitValueList
+from Library.String import IsHexDigitUINT32
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+from Parser.InfAsBuiltProcess import GetPackageListInfo
+from Parser.DecParser import Dec
+
+from Object.Parser.InfPackagesObject import InfPackageItem
+
+def ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList):
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+
+ if PcdTypeItem1.upper != DT.TAB_INF_FEATURE_PCD.upper():
+ ArchList = GetSplitValueList(ArchItem, ' ')
+ for ArchItemNew in ArchList:
+ if not IsValidArch(ArchItemNew):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(ArchItemNew),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=ArchItemNew)
+ SupArchDict[PcdTypeItem1] = ArchList
+ else:
+ SupArchList.append(ArchItem)
+
+ return SupArchList, SupArchDict
+
+def ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj):
+ CommentInsList = []
+ PreUsage = None
+ PreHelpText = ''
+ BlockFlag = -1
+ FFEHelpText = ''
+ CommentItemHelpText = ''
+ Count = 0
+ for CommentItem in CommentList:
+ Count = Count + 1
+ CommentItemUsage, CommentType, CommentString, CommentItemHelpText = ParseComment(CommentItem,
+ DT.ALL_USAGE_TOKENS,
+ {},
+ [],
+ False)
+ if CommentType and CommentString:
+ pass
+
+ if PcdTypeItem == 'FeaturePcd':
+ CommentItemUsage = DT.USAGE_ITEM_CONSUMES
+ if CommentItemHelpText == None:
+ CommentItemHelpText = ''
+
+ if Count == 1:
+ FFEHelpText = CommentItemHelpText
+ else:
+ FFEHelpText = FFEHelpText + DT.END_OF_LINE + CommentItemHelpText
+
+ if Count == len(CommentList):
+ CommentItemHelpText = FFEHelpText
+ BlockFlag = 4
+ else:
+ continue
+
+ if CommentItemHelpText == None:
+ CommentItemHelpText = ''
+ if Count == len(CommentList) and CommentItemUsage == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = DT.END_OF_LINE
+
+ if Count == len(CommentList) and (BlockFlag == 1 or BlockFlag == 2):
+ if CommentItemUsage == DT.ITEM_UNDEFINED:
+ BlockFlag = 4
+ else:
+ BlockFlag = 3
+ elif BlockFlag == -1 and Count == len(CommentList):
+ BlockFlag = 4
+
+ if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == DT.ITEM_UNDEFINED:
+ if BlockFlag == -1:
+ BlockFlag = 1
+ elif BlockFlag == 1:
+ BlockFlag = 2
+ else:
+ if BlockFlag == 1 or BlockFlag == 2:
+ BlockFlag = 3
+ elif BlockFlag == -1:
+ BlockFlag = 4
+ #
+ # Combine two comment line if they are generic comment
+ #
+ if CommentItemUsage == PreUsage == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
+
+ PreHelpText = CommentItemHelpText
+
+ if BlockFlag == 4:
+ CommentItemIns = InfPcdItemCommentContent()
+ CommentItemIns.SetUsageItem(CommentItemUsage)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreHelpText = ''
+
+ elif BlockFlag == 3:
+ #
+ # Add previous help string
+ #
+ CommentItemIns = InfPcdItemCommentContent()
+ CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
+ if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
+ PreHelpText += DT.END_OF_LINE
+ CommentItemIns.SetHelpStringItem(PreHelpText)
+ CommentInsList.append(CommentItemIns)
+ #
+ # Add Current help string
+ #
+ CommentItemIns = InfPcdItemCommentContent()
+ CommentItemIns.SetUsageItem(CommentItemUsage)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreHelpText = ''
+
+ else:
+ PreUsage = CommentItemUsage
+ PreHelpText = CommentItemHelpText
+
+ PcdItemObj.SetHelpStringList(CommentInsList)
+
+ return PcdItemObj
+
+class InfPcdItemCommentContent():
+ def __init__(self):
+ #
+ # ## SOMETIMES_CONSUMES ## HelpString
+ #
+ self.UsageItem = ''
+ #
+ # Help String
+ #
+ self.HelpStringItem = ''
+
+ def SetUsageItem(self, UsageItem):
+ self.UsageItem = UsageItem
+ def GetUsageItem(self):
+ return self.UsageItem
+
+ def SetHelpStringItem(self, HelpStringItem):
+ self.HelpStringItem = HelpStringItem
+ def GetHelpStringItem(self):
+ return self.HelpStringItem
+
+## InfPcdItem
+#
+# This class defined Pcd item used in Module files
+#
+# @param CName: Input value for CName, default is ''
+# @param Token: Input value for Token, default is ''
+# @param TokenSpaceGuidCName: Input value for TokenSpaceGuidCName, default
+# is ''
+# @param DatumType: Input value for DatumType, default is ''
+# @param MaxDatumSize: Input value for MaxDatumSize, default is ''
+# @param DefaultValue: Input value for DefaultValue, default is ''
+# @param ItemType: Input value for ItemType, default is ''
+# @param ValidUsage: Input value for ValidUsage, default is []
+# @param SkuInfoList: Input value for SkuInfoList, default is {}
+# @param SupModuleList: Input value for SupModuleList, default is []
+#
+class InfPcdItem():
+ def __init__(self):
+ self.CName = ''
+ self.Token = ''
+ self.TokenSpaceGuidCName = ''
+ self.TokenSpaceGuidValue = ''
+ self.DatumType = ''
+ self.MaxDatumSize = ''
+ self.DefaultValue = ''
+ self.Offset = ''
+ self.ValidUsage = ''
+ self.ItemType = ''
+ self.SupModuleList = []
+ self.HelpStringList = []
+ self.FeatureFlagExp = ''
+ self.SupArchList = []
+ self.PcdErrorsList = []
+
+ def SetCName(self, CName):
+ self.CName = CName
+ def GetCName(self):
+ return self.CName
+
+ def SetToken(self, Token):
+ self.Token = Token
+ def GetToken(self):
+ return self.Token
+
+ def SetTokenSpaceGuidCName(self, TokenSpaceGuidCName):
+ self.TokenSpaceGuidCName = TokenSpaceGuidCName
+ def GetTokenSpaceGuidCName(self):
+ return self.TokenSpaceGuidCName
+
+ def SetTokenSpaceGuidValue(self, TokenSpaceGuidValue):
+ self.TokenSpaceGuidValue = TokenSpaceGuidValue
+ def GetTokenSpaceGuidValue(self):
+ return self.TokenSpaceGuidValue
+
+ def SetDatumType(self, DatumType):
+ self.DatumType = DatumType
+ def GetDatumType(self):
+ return self.DatumType
+
+ def SetMaxDatumSize(self, MaxDatumSize):
+ self.MaxDatumSize = MaxDatumSize
+ def GetMaxDatumSize(self):
+ return self.MaxDatumSize
+
+ def SetDefaultValue(self, DefaultValue):
+ self.DefaultValue = DefaultValue
+ def GetDefaultValue(self):
+ return self.DefaultValue
+
+ def SetPcdErrorsList(self, PcdErrorsList):
+ self.PcdErrorsList = PcdErrorsList
+ def GetPcdErrorsList(self):
+ return self.PcdErrorsList
+
+ def SetItemType(self, ItemType):
+ self.ItemType = ItemType
+ def GetItemType(self):
+ return self.ItemType
+
+ def SetSupModuleList(self, SupModuleList):
+ self.SupModuleList = SupModuleList
+ def GetSupModuleList(self):
+ return self.SupModuleList
+
+ def SetHelpStringList(self, HelpStringList):
+ self.HelpStringList = HelpStringList
+ def GetHelpStringList(self):
+ return self.HelpStringList
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetSupportArchList(self, ArchList):
+ self.SupArchList = ArchList
+ def GetSupportArchList(self):
+ return self.SupArchList
+
+ def SetOffset(self, Offset):
+ self.Offset = Offset
+ def GetOffset(self):
+ return self.Offset
+
+##
+#
+#
+#
+class InfPcdObject():
+ def __init__(self, FileName):
+ self.Pcds = Sdict()
+ self.FileName = FileName
+
+ def SetPcds(self, PcdContent, KeysList = None, PackageInfo = None):
+
+ if GlobalData.gIS_BINARY_INF:
+ self.SetAsBuildPcds(PcdContent, KeysList, PackageInfo)
+ return True
+
+ #
+ # Validate Arch
+ #
+ SupArchList = []
+ SupArchDict = {}
+ PcdTypeItem = ''
+ for (PcdTypeItem1, ArchItem, LineNo) in KeysList:
+ SupArchList, SupArchDict = ValidateArch(ArchItem, PcdTypeItem1, LineNo, SupArchDict, SupArchList)
+
+ #
+ # Validate PcdType
+ #
+ if (PcdTypeItem1 == '' or PcdTypeItem1 == None):
+ return False
+ else:
+ if not IsValidPcdType(PcdTypeItem1):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PCD_SECTION_TYPE_ERROR%(DT.PCD_USAGE_TYPE_LIST_OF_MODULE),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=PcdTypeItem1)
+ return False
+
+ PcdTypeItem = PcdTypeItem1
+
+ for PcdItem in PcdContent:
+ PcdItemObj = InfPcdItem()
+ CommentList = PcdItem[1]
+ CurrentLineOfPcdItem = PcdItem[2]
+ PcdItem = PcdItem[0]
+
+ if CommentList != None and len(CommentList) != 0:
+ PcdItemObj = ParsePcdComment(CommentList, PcdTypeItem, PcdItemObj)
+ else:
+ CommentItemIns = InfPcdItemCommentContent()
+ CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
+ PcdItemObj.SetHelpStringList([CommentItemIns])
+
+ if len(PcdItem) >= 1 and len(PcdItem) <= 3:
+ PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)
+
+ if len(PcdItem) >= 2 and len(PcdItem) <= 3:
+ #
+ # Contain PcdName and Value, validate value.
+ #
+ if IsValidPcdValue(PcdItem[1]) or PcdItem[1].strip() == "":
+ PcdItemObj.SetDefaultValue(PcdItem[1])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PCD_VALUE_INVALID,
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=PcdItem[1])
+
+ if len(PcdItem) == 3:
+ #
+ # Contain PcdName, value, and FeatureFlag express
+ #
+ #
+ # Validate Feature Flag Express
+ #
+ if PcdItem[2].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(PcdItem[2].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+ PcdItemObj.SetFeatureFlagExp(PcdItem[2])
+
+ if len(PcdItem) < 1 or len(PcdItem) > 3:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PCD_SECTION_CONTENT_ERROR,
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+ return False
+
+ if PcdTypeItem.upper != DT.TAB_INF_FEATURE_PCD.upper():
+ PcdItemObj.SetSupportArchList(SupArchDict[PcdTypeItem])
+ else:
+ PcdItemObj.SetSupportArchList(SupArchList)
+
+ if self.Pcds.has_key((PcdTypeItem, PcdItemObj)):
+ PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]
+ PcdsList.append(PcdItemObj)
+ self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
+ else:
+ PcdsList = []
+ PcdsList.append(PcdItemObj)
+ self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
+
+ return True
+
+ def SetAsBuildPcds(self, PcdContent, KeysList = None, PackageInfo = None):
+ for PcdItem in PcdContent:
+ PcdItemObj = InfPcdItem()
+ CommentList = PcdItem[1]
+ CurrentLineOfPcdItem = PcdItem[2]
+ PcdItem = PcdItem[0]
+ CommentString = ''
+ for CommmentLine in CommentList:
+ CommentString += GetHelpStringByRemoveHashKey(CommmentLine)
+
+ PcdItemObj.SetHelpStringList(CommentString)
+ PcdItemObj.SetItemType(KeysList[0][0])
+ #
+ # Set PcdTokenSpaceCName and CName
+ #
+ PcdItemObj = SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj)
+ #
+ # Set Value/DatumType/MaxDatumSize/Token
+ #
+ PcdItemObj = SetValueDatumTypeMaxSizeToken(PcdItem,
+ CurrentLineOfPcdItem,
+ PcdItemObj,
+ KeysList[0][1],
+ PackageInfo)
+
+ PcdTypeItem = KeysList[0][0]
+ if self.Pcds.has_key((PcdTypeItem, PcdItemObj)):
+ PcdsList = self.Pcds[PcdTypeItem, PcdItemObj]
+ PcdsList.append(PcdItemObj)
+ self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
+ else:
+ PcdsList = []
+ PcdsList.append(PcdItemObj)
+ self.Pcds[PcdTypeItem, PcdItemObj] = PcdsList
+
+ def GetPcds(self):
+ return self.Pcds
+
+def ParserPcdInfoInDec(String):
+ ValueList = GetSplitValueList(String, DT.TAB_VALUE_SPLIT, 3)
+
+ #
+ # DatumType, Token
+ #
+ return ValueList[2], ValueList[3]
+
+def SetValueDatumTypeMaxSizeToken(PcdItem, CurrentLineOfPcdItem, PcdItemObj, Arch, PackageInfo = None):
+ #
+ # Package information not been generated currently, we need to parser INF file to get information.
+ #
+ if not PackageInfo:
+ PackageInfo = []
+ InfFileName = CurrentLineOfPcdItem[2]
+ PackageInfoList = GetPackageListInfo(InfFileName, GlobalData.gWORKSPACE, -1)
+ for PackageInfoListItem in PackageInfoList:
+ PackageInfoIns = InfPackageItem()
+ PackageInfoIns.SetPackageName(PackageInfoListItem)
+ PackageInfo.append(PackageInfoIns)
+
+ PcdInfoInDecHasFound = False
+ for PackageItem in PackageInfo:
+ if PcdInfoInDecHasFound:
+ break
+ PackageName = PackageItem.PackageName
+ #
+ # Open DEC file to get information
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gWORKSPACE, PackageName)))
+
+ DecParser = Dec(FullFileName)
+ #
+ # Find PCD information.
+ #
+ DecPcdsDict = DecParser.GetPcdSectionObject().ValueDict
+ for Key in DecPcdsDict.keys():
+ if (Key[0] == 'PCDSDYNAMICEX' and PcdItemObj.GetItemType() == 'PcdEx') and \
+ (Key[1] == 'COMMON' or Key[1] == Arch):
+ for PcdInDec in DecPcdsDict[Key]:
+ if PcdInDec.TokenCName == PcdItemObj.CName and \
+ PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:
+ PcdItemObj.SetToken(PcdInDec.TokenValue)
+ PcdItemObj.SetDatumType(PcdInDec.DatumType)
+ PcdItemObj.SetSupportArchList([Arch])
+
+ if (Key[0] == 'PCDSPATCHABLEINMODULE' and PcdItemObj.GetItemType() == 'PatchPcd') and \
+ (Key[1] == 'COMMON' or Key[1] == Arch):
+ for PcdInDec in DecPcdsDict[Key]:
+ if PcdInDec.TokenCName == PcdItemObj.CName and \
+ PcdInDec.TokenSpaceGuidCName == PcdItemObj.TokenSpaceGuidCName:
+ PcdItemObj.SetToken(PcdInDec.TokenValue)
+ PcdItemObj.SetDatumType(PcdInDec.DatumType)
+ PcdItemObj.SetSupportArchList([Arch])
+
+ if PcdItemObj.GetDatumType() == 'VOID*':
+ PcdItemObj.SetMaxDatumSize('%s'%(len(GetSplitValueList(PcdItem[1], DT.TAB_COMMA_SPLIT))))
+
+ DecGuidsDict = DecParser.GetGuidSectionObject().ValueDict
+ for Key in DecGuidsDict.keys():
+ if Key == 'COMMON' or Key == Arch:
+ for GuidInDec in DecGuidsDict[Key]:
+ if GuidInDec.GuidCName == PcdItemObj.TokenSpaceGuidCName:
+ PcdItemObj.SetTokenSpaceGuidValue(GuidInDec.GuidString)
+
+ #
+ # Validate Value.
+ #
+ if ValidatePcdValueOnDatumType(PcdItem[1], PcdItemObj.GetDatumType()):
+ PcdItemObj.SetDefaultValue(PcdItem[1])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_ASBUILD_PCD_VALUE_INVALID%("\"" + PcdItem[1] + "\"", "\"" +
+ PcdItemObj.GetDatumType() + "\""),
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+ #
+ # validate offset
+ #
+ if PcdItemObj.GetItemType().upper() == DT.TAB_INF_PATCH_PCD.upper():
+ if not IsHexDigitUINT32(PcdItem[2]):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_ASBUILD_PCD_OFFSET_FORMAT_INVALID%("\"" + PcdItem[2] + "\""),
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+ PcdItemObj.SetOffset(PcdItem[2])
+
+ if PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_ASBUILD_PCD_DECLARITION_MISS%("\"" + PcdItem[0] + "\""),
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+
+ return PcdItemObj
+
+def ValidatePcdValueOnDatumType(Value, Type):
+
+ Value = Value.strip()
+ #
+ # Boolean type only allow 0x00 or 0x01 as value per INF spec
+ #
+ if Type == 'BOOLEAN':
+ if not (Value == '0x00' or Value == '0x01'):
+ return False
+ elif Type == 'VOID*':
+ if not Value.startswith("{"):
+ return False
+ if not Value.endswith("}"):
+ return False
+ #
+ # Strip "{" at head and "}" at tail.
+ #
+ Value = Value[1:-1]
+ ValueList = GetSplitValueList(Value, DT.TAB_COMMA_SPLIT)
+
+ ReIsValidHexByte = re.compile("^0x[0-9a-f]{1,2}$", re.IGNORECASE)
+ for ValueItem in ValueList:
+ if not ReIsValidHexByte.match(ValueItem):
+ return False
+
+ elif Type == 'UINT8' or Type == 'UINT16' or Type == 'UINT32' or Type == 'UINT64':
+
+ ReIsValidUint8z = re.compile('^0[x|X][a-fA-F0-9]{2}$')
+ ReIsValidUint16z = re.compile('^0[x|X][a-fA-F0-9]{4}$')
+ ReIsValidUint32z = re.compile('^0[x|X][a-fA-F0-9]{8}$')
+ ReIsValidUint64z = re.compile('^0[x|X][a-fA-F0-9]{16}$')
+
+ if not ReIsValidUint8z.match(Value) and Type == 'UINT8':
+ return False
+ elif not ReIsValidUint16z.match(Value) and Type == 'UINT16':
+ return False
+ elif not ReIsValidUint32z.match(Value) and Type == 'UINT32':
+ return False
+ elif not ReIsValidUint64z.match(Value) and Type == 'UINT64':
+ return False
+ else:
+ #
+ # Since we assume the DEC file always correct, should never go to here.
+ #
+ pass
+
+ return True
+
+def SetPcdName(PcdItem, CurrentLineOfPcdItem, PcdItemObj):
+ #
+ # Only PCD Name specified
+ # <PcdName> ::= <TokenSpaceGuidCName> "." <TokenCName>
+ #
+ PcdId = GetSplitValueList(PcdItem[0], DT.TAB_SPLIT)
+ if len(PcdId) != 2:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PCD_NAME_FORMAT_ERROR,
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=CurrentLineOfPcdItem[0])
+ else:
+ #
+ # Validate PcdTokenSpaceGuidCName
+ #
+ if not IsValidCVariableName(PcdId[0]):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PCD_CVAR_GUID,
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=PcdId[0])
+ if not IsValidCVariableName(PcdId[1]):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_PCD_CVAR_PCDCNAME,
+ File=CurrentLineOfPcdItem[2],
+ Line=CurrentLineOfPcdItem[1],
+ ExtraData=PcdId[1])
+ PcdItemObj.SetTokenSpaceGuidCName(PcdId[0])
+ PcdItemObj.SetCName(PcdId[1])
+
+ return PcdItemObj \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py
new file mode 100644
index 0000000000..4df62bb459
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfPpiObject.py
@@ -0,0 +1,343 @@
+## @file
+# This file is used to define class objects of INF file [Ppis] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfPpiObject
+'''
+
+from Library.ParserValidate import IsValidCVariableName
+from Library.CommentParsing import ParseComment
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+
+from Library.Misc import Sdict
+from Library import DataType as DT
+import Logger.Log as Logger
+from Logger import ToolError
+from Logger import StringTable as ST
+
+def ParsePpiComment(CommentsList, InfPpiItemObj):
+ PreNotify = None
+ PreUsage = None
+ PreHelpText = ''
+ BlockFlag = -1
+ CommentInsList = []
+ Count = 0
+ for CommentItem in CommentsList:
+ Count = Count + 1
+ CommentItemUsage, \
+ CommentItemNotify, \
+ CommentItemString, \
+ CommentItemHelpText = \
+ ParseComment(CommentItem,
+ DT.ALL_USAGE_TOKENS,
+ DT.PPI_NOTIFY_TOKENS,
+ ['PPI'],
+ False)
+
+ #
+ # To avoid PyLint error
+ #
+ if CommentItemString:
+ pass
+
+ if CommentItemHelpText == None:
+ CommentItemHelpText = ''
+ if Count == len(CommentsList) and CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = DT.END_OF_LINE
+ #
+ # For the Last comment Item, set BlockFlag.
+ #
+ if Count == len(CommentsList):
+ if BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
+ BlockFlag = 4
+ else:
+ BlockFlag = 3
+ elif BlockFlag == -1:
+ BlockFlag = 4
+
+ #
+ # Comment USAGE and NOTIFY information are "UNDEFINED"
+ #
+ if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
+ if BlockFlag == -1:
+ BlockFlag = 1
+ elif BlockFlag == 1:
+ BlockFlag = 2
+ else:
+ if BlockFlag == 1 or BlockFlag == 2:
+ BlockFlag = 3
+ #
+ # An item have Usage or Notify information and the first time get this information
+ #
+ elif BlockFlag == -1:
+ BlockFlag = 4
+
+ #
+ # Combine two comment line if they are generic comment
+ #
+ if CommentItemUsage == CommentItemNotify == PreUsage == PreNotify == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
+ #
+ # Store this information for next line may still need combine operation.
+ #
+ PreHelpText = CommentItemHelpText
+
+ if BlockFlag == 4:
+ CommentItemIns = InfPpiItemCommentContent()
+ CommentItemIns.SetUsage(CommentItemUsage)
+ CommentItemIns.SetNotify(CommentItemNotify)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreNotify = None
+ PreHelpText = ''
+
+ elif BlockFlag == 3:
+ #
+ # Add previous help string
+ #
+ CommentItemIns = InfPpiItemCommentContent()
+ CommentItemIns.SetUsage(DT.ITEM_UNDEFINED)
+ CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
+ if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
+ PreHelpText += DT.END_OF_LINE
+ CommentItemIns.SetHelpStringItem(PreHelpText)
+ CommentInsList.append(CommentItemIns)
+ #
+ # Add Current help string
+ #
+ CommentItemIns = InfPpiItemCommentContent()
+ CommentItemIns.SetUsage(CommentItemUsage)
+ CommentItemIns.SetNotify(CommentItemNotify)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreNotify = None
+ PreHelpText = ''
+ else:
+ PreUsage = CommentItemUsage
+ PreNotify = CommentItemNotify
+ PreHelpText = CommentItemHelpText
+
+ InfPpiItemObj.SetCommentList(CommentInsList)
+
+ return InfPpiItemObj
+
+class InfPpiItemCommentContent():
+ def __init__(self):
+ #
+ # ## SOMETIMES_CONSUMES ## HelpString
+ #
+ self.UsageItem = ''
+ #
+ # Help String
+ #
+ self.HelpStringItem = ''
+ self.Notify = ''
+ self.CommentList = []
+
+ def SetUsage(self, UsageItem):
+ self.UsageItem = UsageItem
+ def GetUsage(self):
+ return self.UsageItem
+
+ def SetNotify(self, Notify):
+ if Notify != DT.ITEM_UNDEFINED:
+ self.Notify = 'true'
+ def GetNotify(self):
+ return self.Notify
+
+ def SetHelpStringItem(self, HelpStringItem):
+ self.HelpStringItem = HelpStringItem
+ def GetHelpStringItem(self):
+ return self.HelpStringItem
+
+class InfPpiItem():
+ def __init__(self):
+ self.Name = ''
+ self.FeatureFlagExp = ''
+ self.SupArchList = []
+ self.CommentList = []
+
+ def SetName(self, Name):
+ self.Name = Name
+ def GetName(self):
+ return self.Name
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ def SetCommentList(self, CommentList):
+ self.CommentList = CommentList
+ def GetCommentList(self):
+ return self.CommentList
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+##
+#
+#
+#
+class InfPpiObject():
+ def __init__(self):
+ self.Ppis = Sdict()
+ #
+ # Macro defined in this section should be only used in this section.
+ #
+ self.Macros = {}
+
+ def SetPpi(self, PpiList, Arch = None):
+ __SupArchList = []
+ for ArchItem in Arch:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+ __SupArchList.append(ArchItem)
+
+ for Item in PpiList:
+ #
+ # Get Comment content of this protocol
+ #
+ CommentsList = None
+ if len(Item) == 3:
+ CommentsList = Item[1]
+ CurrentLineOfItem = Item[2]
+ Item = Item[0]
+ InfPpiItemObj = InfPpiItem()
+ if len(Item) >= 1 and len(Item) <= 2:
+ #
+ # Only CName contained
+ #
+ if not IsValidCVariableName(Item[0]):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ if (Item[0] != ''):
+ InfPpiItemObj.SetName(Item[0])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_CNAME_MISSING,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ #
+ # Have FeatureFlag information
+ #
+ if len(Item) == 2:
+ #
+ # Contained CName and Feature Flag Express
+ # <statements> ::= <CName> ["|" <FeatureFlagExpress>]
+ # Item[1] should not be empty
+ #
+ if Item[1].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ #
+ # Validate Feature Flag Express for PPI entry
+ # Item[1] contain FFE information
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ InfPpiItemObj.SetFeatureFlagExp(Item[1])
+ if len(Item) != 1 and len(Item) != 2:
+ #
+ # Invalid format of Ppi statement
+ #
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+
+ #
+ # Get/Set Usage and HelpString for PPI entry
+ #
+ if CommentsList != None and len(CommentsList) != 0:
+ InfPpiItemObj = ParsePpiComment(CommentsList, InfPpiItemObj)
+ else:
+ CommentItemIns = InfPpiItemCommentContent()
+ CommentItemIns.SetUsage(DT.ITEM_UNDEFINED)
+ CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
+ InfPpiItemObj.SetCommentList([CommentItemIns])
+
+ InfPpiItemObj.SetSupArchList(__SupArchList)
+
+ #
+ # Determine PPI name duplicate. Follow below rule:
+ #
+ # A PPI must not be duplicated within a [Ppis] section.
+ # A PPI may appear in multiple architectural [Ppis]
+ # sections. A PPI listed in an architectural [Ppis]
+ # section must not be listed in the common architectural
+ # [Ppis] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+ for Item in self.Ppis:
+ if Item.GetName() == InfPpiItemObj.GetName():
+ ItemSupArchList = Item.GetSupArchList()
+ for ItemArch in ItemSupArchList:
+ for PpiItemObjArch in __SupArchList:
+ if ItemArch == PpiItemObjArch:
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+ #
+ pass
+ if ItemArch.upper() == 'COMMON' or PpiItemObjArch.upper() == 'COMMON':
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+ #
+ pass
+
+ if self.Ppis.has_key((InfPpiItemObj)):
+ PpiList = self.Ppis[InfPpiItemObj]
+ PpiList.append(InfPpiItemObj)
+ self.Ppis[InfPpiItemObj] = PpiList
+ else:
+ PpiList = []
+ PpiList.append(InfPpiItemObj)
+ self.Ppis[InfPpiItemObj] = PpiList
+
+ return True
+
+
+ def GetPpi(self):
+ return self.Ppis \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py
new file mode 100644
index 0000000000..c94e53c98f
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfProtocolObject.py
@@ -0,0 +1,311 @@
+## @file
+# This file is used to define class objects of INF file [Protocols] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfProtocolObject
+'''
+
+from Library.ParserValidate import IsValidCVariableName
+from Library.CommentParsing import ParseComment
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+
+from Library.Misc import Sdict
+
+from Object.Parser.InfMisc import ErrorInInf
+
+from Library import DataType as DT
+from Logger import StringTable as ST
+
+def ParseProtocolComment(CommentsList, InfProtocolItemObj):
+ CommentInsList = []
+ PreUsage = None
+ PreNotify = None
+ PreHelpText = ''
+ BlockFlag = -1
+ Count = 0
+ for CommentItem in CommentsList:
+ Count = Count + 1
+ CommentItemUsage, \
+ CommentItemNotify, \
+ CommentItemString, \
+ CommentItemHelpText = \
+ ParseComment(CommentItem,
+ DT.PROTOCOL_USAGE_TOKENS,
+ DT.PROTOCOL_NOTIFY_TOKENS,
+ ['PROTOCOL'],
+ False)
+
+ if CommentItemString:
+ pass
+
+ if CommentItemHelpText == None:
+ CommentItemHelpText = ''
+ if Count == len(CommentsList) and CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = DT.END_OF_LINE
+
+ if Count == len(CommentsList):
+ if BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
+ BlockFlag = 4
+ else:
+ BlockFlag = 3
+ elif BlockFlag == -1:
+ BlockFlag = 4
+
+ if BlockFlag == -1 or BlockFlag == 1 or BlockFlag == 2:
+ if CommentItemUsage == CommentItemNotify == DT.ITEM_UNDEFINED:
+ if BlockFlag == -1:
+ BlockFlag = 1
+ elif BlockFlag == 1:
+ BlockFlag = 2
+ else:
+ if BlockFlag == 1 or BlockFlag == 2:
+ BlockFlag = 3
+ elif BlockFlag == -1:
+ BlockFlag = 4
+
+ #
+ # Combine two comment line if they are generic comment
+ #
+ if CommentItemUsage == CommentItemNotify == PreUsage == PreNotify == DT.ITEM_UNDEFINED:
+ CommentItemHelpText = PreHelpText + DT.END_OF_LINE + CommentItemHelpText
+
+ PreHelpText = CommentItemHelpText
+
+ if BlockFlag == 4:
+ CommentItemIns = InfProtocolItemCommentContent()
+ CommentItemIns.SetUsageItem(CommentItemUsage)
+ CommentItemIns.SetNotify(CommentItemNotify)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreNotify = None
+ PreHelpText = ''
+
+ elif BlockFlag == 3:
+ #
+ # Add previous help string
+ #
+ CommentItemIns = InfProtocolItemCommentContent()
+ CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
+ CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
+ if PreHelpText == '' or PreHelpText.endswith(DT.END_OF_LINE):
+ PreHelpText += DT.END_OF_LINE
+ CommentItemIns.SetHelpStringItem(PreHelpText)
+ CommentInsList.append(CommentItemIns)
+ #
+ # Add Current help string
+ #
+ CommentItemIns = InfProtocolItemCommentContent()
+ CommentItemIns.SetUsageItem(CommentItemUsage)
+ CommentItemIns.SetNotify(CommentItemNotify)
+ CommentItemIns.SetHelpStringItem(CommentItemHelpText)
+ CommentInsList.append(CommentItemIns)
+
+ BlockFlag = -1
+ PreUsage = None
+ PreNotify = None
+ PreHelpText = ''
+
+ else:
+ PreUsage = CommentItemUsage
+ PreNotify = CommentItemNotify
+ PreHelpText = CommentItemHelpText
+
+ InfProtocolItemObj.SetCommentList(CommentInsList)
+
+ return InfProtocolItemObj
+
+class InfProtocolItemCommentContent():
+ def __init__(self):
+ #
+ # ## SOMETIMES_CONSUMES ## HelpString
+ #
+ self.UsageItem = ''
+ #
+ # Help String
+ #
+ self.HelpStringItem = ''
+ self.Notify = ''
+ self.CommentList = []
+
+ def SetUsageItem(self, UsageItem):
+ self.UsageItem = UsageItem
+ def GetUsageItem(self):
+ return self.UsageItem
+
+ def SetNotify(self, Notify):
+ if Notify != DT.ITEM_UNDEFINED:
+ self.Notify = 'true'
+ def GetNotify(self):
+ return self.Notify
+
+ def SetHelpStringItem(self, HelpStringItem):
+ self.HelpStringItem = HelpStringItem
+ def GetHelpStringItem(self):
+ return self.HelpStringItem
+
+class InfProtocolItem():
+ def __init__(self):
+ self.Name = ''
+ self.FeatureFlagExp = ''
+ self.SupArchList = []
+ self.CommentList = []
+
+ def SetName(self, Name):
+ self.Name = Name
+ def GetName(self):
+ return self.Name
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+ def SetCommentList(self, CommentList):
+ self.CommentList = CommentList
+ def GetCommentList(self):
+ return self.CommentList
+
+##
+#
+#
+#
+class InfProtocolObject():
+ def __init__(self):
+ self.Protocols = Sdict()
+ #
+ # Macro defined in this section should be only used in this section.
+ #
+ self.Macros = {}
+
+ def SetProtocol(self, ProtocolContent, Arch = None,):
+ __SupArchList = []
+ for ArchItem in Arch:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+ __SupArchList.append(ArchItem)
+
+ for Item in ProtocolContent:
+ #
+ # Get Comment content of this protocol
+ #
+ CommentsList = None
+ if len(Item) == 3:
+ CommentsList = Item[1]
+ CurrentLineOfItem = Item[2]
+ LineInfo = (CurrentLineOfItem[2], CurrentLineOfItem[1], CurrentLineOfItem[0])
+ Item = Item[0]
+ InfProtocolItemObj = InfProtocolItem()
+ if len(Item) >= 1 and len(Item) <= 2:
+ #
+ # Only CName contained
+ #
+ if not IsValidCVariableName(Item[0]):
+ ErrorInInf(ST.ERR_INF_PARSER_INVALID_CNAME%(Item[0]),
+ LineInfo=LineInfo)
+ if (Item[0] != ''):
+ InfProtocolItemObj.SetName(Item[0])
+ else:
+ ErrorInInf(ST.ERR_INF_PARSER_CNAME_MISSING,
+ LineInfo=LineInfo)
+ if len(Item) == 2:
+ #
+ # Contained CName and Feature Flag Express
+ # <statements> ::= <CName> ["|"
+ # <FeatureFlagExpress>]
+ # For Protocol Object
+ #
+ if Item[1].strip() == '':
+ ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ LineInfo=LineInfo)
+ #
+ # Validate Feature Flag Express for Item[1]
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(Item[1].strip())
+ if not FeatureFlagRtv[0]:
+ ErrorInInf(ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ LineInfo=LineInfo)
+ InfProtocolItemObj.SetFeatureFlagExp(Item[1])
+
+ if len(Item) < 1 or len(Item) > 2:
+ #
+ # Invalid format of Protocols statement
+ #
+ ErrorInInf(ST.ERR_INF_PARSER_GUID_PPI_PROTOCOL_SECTION_CONTENT_ERROR,
+ LineInfo=LineInfo)
+
+ #
+ # Get/Set Usage and HelpString for Protocol entry
+ #
+ if CommentsList != None and len(CommentsList) != 0:
+ InfProtocolItemObj = ParseProtocolComment(CommentsList, InfProtocolItemObj)
+ else:
+ CommentItemIns = InfProtocolItemCommentContent()
+ CommentItemIns.SetUsageItem(DT.ITEM_UNDEFINED)
+ CommentItemIns.SetNotify(DT.ITEM_UNDEFINED)
+ InfProtocolItemObj.SetCommentList([CommentItemIns])
+
+ InfProtocolItemObj.SetSupArchList(__SupArchList)
+
+ #
+ # Determine protocol name duplicate. Follow below rule:
+ #
+ # A protocol must not be duplicated within a [Protocols] section.
+ # A protocol may appear in multiple architectural [Protocols]
+ # sections. A protocol listed in an architectural [Protocols]
+ # section must not be listed in the common architectural
+ # [Protocols] section.
+ #
+ # NOTE: This check will not report error now.
+ #
+ for Item in self.Protocols:
+ if Item.GetName() == InfProtocolItemObj.GetName():
+ ItemSupArchList = Item.GetSupArchList()
+ for ItemArch in ItemSupArchList:
+ for ProtocolItemObjArch in __SupArchList:
+ if ItemArch == ProtocolItemObjArch:
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE
+ #
+ pass
+ if ItemArch.upper() == 'COMMON' or ProtocolItemObjArch.upper() == 'COMMON':
+ #
+ # ST.ERR_INF_PARSER_ITEM_DUPLICATE_COMMON
+ #
+ pass
+
+ if self.Protocols.has_key((InfProtocolItemObj)):
+ ProcotolList = self.Protocols[InfProtocolItemObj]
+ ProcotolList.append(InfProtocolItemObj)
+ self.Protocols[InfProtocolItemObj] = ProcotolList
+ else:
+ ProcotolList = []
+ ProcotolList.append(InfProtocolItemObj)
+ self.Protocols[InfProtocolItemObj] = ProcotolList
+
+ return True
+
+ def GetProtocol(self):
+ return self.Protocols
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py
new file mode 100644
index 0000000000..9988f8ecfe
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfSoucesObject.py
@@ -0,0 +1,240 @@
+## @file
+# This file is used to define class objects of INF file [Sources] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfSourcesObject
+'''
+
+import os
+
+from Logger import StringTable as ST
+from Logger import ToolError
+import Logger.Log as Logger
+from Library import GlobalData
+
+from Library.Misc import Sdict
+from Library.ExpressionValidate import IsValidFeatureFlagExp
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+from Library.Misc import ValidFile
+from Library.ParserValidate import IsValidFamily
+from Library.ParserValidate import IsValidPath
+
+## __GenSourceInstance
+#
+#
+def GenSourceInstance(Item, CurrentLineOfItem, ItemObj):
+
+ IsValidFileFlag = False
+
+ if len(Item) < 6 and len(Item) >= 1:
+ #
+ # File | Family | TagName | ToolCode | FeatureFlagExpr
+ #
+ if len(Item) == 5:
+ #
+ # Validate Feature Flag Express
+ #
+ if Item[4].strip() == '':
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_MISSING,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ #
+ # Validate FFE
+ #
+ FeatureFlagRtv = IsValidFeatureFlagExp(Item[4].strip())
+ if not FeatureFlagRtv[0]:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FEATURE_FLAG_EXP_SYNTAX_INVLID%(FeatureFlagRtv[1]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ ItemObj.SetFeatureFlagExp(Item[4])
+ if len(Item) >= 4:
+ if Item[3].strip() == '':
+ ItemObj.SetToolCode(Item[3])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_TOOLCODE_NOT_PERMITTED%(Item[2]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ if len(Item) >= 3:
+ if Item[2].strip() == '':
+ ItemObj.SetTagName(Item[2])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_TAGNAME_NOT_PERMITTED%(Item[2]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ if len(Item) >= 2:
+ if IsValidFamily(Item[1].strip()):
+ #
+ # To align with UDP specification. "*" is not permitted in UDP specification
+ #
+ if Item[1].strip() == "*":
+ Item[1] = ""
+ ItemObj.SetFamily(Item[1])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_SOURCE_SECTION_FAMILY_INVALID%(Item[1]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ if len(Item) >= 1:
+ #
+ # Validate file name exist.
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(GlobalData.gINF_MODULE_DIR, Item[0])))
+ if not (ValidFile(FullFileName) or ValidFile(Item[0])):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_FILELIST_EXIST%(Item[0]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+
+ #
+ # Validate file exist/format.
+ #
+
+ if IsValidPath(Item[0], GlobalData.gINF_MODULE_DIR):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(Item[0]),
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+ return False
+ if IsValidFileFlag:
+ ItemObj.SetSourceFileName(Item[0])
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_SOURCES_SECTION_CONTENT_ERROR,
+ File=CurrentLineOfItem[2],
+ Line=CurrentLineOfItem[1],
+ ExtraData=CurrentLineOfItem[0])
+
+ return ItemObj
+
+## InfSourcesItemObject()
+#
+#
+class InfSourcesItemObject():
+ def __init__(self, \
+ SourceFileName = '', \
+ Family = '', \
+ TagName = '', \
+ ToolCode = '', \
+ FeatureFlagExp = ''):
+ self.SourceFileName = SourceFileName
+ self.Family = Family
+ self.TagName = TagName
+ self.ToolCode = ToolCode
+ self.FeatureFlagExp = FeatureFlagExp
+ self.HeaderString = ''
+ self.TailString = ''
+ self.SupArchList = []
+
+ def SetSourceFileName(self, SourceFilename):
+ self.SourceFileName = SourceFilename
+ def GetSourceFileName(self):
+ return self.SourceFileName
+
+ def SetFamily(self, Family):
+ self.Family = Family
+ def GetFamily(self):
+ return self.Family
+
+ def SetTagName(self, TagName):
+ self.TagName = TagName
+ def GetTagName(self):
+ return self.TagName
+
+ def SetToolCode(self, ToolCode):
+ self.ToolCode = ToolCode
+ def GetToolCode(self):
+ return self.ToolCode
+
+ def SetFeatureFlagExp(self, FeatureFlagExp):
+ self.FeatureFlagExp = FeatureFlagExp
+ def GetFeatureFlagExp(self):
+ return self.FeatureFlagExp
+
+ def SetHeaderString(self, HeaderString):
+ self.HeaderString = HeaderString
+ def GetHeaderString(self):
+ return self.HeaderString
+
+ def SetTailString(self, TailString):
+ self.TailString = TailString
+ def GetTailString(self):
+ return self.TailString
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+##
+#
+#
+#
+class InfSourcesObject(InfSectionCommonDef):
+ def __init__(self):
+ self.Sources = Sdict()
+ InfSectionCommonDef.__init__(self)
+
+ def SetSources(self, SourceList, Arch = None):
+ __SupArchList = []
+ for ArchItem in Arch:
+ #
+ # Validate Arch
+ #
+ if (ArchItem == '' or ArchItem == None):
+ ArchItem = 'COMMON'
+ __SupArchList.append(ArchItem)
+
+ for Item in SourceList:
+ ItemObj = InfSourcesItemObject()
+ CurrentLineOfItem = Item[2]
+ Item = Item[0]
+
+ ItemObj = GenSourceInstance(Item, CurrentLineOfItem, ItemObj)
+
+ ItemObj.SetSupArchList(__SupArchList)
+
+ if self.Sources.has_key((ItemObj)):
+ SourceContent = self.Sources[ItemObj]
+ SourceContent.append(ItemObj)
+ self.Sources[ItemObj] = SourceContent
+ else:
+ SourceContent = []
+ SourceContent.append(ItemObj)
+ self.Sources[ItemObj] = SourceContent
+
+ return True
+
+ def GetSources(self):
+ return self.Sources
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py b/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py
new file mode 100644
index 0000000000..d576cffbd0
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/InfUserExtensionObject.py
@@ -0,0 +1,133 @@
+## @file
+# This file is used to define class objects of INF file [UserExtension] section.
+# It will consumed by InfParser.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+InfUserExtensionsObject
+'''
+
+from Logger import StringTable as ST
+from Logger import ToolError
+import Logger.Log as Logger
+from Library import GlobalData
+
+from Library.Misc import Sdict
+
+class InfUserExtensionItem():
+ def __init__(self,
+ Content = '',
+ UserId = '',
+ IdString = ''):
+ self.Content = Content
+ self.UserId = UserId
+ self.IdString = IdString
+ self.SupArchList = []
+
+ def SetContent(self, Content):
+ self.Content = Content
+ def GetContent(self):
+ return self.Content
+
+ def SetUserId(self, UserId):
+ self.UserId = UserId
+ def GetUserId(self):
+ return self.UserId
+
+ def SetIdString(self, IdString):
+ self.IdString = IdString
+ def GetIdString(self):
+ return self.IdString
+
+ def SetSupArchList(self, SupArchList):
+ self.SupArchList = SupArchList
+ def GetSupArchList(self):
+ return self.SupArchList
+
+##
+#
+#
+#
+class InfUserExtensionObject():
+ def __init__(self):
+ self.UserExtension = Sdict()
+
+ def SetUserExtension(self, UserExtensionCont, IdContent=None, LineNo=None):
+ if not UserExtensionCont or UserExtensionCont == '':
+ return True
+ #
+ # IdContent is a list contain UserId and IdString
+ # For this call the general section header parser, if no definition of
+ # IdString/UserId, it will return 'COMMON'
+ #
+ for IdContentItem in IdContent:
+ InfUserExtensionItemObj = InfUserExtensionItem()
+ if IdContentItem[0] == 'COMMON':
+ UserId = ''
+ else:
+ UserId = IdContentItem[0]
+
+ if IdContentItem[1] == 'COMMON':
+ IdString = ''
+ else:
+ IdString = IdContentItem[1]
+
+ #
+ # Fill UserExtensionObj members.
+ #
+ InfUserExtensionItemObj.SetUserId(UserId)
+ InfUserExtensionItemObj.SetIdString(IdString)
+ InfUserExtensionItemObj.SetContent(UserExtensionCont)
+ InfUserExtensionItemObj.SetSupArchList(IdContentItem[2])
+
+ for CheckItem in self.UserExtension:
+ if IdContentItem[0] == CheckItem[0] and IdContentItem[1] == CheckItem[1]:
+ if IdContentItem[2].upper() == 'COMMON' or CheckItem[2].upper() == 'COMMON':
+ #
+ # For COMMON ARCH type, do special check.
+ #
+ Logger.Error('InfParser',
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR%\
+ (IdContentItem[0] + '.' + IdContentItem[1] + '.' + IdContentItem[2]),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=None)
+
+ if self.UserExtension.has_key(IdContentItem):
+ #
+ # Each UserExtensions section header must have a unique set
+ # of UserId, IdString and Arch values.
+ # This means that the same UserId can be used in more than one
+ # section header, provided the IdString or Arch values are
+ # different. The same IdString values can be used in more than
+ # one section header if the UserId or Arch values are
+ # different. The same UserId and the same IdString can be used
+ # in a section header if the Arch values are different in each
+ # of the section headers.
+ #
+ Logger.Error('InfParser',
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR%\
+ (IdContentItem[0] + '.' + IdContentItem[1] + '.' + IdContentItem[2]),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=None)
+ else:
+ UserExtensionList = []
+ UserExtensionList.append(InfUserExtensionItemObj)
+ self.UserExtension[IdContentItem] = UserExtensionList
+
+ return True
+
+ def GetUserExtension(self):
+ return self.UserExtension \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/Parser/__init__.py b/BaseTools/Source/Python/UPT/Object/Parser/__init__.py
new file mode 100644
index 0000000000..b457c3c97b
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/Parser/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Object' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+PARSER
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Object/__init__.py b/BaseTools/Source/Python/UPT/Object/__init__.py
new file mode 100644
index 0000000000..7925ab65ba
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Object/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Object' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Object
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/DecParser.py b/BaseTools/Source/Python/UPT/Parser/DecParser.py
new file mode 100644
index 0000000000..823cf71e5e
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/DecParser.py
@@ -0,0 +1,989 @@
+## @file
+# This file is used to parse DEC file. It will consumed by DecParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+'''
+DecParser
+'''
+## Import modules
+#
+import Logger.Log as Logger
+from Logger.ToolError import FILE_PARSE_FAILURE
+from Logger.ToolError import FILE_OPEN_FAILURE
+from Logger import StringTable as ST
+
+import Library.DataType as DT
+from Library.ParserValidate import IsValidToken
+from Library.ParserValidate import IsValidPath
+from Library.ParserValidate import IsValidCFormatGuid
+from Library.ParserValidate import IsValidIdString
+from Library.ParserValidate import IsValidUserId
+from Library.ParserValidate import IsValidArch
+from Library.ParserValidate import IsValidWord
+from Parser.DecParserMisc import TOOL_NAME
+from Parser.DecParserMisc import CleanString
+from Parser.DecParserMisc import IsValidPcdDatum
+from Parser.DecParserMisc import ParserHelper
+from Parser.DecParserMisc import StripRoot
+from Parser.DecParserMisc import VERSION_PATTERN
+from Parser.DecParserMisc import CVAR_PATTERN
+from Parser.DecParserMisc import PCD_TOKEN_PATTERN
+from Parser.DecParserMisc import MACRO_PATTERN
+from Parser.DecParserMisc import FileContent
+from Object.Parser.DecObject import _DecComments
+from Object.Parser.DecObject import DecDefineObject
+from Object.Parser.DecObject import DecDefineItemObject
+from Object.Parser.DecObject import DecIncludeObject
+from Object.Parser.DecObject import DecIncludeItemObject
+from Object.Parser.DecObject import DecLibraryclassObject
+from Object.Parser.DecObject import DecLibraryclassItemObject
+from Object.Parser.DecObject import DecGuidObject
+from Object.Parser.DecObject import DecPpiObject
+from Object.Parser.DecObject import DecProtocolObject
+from Object.Parser.DecObject import DecGuidItemObject
+from Object.Parser.DecObject import DecUserExtensionObject
+from Object.Parser.DecObject import DecUserExtensionItemObject
+from Object.Parser.DecObject import DecPcdObject
+from Object.Parser.DecObject import DecPcdItemObject
+from Library.Misc import GuidStructureStringToGuidString
+from Library.Misc import CheckGuidRegFormat
+from Library.String import ReplaceMacro
+from Library.String import GetSplitValueList
+from Library.String import gMACRO_PATTERN
+from Library.String import ConvertSpecialChar
+
+##
+# _DecBase class for parsing
+#
+class _DecBase:
+ def __init__(self, RawData):
+ self._RawData = RawData
+ self._ItemDict = {}
+ self._LocalMacro = {}
+ #
+ # Data parsed by 'self' are saved to this object
+ #
+ self.ItemObject = None
+
+ def GetDataObject(self):
+ return self.ItemObject
+
+ ## BlockStart
+ #
+ # Called if a new section starts
+ #
+ def BlockStart(self):
+ self._LocalMacro = {}
+
+ ## _CheckReDefine
+ #
+ # @param Key: to be checked if multi-defined
+ # @param Scope: Format: [[SectionName, Arch], ...].
+ # If scope is none, use global scope
+ #
+ def _CheckReDefine(self, Key, Scope = None):
+ if not Scope:
+ Scope = self._RawData.CurrentScope
+ return
+
+ SecArch = []
+ #
+ # Copy scope to SecArch, avoid Scope be changed outside
+ #
+ SecArch[0:1] = Scope[:]
+ if Key not in self._ItemDict:
+ self._ItemDict[Key] = [[SecArch, self._RawData.LineIndex]]
+ return
+
+ for Value in self._ItemDict[Key]:
+ for SubValue in Scope:
+ #
+ # If current is common section
+ #
+ if SubValue[-1] == 'COMMON':
+ for Other in Value[0]:
+ # Key in common cannot be redefined in other arches
+ # [:-1] means stripping arch info
+ if Other[:-1] == SubValue[:-1]:
+ self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
+ return
+ continue
+ CommonScope = []
+ CommonScope[0:1] = SubValue
+ CommonScope[-1] = 'COMMON'
+ #
+ # Cannot be redefined if this key already defined in COMMON Or defined in same arch
+ #
+ if SubValue in Value[0] or CommonScope in Value[0]:
+ self._LoggerError(ST.ERR_DECPARSE_REDEFINE % (Key, Value[1]))
+ return
+ self._ItemDict[Key].append([SecArch, self._RawData.LineIndex])
+
+ ## CheckRequiredFields
+ # Some sections need to check if some fields exist, define section for example
+ # Derived class can re-implement, top parser will call this function after all parsing done
+ #
+ def CheckRequiredFields(self):
+ if self._RawData:
+ pass
+ return True
+
+ ## IsItemRequired
+ # In DEC spec, sections must have at least one statement except user
+ # extension.
+ # For example: "[guids" [<attribs>] "]" <EOL> <statements>+
+ # sub class can override this method to indicate if statement is a must.
+ #
+ def _IsStatementRequired(self):
+ if self._RawData:
+ pass
+ return False
+
+ def _LoggerError(self, ErrorString):
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
+ Line = self._RawData.LineIndex,
+ ExtraData=ErrorString + ST.ERR_DECPARSE_LINE % self._RawData.CurrentLine)
+
+ def _ReplaceMacro(self, String):
+ if gMACRO_PATTERN.findall(String):
+ String = ReplaceMacro(String, self._LocalMacro, False,
+ FileName = self._RawData.Filename,
+ Line = ['', self._RawData.LineIndex])
+ String = ReplaceMacro(String, self._RawData.Macros, False,
+ FileName = self._RawData.Filename,
+ Line = ['', self._RawData.LineIndex])
+ MacroUsed = gMACRO_PATTERN.findall(String)
+ if MacroUsed:
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE,
+ File=self._RawData.Filename,
+ Line = self._RawData.LineIndex,
+ ExtraData = ST.ERR_DECPARSE_MACRO_RESOLVE % (str(MacroUsed), String))
+ return String
+
+ def _MacroParser(self, String):
+ TokenList = GetSplitValueList(String, ' ', 1)
+ if len(TokenList) < 2 or TokenList[1] == '':
+ self._LoggerError(ST.ERR_DECPARSE_MACRO_PAIR)
+
+ TokenList = GetSplitValueList(TokenList[1], DT.TAB_EQUAL_SPLIT, 1)
+ if TokenList[0] == '':
+ self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME)
+ elif not IsValidToken(MACRO_PATTERN, TokenList[0]):
+ self._LoggerError(ST.ERR_DECPARSE_MACRO_NAME_UPPER % TokenList[0])
+
+ if len(TokenList) == 1:
+ self._LocalMacro[TokenList[0]] = ''
+ else:
+ self._LocalMacro[TokenList[0]] = self._ReplaceMacro(TokenList[1])
+
+ ## _ParseItem
+ #
+ # Parse specified item, this function must be derived by subclass
+ #
+ def _ParseItem(self):
+ if self._RawData:
+ pass
+ #
+ # Should never be called
+ #
+ return None
+
+
+ ## _TailCommentStrategy
+ #
+ # This function can be derived to parse tail comment
+ # default is it will not consume any lines
+ #
+ # @param Comment: Comment of current line
+ #
+ def _TailCommentStrategy(self, Comment):
+ if Comment:
+ pass
+ if self._RawData:
+ pass
+ return False
+
+ ## _StopCurrentParsing
+ #
+ # Called in Parse if current parsing should be stopped when encounter some
+ # keyword
+ # Default is section start and end
+ #
+ # @param Line: Current line
+ #
+ def _StopCurrentParsing(self, Line):
+ if self._RawData:
+ pass
+ return Line[0] == DT.TAB_SECTION_START and Line[-1] == DT.TAB_SECTION_END
+
+ ## _TryBackSlash
+ #
+ # Split comment and DEC content, concatenate lines if end of char is '\'
+ #
+ # @param ProcessedLine: ProcessedLine line
+ # @param ProcessedComments: ProcessedComments line
+ #
+ def _TryBackSlash(self, ProcessedLine, ProcessedComments):
+ CatLine = ''
+ Comment = ''
+ Line = ProcessedLine
+ CommentList = ProcessedComments
+ while not self._RawData.IsEndOfFile():
+ if Line == '':
+ self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
+ break
+
+ if Comment:
+ CommentList.append((Comment, self._RawData.LineIndex))
+ if Line[-1] != DT.TAB_SLASH:
+ CatLine += Line
+ break
+ elif len(Line) < 2 or Line[-2] != ' ':
+ self._LoggerError(ST.ERR_DECPARSE_BACKSLASH)
+ else:
+ CatLine += Line[:-1]
+ Line, Comment = CleanString(self._RawData.GetNextLine())
+ #
+ # Reach end of content
+ #
+ if self._RawData.IsEndOfFile():
+ if not CatLine:
+ if ProcessedLine[-1] == DT.TAB_SLASH:
+ self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
+ CatLine = ProcessedLine
+ else:
+ if not Line or Line[-1] == DT.TAB_SLASH:
+ self._LoggerError(ST.ERR_DECPARSE_BACKSLASH_EMPTY)
+ CatLine += Line
+
+ self._RawData.CurrentLine = self._ReplaceMacro(CatLine)
+ return CatLine, CommentList
+
+ ## Parse
+ # This is a template method in which other member functions which might
+ # override by sub class are called. It is responsible for reading file
+ # line by line, and call other member functions to parse. This function
+ # should not be re-implement by sub class.
+ #
+ def Parse(self):
+ HeadComments = []
+ TailComments = []
+
+ #======================================================================
+ # CurComments may pointer to HeadComments or TailComments
+ #======================================================================
+ CurComments = HeadComments
+ CurObj = None
+ ItemNum = 0
+ FromBuf = False
+
+ #======================================================================
+ # Used to report error information if empty section found
+ #======================================================================
+ Index = self._RawData.LineIndex
+ LineStr = self._RawData.CurrentLine
+ while not self._RawData.IsEndOfFile() or self._RawData.NextLine:
+ if self._RawData.NextLine:
+ #==============================================================
+ # Have processed line in buffer
+ #==============================================================
+ Line = self._RawData.NextLine
+ HeadComments.extend(self._RawData.HeadComment)
+ TailComments.extend(self._RawData.TailComment)
+ self._RawData.ResetNext()
+ Comment = ''
+ FromBuf = True
+ else:
+ #==============================================================
+ # No line in buffer, read next line
+ #==============================================================
+ Line, Comment = CleanString(self._RawData.GetNextLine())
+ FromBuf = False
+ if Line:
+ if not FromBuf and CurObj and TailComments:
+ #==========================================================
+ # Set tail comments to previous statement if not empty.
+ #==========================================================
+ CurObj.SetTailComment(CurObj.GetTailComment()+TailComments)
+
+ if not FromBuf:
+ del TailComments[:]
+ CurComments = TailComments
+ Comments = []
+ if Comment:
+ Comments = [(Comment, self._RawData.LineIndex)]
+
+ #==============================================================
+ # Try if last char of line has backslash
+ #==============================================================
+ Line, Comments = self._TryBackSlash(Line, Comments)
+ CurComments.extend(Comments)
+
+ #==============================================================
+ # Macro found
+ #==============================================================
+ if Line.startswith('DEFINE '):
+ self._MacroParser(Line)
+ del HeadComments[:]
+ del TailComments[:]
+ CurComments = HeadComments
+ continue
+
+ if self._StopCurrentParsing(Line):
+ #==========================================================
+ # This line does not belong to this parse,
+ # Save it, can be used by next parse
+ #==========================================================
+ self._RawData.SetNext(Line, HeadComments, TailComments)
+ break
+
+ Obj = self._ParseItem()
+ ItemNum += 1
+ if Obj:
+ Obj.SetHeadComment(Obj.GetHeadComment()+HeadComments)
+ Obj.SetTailComment(Obj.GetTailComment()+TailComments)
+ del HeadComments[:]
+ del TailComments[:]
+ CurObj = Obj
+ else:
+ CurObj = None
+ else:
+ if id(CurComments) == id(TailComments):
+ #==========================================================
+ # Check if this comment belongs to tail comment
+ #==========================================================
+ if not self._TailCommentStrategy(Comment):
+ CurComments = HeadComments
+
+ if Comment:
+ CurComments.append(((Comment, self._RawData.LineIndex)))
+ else:
+ del CurComments[:]
+
+ if self._IsStatementRequired() and ItemNum == 0:
+ Logger.Error(
+ TOOL_NAME, FILE_PARSE_FAILURE,
+ File=self._RawData.Filename,
+ Line=Index,
+ ExtraData=ST.ERR_DECPARSE_STATEMENT_EMPTY % LineStr
+ )
+
+## _DecDefine
+# Parse define section
+#
+class _DecDefine(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.ItemObject = DecDefineObject(RawData.Filename)
+ self._LocalMacro = self._RawData.Macros
+ self._DefSecNum = 0
+
+ #
+ # Each field has a function to validate
+ #
+ self.DefineValidation = {
+ DT.TAB_DEC_DEFINES_DEC_SPECIFICATION : self._SetDecSpecification,
+ DT.TAB_DEC_DEFINES_PACKAGE_NAME : self._SetPackageName,
+ DT.TAB_DEC_DEFINES_PACKAGE_GUID : self._SetPackageGuid,
+ DT.TAB_DEC_DEFINES_PACKAGE_VERSION : self._SetPackageVersion,
+ }
+
+ def BlockStart(self):
+ self._DefSecNum += 1
+ if self._DefSecNum > 1:
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_MULTISEC)
+
+ ## CheckRequiredFields
+ #
+ # Check required fields: DEC_SPECIFICATION, PACKAGE_NAME
+ # PACKAGE_GUID, PACKAGE_VERSION
+ #
+ def CheckRequiredFields(self):
+ Ret = False
+ if self.ItemObject.GetPackageSpecification() == '':
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
+ ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
+ elif self.ItemObject.GetPackageName() == '':
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
+ ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
+ elif self.ItemObject.GetPackageGuid() == '':
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
+ ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
+ elif self.ItemObject.GetPackageVersion() == '':
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._RawData.Filename,
+ ExtraData=ST.ERR_DECPARSE_DEFINE_REQUIRED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
+ else:
+ Ret = True
+ return Ret
+
+ def _ParseItem(self):
+ Line = self._RawData.CurrentLine
+ TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
+ if TokenList[0] == DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
+ pass
+ elif len(TokenList) < 2:
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_FORMAT)
+ elif TokenList[0] not in self.DefineValidation:
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_UNKNOWKEY % TokenList[0])
+ else:
+ self.DefineValidation[TokenList[0]](TokenList[1])
+
+ DefineItem = DecDefineItemObject()
+ if TokenList[0] != DT.TAB_DEC_DEFINES_PKG_UNI_FILE:
+ DefineItem.Key = TokenList[0]
+ DefineItem.Value = TokenList[1]
+ self.ItemObject.AddItem(DefineItem, self._RawData.CurrentScope)
+ return DefineItem
+
+ def _SetDecSpecification(self, Token):
+ if self.ItemObject.GetPackageSpecification():
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_DEC_SPECIFICATION)
+ if not IsValidToken('0[xX][0-9a-fA-F]{8}', Token):
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_SPEC)
+ self.ItemObject.SetPackageSpecification(Token)
+
+ def _SetPackageName(self, Token):
+ if self.ItemObject.GetPackageName():
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_NAME)
+ if not IsValidWord(Token):
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGNAME)
+ self.ItemObject.SetPackageName(Token)
+
+ def _SetPackageGuid(self, Token):
+ if self.ItemObject.GetPackageGuid():
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_GUID)
+ if not CheckGuidRegFormat(Token):
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
+ self.ItemObject.SetPackageGuid(Token)
+
+ def _SetPackageVersion(self, Token):
+ if self.ItemObject.GetPackageVersion():
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_DEFINED % DT.TAB_DEC_DEFINES_PACKAGE_VERSION)
+ if not IsValidToken(VERSION_PATTERN, Token):
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGVERSION)
+ else:
+ if not DT.TAB_SPLIT in Token:
+ Token = Token + '.0'
+ self.ItemObject._PkgVersion = Token
+
+## _DecInclude
+#
+# Parse include section
+#
+class _DecInclude(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.ItemObject = DecIncludeObject(RawData.Filename)
+
+ def _ParseItem(self):
+ Line = self._RawData.CurrentLine
+
+ if not IsValidPath(Line, self._RawData.PackagePath):
+ self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Line)
+
+ Item = DecIncludeItemObject(StripRoot(self._RawData.PackagePath, Line), self._RawData.PackagePath)
+ self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
+ return Item
+
+## _DecLibraryclass
+#
+# Parse library class section
+#
+class _DecLibraryclass(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.ItemObject = DecLibraryclassObject(RawData.Filename)
+
+ def _ParseItem(self):
+ Line = self._RawData.CurrentLine
+ TokenList = GetSplitValueList(Line, DT.TAB_VALUE_SPLIT)
+ if len(TokenList) != 2:
+ self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_SPLIT)
+ if TokenList[0] == '' or TokenList[1] == '':
+ self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_EMPTY)
+ if not IsValidToken('[A-Z][0-9A-Za-z]*', TokenList[0]):
+ self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_LIB)
+
+ self._CheckReDefine(TokenList[0])
+
+ Value = TokenList[1]
+ #
+ # Must end with .h
+ #
+ if not Value.endswith('.h'):
+ self._LoggerError(ST.ERR_DECPARSE_LIBCLASS_PATH_EXT)
+
+ #
+ # Path must be existed
+ #
+ if not IsValidPath(Value, self._RawData.PackagePath):
+ self._LoggerError(ST.ERR_DECPARSE_INCLUDE % Value)
+
+ Item = DecLibraryclassItemObject(TokenList[0], StripRoot(self._RawData.PackagePath, Value),
+ self._RawData.PackagePath)
+ self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
+ return Item
+
+## _DecPcd
+#
+# Parse PCD section
+#
+class _DecPcd(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.ItemObject = DecPcdObject(RawData.Filename)
+ #
+ # Used to check duplicate token
+ # Key is token space and token number (integer), value is C name
+ #
+ self.TokenMap = {}
+
+ def _ParseItem(self):
+ Line = self._RawData.CurrentLine
+ TokenList = Line.split(DT.TAB_VALUE_SPLIT)
+ if len(TokenList) < 4:
+ self._LoggerError(ST.ERR_DECPARSE_PCD_SPLIT)
+
+ #
+ # Token space guid C name
+ #
+ PcdName = GetSplitValueList(TokenList[0], DT.TAB_SPLIT)
+ if len(PcdName) != 2 or PcdName[0] == '' or PcdName[1] == '':
+ self._LoggerError(ST.ERR_DECPARSE_PCD_NAME)
+
+ Guid = PcdName[0]
+ if not IsValidToken(CVAR_PATTERN, Guid):
+ self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
+
+ #
+ # PCD C name
+ #
+ CName = PcdName[1]
+ if not IsValidToken(CVAR_PATTERN, CName):
+ self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_PCDCNAME)
+
+ self._CheckReDefine(Guid + DT.TAB_SPLIT + CName)
+
+ #
+ # Default value, may be C array, string or number
+ #
+ Data = DT.TAB_VALUE_SPLIT.join(TokenList[1:-2]).strip()
+
+ #
+ # PCD data type
+ #
+ DataType = TokenList[-2].strip()
+ Valid, Cause = IsValidPcdDatum(DataType, Data)
+ if not Valid:
+ self._LoggerError(Cause)
+ PcdType = self._RawData.CurrentScope[0][0]
+ if PcdType == DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() and DataType != 'BOOLEAN':
+ self._LoggerError(ST.ERR_DECPARSE_PCD_FEATUREFLAG)
+ #
+ # Token value is the last element in list.
+ #
+ Token = TokenList[-1].strip()
+ if not IsValidToken(PCD_TOKEN_PATTERN, Token):
+ self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN % Token)
+ elif not Token.startswith('0x') and not Token.startswith('0X'):
+ if long(Token) > 4294967295:
+ self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_INT % Token)
+ Token = hex(long(Token))[:-1]
+
+ IntToken = long(Token, 0)
+ if (Guid, IntToken) in self.TokenMap:
+ if self.TokenMap[Guid, IntToken] != CName:
+ self._LoggerError(ST.ERR_DECPARSE_PCD_TOKEN_UNIQUE%(Token))
+ else:
+ self.TokenMap[Guid, IntToken] = CName
+
+ Item = DecPcdItemObject(Guid, CName, Data, DataType, Token)
+ self.ItemObject.AddItem(Item, self._RawData.CurrentScope)
+ return Item
+
+## _DecGuid
+#
+# Parse GUID, PPI, Protocol section
+#
+class _DecGuid(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.GuidObj = DecGuidObject(RawData.Filename)
+ self.PpiObj = DecPpiObject(RawData.Filename)
+ self.ProtocolObj = DecProtocolObject(RawData.Filename)
+ self.ObjectDict = \
+ {
+ DT.TAB_GUIDS.upper() : self.GuidObj,
+ DT.TAB_PPIS.upper() : self.PpiObj,
+ DT.TAB_PROTOCOLS.upper() : self.ProtocolObj
+ }
+
+ def GetDataObject(self):
+ if self._RawData.CurrentScope:
+ return self.ObjectDict[self._RawData.CurrentScope[0][0]]
+ return None
+
+ def GetGuidObject(self):
+ return self.GuidObj
+
+ def GetPpiObject(self):
+ return self.PpiObj
+
+ def GetProtocolObject(self):
+ return self.ProtocolObj
+
+ def _ParseItem(self):
+ Line = self._RawData.CurrentLine
+ TokenList = GetSplitValueList(Line, DT.TAB_EQUAL_SPLIT, 1)
+ if len(TokenList) < 2:
+ self._LoggerError(ST.ERR_DECPARSE_CGUID)
+ if TokenList[0] == '':
+ self._LoggerError(ST.ERR_DECPARSE_CGUID_NAME)
+ if TokenList[1] == '':
+ self._LoggerError(ST.ERR_DECPARSE_CGUID_GUID)
+ if not IsValidToken(CVAR_PATTERN, TokenList[0]):
+ self._LoggerError(ST.ERR_DECPARSE_PCD_CVAR_GUID)
+
+ self._CheckReDefine(TokenList[0])
+
+ if TokenList[1][0] != '{':
+ if not CheckGuidRegFormat(TokenList[1]):
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_PKGGUID)
+ GuidString = TokenList[1]
+ else:
+ #
+ # Convert C format GUID to GUID string and Simple error check
+ #
+ GuidString = GuidStructureStringToGuidString(TokenList[1])
+ if TokenList[1][0] != '{' or TokenList[1][-1] != '}' or GuidString == '':
+ self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
+
+ #
+ # Check C format GUID
+ #
+ if not IsValidCFormatGuid(TokenList[1]):
+ self._LoggerError(ST.ERR_DECPARSE_CGUID_GUIDFORMAT)
+
+ Item = DecGuidItemObject(TokenList[0], TokenList[1], GuidString)
+ ItemObject = self.ObjectDict[self._RawData.CurrentScope[0][0]]
+ ItemObject.AddItem(Item, self._RawData.CurrentScope)
+ return Item
+
+## _DecUserExtension
+#
+# Parse user extention section
+#
+class _DecUserExtension(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.ItemObject = DecUserExtensionObject(RawData.Filename)
+ self._Headers = []
+ self._CurItems = []
+
+ def BlockStart(self):
+ self._CurItems = []
+ for Header in self._RawData.CurrentScope:
+ if Header in self._Headers:
+ self._LoggerError(ST.ERR_DECPARSE_UE_DUPLICATE)
+ else:
+ self._Headers.append(Header)
+
+ for Item in self._CurItems:
+ if Item.UserId == Header[1] and Item.IdString == Header[2]:
+ Item.ArchAndModuleType.append(Header[3])
+ break
+ else:
+ Item = DecUserExtensionItemObject()
+ Item.UserId = Header[1]
+ Item.IdString = Header[2]
+ Item.ArchAndModuleType.append(Header[3])
+ self._CurItems.append(Item)
+ self.ItemObject.AddItem(Item, None)
+ self._LocalMacro = {}
+
+ def _ParseItem(self):
+ Line = self._RawData.CurrentLine
+ Item = None
+ for Item in self._CurItems:
+ if Item.UserString:
+ Item.UserString = '\n'.join([Item.UserString, Line])
+ else:
+ Item.UserString = Line
+ return Item
+
+## Dec
+#
+# Top dec parser
+#
+class Dec(_DecBase, _DecComments):
+ def __init__(self, DecFile, Parse = True):
+ try:
+ Content = ConvertSpecialChar(open(DecFile, 'rb').readlines())
+ except BaseException:
+ Logger.Error(TOOL_NAME, FILE_OPEN_FAILURE, File=DecFile,
+ ExtraData=ST.ERR_DECPARSE_FILEOPEN % DecFile)
+ RawData = FileContent(DecFile, Content)
+
+ _DecComments.__init__(self)
+ _DecBase.__init__(self, RawData)
+
+ self._Define = _DecDefine(RawData)
+ self._Include = _DecInclude(RawData)
+ self._Guid = _DecGuid(RawData)
+ self._LibClass = _DecLibraryclass(RawData)
+ self._Pcd = _DecPcd(RawData)
+ self._UserEx = _DecUserExtension(RawData)
+
+ #
+ # DEC file supported data types (one type per section)
+ #
+ self._SectionParser = {
+ DT.TAB_DEC_DEFINES.upper() : self._Define,
+ DT.TAB_INCLUDES.upper() : self._Include,
+ DT.TAB_LIBRARY_CLASSES.upper() : self._LibClass,
+ DT.TAB_GUIDS.upper() : self._Guid,
+ DT.TAB_PPIS.upper() : self._Guid,
+ DT.TAB_PROTOCOLS.upper() : self._Guid,
+ DT.TAB_PCDS_FIXED_AT_BUILD_NULL.upper() : self._Pcd,
+ DT.TAB_PCDS_PATCHABLE_IN_MODULE_NULL.upper() : self._Pcd,
+ DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() : self._Pcd,
+ DT.TAB_PCDS_DYNAMIC_NULL.upper() : self._Pcd,
+ DT.TAB_PCDS_DYNAMIC_EX_NULL.upper() : self._Pcd,
+ DT.TAB_USER_EXTENSIONS.upper() : self._UserEx
+ }
+
+ if Parse:
+ self.ParseDecComment()
+ self.Parse()
+ #
+ # Parsing done, check required fields
+ #
+ self.CheckRequiredFields()
+
+ def CheckRequiredFields(self):
+ for SectionParser in self._SectionParser.values():
+ if not SectionParser.CheckRequiredFields():
+ return False
+ return True
+
+ ##
+ # Parse DEC file
+ #
+ def ParseDecComment(self):
+ while not self._RawData.IsEndOfFile():
+ Line, Comment = CleanString(self._RawData.GetNextLine())
+ #
+ # Header must be pure comment
+ #
+ if Line != '':
+ self._RawData.UndoNextLine()
+ break
+
+ if Comment:
+ self._HeadComment.append((Comment, self._RawData.LineIndex))
+ #
+ # Double '#' indicates end of header comments
+ #
+ if not Comment or Comment == DT.TAB_SPECIAL_COMMENT:
+ break
+
+ return
+
+ def _StopCurrentParsing(self, Line):
+ return False
+
+ def _ParseItem(self):
+ self._SectionHeaderParser()
+ if len(self._RawData.CurrentScope) == 0:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_EMPTY)
+
+ SectionObj = self._SectionParser[self._RawData.CurrentScope[0][0]]
+
+ SectionObj.BlockStart()
+ SectionObj.Parse()
+
+ return SectionObj.GetDataObject()
+
+ def _UserExtentionSectionParser(self):
+ self._RawData.CurrentScope = []
+ ArchList = set()
+ Section = self._RawData.CurrentLine[1:-1]
+
+ Par = ParserHelper(Section, self._RawData.Filename)
+ while not Par.End():
+ #
+ # User extention
+ #
+ Token = Par.GetToken()
+ if Token.upper() != DT.TAB_USER_EXTENSIONS.upper():
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_UE)
+ UserExtension = Token.upper()
+
+ Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
+ #
+ # UserID
+ #
+ Token = Par.GetToken()
+ if not IsValidUserId(Token):
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_USERID)
+ UserId = Token
+
+ Par.AssertChar(DT.TAB_SPLIT, ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
+ #
+ # IdString
+ #
+ Token = Par.GetToken()
+ if not IsValidIdString(Token):
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_UE_IDSTRING)
+ IdString = Token
+
+ Arch = 'COMMON'
+ if Par.Expect(DT.TAB_SPLIT):
+ Token = Par.GetToken()
+ Arch = Token.upper()
+ if not IsValidArch(Arch):
+ self._LoggerError(ST.ERR_DECPARSE_ARCH)
+ ArchList.add(Arch)
+
+ if [UserExtension, UserId, IdString, Arch] not in \
+ self._RawData.CurrentScope:
+ self._RawData.CurrentScope.append(
+ [UserExtension, UserId, IdString, Arch]
+ )
+
+ if not Par.Expect(DT.TAB_COMMA_SPLIT):
+ break
+ elif Par.End():
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMA)
+
+ Par.AssertEnd(ST.ERR_DECPARSE_SECTION_UE, self._RawData.LineIndex)
+
+ if 'COMMON' in ArchList and len(ArchList) > 1:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
+
+ ## Section header parser
+ #
+ # The section header is always in following format:
+ #
+ # [section_name.arch<.platform|module_type>]
+ #
+ def _SectionHeaderParser(self):
+ if self._RawData.CurrentLine[0] != DT.TAB_SECTION_START or self._RawData.CurrentLine[-1] != DT.TAB_SECTION_END:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_IDENTIFY)
+
+ RawSection = self._RawData.CurrentLine[1:-1].strip().upper()
+
+ #
+ # Check defines section which is only allowed to occur once and
+ # no arch can be followed
+ #
+ if RawSection.startswith(DT.TAB_DEC_DEFINES.upper()):
+ if RawSection != DT.TAB_DEC_DEFINES.upper():
+ self._LoggerError(ST.ERR_DECPARSE_DEFINE_SECNAME)
+
+ #
+ # Check user extension section
+ #
+ if RawSection.startswith(DT.TAB_USER_EXTENSIONS.upper()):
+ return self._UserExtentionSectionParser()
+
+ self._RawData.CurrentScope = []
+ SectionNames = []
+ ArchList = set()
+ for Item in GetSplitValueList(RawSection, DT.TAB_COMMA_SPLIT):
+ if Item == '':
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
+
+ ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
+
+ #
+ # different types of PCD are permissible in one section
+ #
+ SectionName = ItemList[0]
+ if SectionName not in self._SectionParser:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_UNKNOW % SectionName)
+
+ if SectionName not in SectionNames:
+ SectionNames.append(SectionName)
+
+ #
+ # In DEC specification, all section headers have at most two part:
+ # SectionName.Arch except UserExtention
+ #
+ if len(ItemList) > 2:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBTOOMANY % Item)
+
+ if DT.TAB_PCDS_FEATURE_FLAG_NULL.upper() in SectionNames and len(SectionNames) > 1:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_FEATUREFLAG % DT.TAB_PCDS_FEATURE_FLAG_NULL)
+ #
+ # S1 is always Arch
+ #
+ if len(ItemList) > 1:
+ Str1 = ItemList[1]
+ if not IsValidArch(Str1):
+ self._LoggerError(ST.ERR_DECPARSE_ARCH)
+ else:
+ Str1 = 'COMMON'
+ ArchList.add(Str1)
+
+ if [SectionName, Str1] not in self._RawData.CurrentScope:
+ self._RawData.CurrentScope.append([SectionName, Str1])
+ #
+ # 'COMMON' must not be used with specific ARCHs at the same section
+ #
+ if 'COMMON' in ArchList and len(ArchList) > 1:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_COMMON)
+
+ if len(SectionNames) == 0:
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_SUBEMPTY % self._RawData.CurrentLine)
+ if len(SectionNames) != 1:
+ for Sec in SectionNames:
+ if not Sec.startswith(DT.TAB_PCDS.upper()):
+ self._LoggerError(ST.ERR_DECPARSE_SECTION_NAME % str(SectionNames))
+
+ def GetDefineSectionObject(self):
+ return self._Define.GetDataObject()
+
+ def GetIncludeSectionObject(self):
+ return self._Include.GetDataObject()
+
+ def GetGuidSectionObject(self):
+ return self._Guid.GetGuidObject()
+
+ def GetProtocolSectionObject(self):
+ return self._Guid.GetProtocolObject()
+
+ def GetPpiSectionObject(self):
+ return self._Guid.GetPpiObject()
+
+ def GetLibraryClassSectionObject(self):
+ return self._LibClass.GetDataObject()
+
+ def GetPcdSectionObject(self):
+ return self._Pcd.GetDataObject()
+
+ def GetUserExtensionSectionObject(self):
+ return self._UserEx.GetDataObject()
+
+ def GetPackageSpecification(self):
+ return self._Define.GetDataObject().GetPackageSpecification()
+
+ def GetPackageName(self):
+ return self._Define.GetDataObject().GetPackageName()
+
+ def GetPackageGuid(self):
+ return self._Define.GetDataObject().GetPackageGuid()
+
+ def GetPackageVersion(self):
+ return self._Define.GetDataObject().GetPackageVersion()
+
+ def GetPackageUniFile(self):
+ return self._Define.GetDataObject().GetPackageUniFile()
diff --git a/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py b/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
new file mode 100644
index 0000000000..8d28979393
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/DecParserMisc.py
@@ -0,0 +1,371 @@
+## @file
+# This file is used to define helper class and function for DEC parser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+'''
+DecParserMisc
+'''
+
+## Import modules
+#
+import os
+import Logger.Log as Logger
+from Logger.ToolError import FILE_PARSE_FAILURE
+from Logger import StringTable as ST
+from Library.DataType import TAB_COMMENT_SPLIT
+from Library.DataType import TAB_COMMENT_EDK1_SPLIT
+from Library.ExpressionValidate import IsValidBareCString
+from Library.ParserValidate import IsValidCFormatGuid
+from Library.ExpressionValidate import IsValidLogicalExpr
+from Library.ExpressionValidate import IsValidStringTest
+from Library.Misc import CheckGuidRegFormat
+
+TOOL_NAME = 'DecParser'
+VERSION_PATTERN = '[0-9]+(\.[0-9]+)?'
+CVAR_PATTERN = '[_a-zA-Z][a-zA-Z0-9_]*'
+PCD_TOKEN_PATTERN = '(0[xX]0*[a-fA-F0-9]{1,8})|([0-9]+)'
+MACRO_PATTERN = '[A-Z][_A-Z0-9]*'
+
+## FileContent
+# Class to hold DEC file information
+#
+class FileContent:
+ def __init__(self, Filename, FileContent2):
+ self.Filename = Filename
+ self.PackagePath, self.PackageFile = os.path.split(Filename)
+ self.LineIndex = 0
+ self.CurrentLine = ''
+ self.NextLine = ''
+ self.HeadComment = []
+ self.TailComment = []
+ self.CurrentScope = None
+ self.Content = FileContent2
+ self.Macros = {}
+ self.FileLines = len(FileContent2)
+
+ def GetNextLine(self):
+ if self.LineIndex >= self.FileLines:
+ return ''
+ Line = self.Content[self.LineIndex]
+ self.LineIndex += 1
+ return Line
+
+ def UndoNextLine(self):
+ if self.LineIndex > 0:
+ self.LineIndex -= 1
+
+ def ResetNext(self):
+ self.HeadComment = []
+ self.TailComment = []
+ self.NextLine = ''
+
+ def SetNext(self, Line, HeadComment, TailComment):
+ self.NextLine = Line
+ self.HeadComment = HeadComment
+ self.TailComment = TailComment
+
+ def IsEndOfFile(self):
+ return self.LineIndex >= self.FileLines
+
+
+## StripRoot
+#
+# Strip root path
+#
+# @param Root: Root must be absolute path
+# @param Path: Path to be stripped
+#
+def StripRoot(Root, Path):
+ OrigPath = Path
+ Root = os.path.normpath(Root)
+ Path = os.path.normpath(Path)
+ if not os.path.isabs(Root):
+ return OrigPath
+ if Path.startswith(Root):
+ Path = Path[len(Root):]
+ if Path and Path[0] == os.sep:
+ Path = Path[1:]
+ return Path
+ return OrigPath
+
+## CleanString
+#
+# Split comments in a string
+# Remove spaces
+#
+# @param Line: The string to be cleaned
+# @param CommentCharacter: Comment char, used to ignore comment content,
+# default is DataType.TAB_COMMENT_SPLIT
+#
+def CleanString(Line, CommentCharacter=TAB_COMMENT_SPLIT, \
+ AllowCppStyleComment=False):
+ #
+ # remove whitespace
+ #
+ Line = Line.strip()
+ #
+ # Replace EDK1's comment character
+ #
+ if AllowCppStyleComment:
+ Line = Line.replace(TAB_COMMENT_EDK1_SPLIT, CommentCharacter)
+ #
+ # separate comments and statements
+ #
+ Comment = ''
+ InQuote = False
+ for Index in range(0, len(Line)):
+ if Line[Index] == '"':
+ InQuote = not InQuote
+ continue
+ if Line[Index] == CommentCharacter and not InQuote:
+ Comment = Line[Index:].strip()
+ Line = Line[0:Index].strip()
+ break
+
+ return Line, Comment
+
+
+## IsValidHexByte
+#
+# Check if Token is HexByte: <HexByte> ::= 0x <HexDigit>{1,2}
+#
+# @param Token: Token to be checked
+#
+def IsValidHexByte(Token):
+ Token = Token.strip()
+ if not Token.lower().startswith('0x') or not (len(Token) < 5 and len(Token) > 2):
+ return False
+ try:
+ Token = long(Token, 0)
+ except BaseException:
+ return False
+ return True
+
+## IsValidNList
+#
+# Check if Value has the format of <HexByte> ["," <HexByte>]{0,}
+# <HexByte> ::= "0x" <HexDigit>{1,2}
+#
+# @param Value: Value to be checked
+#
+def IsValidNList(Value):
+ Par = ParserHelper(Value)
+ if Par.End():
+ return False
+ while not Par.End():
+ Token = Par.GetToken(',\t ')
+ if not IsValidHexByte(Token):
+ return False
+ if Par.Expect(','):
+ if Par.End():
+ return False
+ continue
+ else:
+ break
+ return Par.End()
+
+## IsValidCArray
+#
+# check Array is valid
+#
+# @param Array: The input Array
+#
+def IsValidCArray(Array):
+ Par = ParserHelper(Array)
+ if not Par.Expect('{'):
+ return False
+ if Par.End():
+ return False
+ while not Par.End():
+ Token = Par.GetToken(',}\t ')
+ #
+ # 0xa, 0xaa
+ #
+ if not IsValidHexByte(Token):
+ return False
+ if Par.Expect(','):
+ if Par.End():
+ return False
+ continue
+ elif Par.Expect('}'):
+ #
+ # End of C array
+ #
+ break
+ else:
+ return False
+ return Par.End()
+
+## IsValidPcdDatum
+#
+# check PcdDatum is valid
+#
+# @param Type: The pcd Type
+# @param Value: The pcd Value
+#
+def IsValidPcdDatum(Type, Value):
+ if Type not in ["UINT8", "UINT16", "UINT32", "UINT64", "VOID*", "BOOLEAN"]:
+ return False, ST.ERR_DECPARSE_PCD_TYPE
+ if Type == "VOID*":
+ if not ((Value.startswith('L"') or Value.startswith('"') and \
+ Value.endswith('"'))
+ or (IsValidCArray(Value)) or (IsValidCFormatGuid(Value)) \
+ or (IsValidNList(Value)) or (CheckGuidRegFormat(Value))
+ ):
+ return False, ST.ERR_DECPARSE_PCD_VOID % (Value, Type)
+ RealString = Value[Value.find('"') + 1 :-1]
+ if RealString:
+ if not IsValidBareCString(RealString):
+ return False, ST.ERR_DECPARSE_PCD_VOID % (Value, Type)
+ elif Type == 'BOOLEAN':
+ if Value in ['TRUE', 'FALSE', 'true', 'false', 'True', 'False',
+ '0x1', '0x01', '1', '0x0', '0x00', '0']:
+ return True, ""
+ Valid, Cause = IsValidStringTest(Value)
+ if not Valid:
+ Valid, Cause = IsValidLogicalExpr(Value)
+ if not Valid:
+ return False, Cause
+ else:
+ if Value and (Value[0] == '-' or Value[0] == '+'):
+ return False, ST.ERR_DECPARSE_PCD_INT_NEGTIVE % (Value, Type)
+ try:
+ StrVal = Value
+ if Value and not Value.startswith('0x') \
+ and not Value.startswith('0X'):
+ Value = Value.lstrip('0')
+ if not Value:
+ return True, ""
+ Value = long(Value, 0)
+ TypeLenMap = {
+ #
+ # 0x00 - 0xff
+ #
+ 'UINT8' : 2,
+ #
+ # 0x0000 - 0xffff
+ #
+ 'UINT16' : 4,
+ #
+ # 0x00000000 - 0xffffffff
+ #
+ 'UINT32' : 8,
+ #
+ # 0x0 - 0xffffffffffffffff
+ #
+ 'UINT64' : 16
+ }
+ HexStr = hex(Value)
+ #
+ # First two chars of HexStr are 0x and tail char is L
+ #
+ if TypeLenMap[Type] < len(HexStr) - 3:
+ return False, ST.ERR_DECPARSE_PCD_INT_EXCEED % (StrVal, Type)
+ except BaseException:
+ return False, ST.ERR_DECPARSE_PCD_INT % (Value, Type)
+
+ return True, ""
+
+## ParserHelper
+#
+class ParserHelper:
+ def __init__(self, String, File=''):
+ self._String = String
+ self._StrLen = len(String)
+ self._Index = 0
+ self._File = File
+
+ ## End
+ #
+ # End
+ #
+ def End(self):
+ self.__SkipWhitespace()
+ return self._Index >= self._StrLen
+
+ ## __SkipWhitespace
+ #
+ # Skip whitespace
+ #
+ def __SkipWhitespace(self):
+ for Char in self._String[self._Index:]:
+ if Char not in ' \t':
+ break
+ self._Index += 1
+
+ ## Expect
+ #
+ # Expect char in string
+ #
+ # @param ExpectChar: char expected in index of string
+ #
+ def Expect(self, ExpectChar):
+ self.__SkipWhitespace()
+ for Char in self._String[self._Index:]:
+ if Char != ExpectChar:
+ return False
+ else:
+ self._Index += 1
+ return True
+ #
+ # Index out of bound of String
+ #
+ return False
+
+ ## GetToken
+ #
+ # Get token until encounter StopChar, front whitespace is consumed
+ #
+ # @param StopChar: Get token until encounter char in StopChar
+ # @param StkipPair: Only can be ' or ", StopChar in SkipPair are skipped
+ #
+ def GetToken(self, StopChar='.,|\t ', SkipPair='"'):
+ self.__SkipWhitespace()
+ PreIndex = self._Index
+ InQuote = False
+ LastChar = ''
+ for Char in self._String[self._Index:]:
+ if Char == SkipPair and LastChar != '\\':
+ InQuote = not InQuote
+ if Char in StopChar and not InQuote:
+ break
+ self._Index += 1
+ if Char == '\\' and LastChar == '\\':
+ LastChar = ''
+ else:
+ LastChar = Char
+ return self._String[PreIndex:self._Index]
+
+ ## AssertChar
+ #
+ # Assert char at current index of string is AssertChar, or will report
+ # error message
+ #
+ # @param AssertChar: AssertChar
+ # @param ErrorString: ErrorString
+ # @param ErrorLineNum: ErrorLineNum
+ #
+ def AssertChar(self, AssertChar, ErrorString, ErrorLineNum):
+ if not self.Expect(AssertChar):
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._File,
+ Line=ErrorLineNum, ExtraData=ErrorString)
+
+ ## AssertEnd
+ #
+ # @param ErrorString: ErrorString
+ # @param ErrorLineNum: ErrorLineNum
+ #
+ def AssertEnd(self, ErrorString, ErrorLineNum):
+ self.__SkipWhitespace()
+ if self._Index != self._StrLen:
+ Logger.Error(TOOL_NAME, FILE_PARSE_FAILURE, File=self._File,
+ Line=ErrorLineNum, ExtraData=ErrorString)
diff --git a/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py b/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
new file mode 100644
index 0000000000..12c46f1954
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfAsBuiltProcess.py
@@ -0,0 +1,219 @@
+## @file
+# This file is used to provide method for process AsBuilt INF file. It will consumed by InfParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+'''
+InfAsBuiltProcess
+'''
+## Import modules
+#
+
+import os
+import re
+from Library import GlobalData
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger import ToolError
+
+from Library.String import GetSplitValueList
+from Library.Misc import GetHelpStringByRemoveHashKey
+from Library.Misc import ValidFile
+from Library.Misc import ProcessLineExtender
+from Library.ParserValidate import IsValidPath
+from Library.Parsing import MacroParser
+from Parser.InfParserMisc import InfExpandMacro
+
+from Library import DataType as DT
+
+## GetLibInstanceInfo
+#
+# Get the information from Library Instance INF file.
+#
+# @param string. A string start with # and followed by INF file path
+# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
+#
+# @return GUID, Version
+def GetLibInstanceInfo(String, WorkSpace, LineNo):
+
+ FileGuidString = ""
+ VerString = ""
+
+ OrignalString = String
+ String = String.strip()
+ if not String:
+ return None, None
+ #
+ # Remove "#" characters at the beginning
+ #
+ String = GetHelpStringByRemoveHashKey(String)
+ String = String.strip()
+
+ FileLinesList = GetFileLineContent(String, WorkSpace, LineNo, OrignalString)
+
+
+ ReFindFileGuidPattern = re.compile("^\s*FILE_GUID\s*=.*$")
+ ReFindVerStringPattern = re.compile("^\s*VERSION_STRING\s*=.*$")
+
+ FileLinesList = ProcessLineExtender(FileLinesList)
+
+ for Line in FileLinesList:
+ if ReFindFileGuidPattern.match(Line):
+ FileGuidString = Line
+ if ReFindVerStringPattern.match(Line):
+ VerString = Line
+
+ if FileGuidString:
+ FileGuidString = GetSplitValueList(FileGuidString, '=', 1)[1]
+ if VerString:
+ VerString = GetSplitValueList(VerString, '=', 1)[1]
+
+ return FileGuidString, VerString
+
+## GetPackageListInfo
+#
+# Get the package information from INF file.
+#
+# @param string. A string start with # and followed by INF file path
+# @param WorkSpace. The WorkSpace directory used to combined with INF file path.
+#
+# @return GUID, Version
+def GetPackageListInfo(FileNameString, WorkSpace, LineNo):
+ PackageInfoList = []
+ DefineSectionMacros = {}
+ PackageSectionMacros = {}
+
+ FileLinesList = GetFileLineContent(FileNameString, WorkSpace, LineNo, '')
+
+ RePackageHeader = re.compile('^\s*\[Packages.*\].*$')
+ ReDefineHeader = re.compile('^\s*\[Defines].*$')
+
+ PackageHederFlag = False
+ DefineHeaderFlag = False
+ LineNo = -1
+ for Line in FileLinesList:
+ LineNo += 1
+ Line = Line.strip()
+
+ if Line.startswith('['):
+ PackageHederFlag = False
+ DefineHeaderFlag = False
+
+ if Line.startswith("#"):
+ continue
+
+ if not Line:
+ continue
+
+ #
+ # Found [Packages] section
+ #
+ if RePackageHeader.match(Line):
+ PackageHederFlag = True
+ continue
+
+ #
+ # Found [Define] section
+ #
+ if ReDefineHeader.match(Line):
+ DefineHeaderFlag = True
+ continue
+
+ if DefineHeaderFlag:
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((Line, LineNo),
+ FileNameString,
+ DT.MODEL_META_DATA_HEADER,
+ DefineSectionMacros)
+
+ if Name != None:
+ DefineSectionMacros[Name] = Value
+ continue
+
+ if PackageHederFlag:
+
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((Line, LineNo),
+ FileNameString,
+ DT.MODEL_META_DATA_PACKAGE,
+ DefineSectionMacros)
+ if Name != None:
+ PackageSectionMacros[Name] = Value
+ continue
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ Line = InfExpandMacro(Line, (FileNameString, Line, LineNo), DefineSectionMacros, PackageSectionMacros, True)
+
+ Line = GetSplitValueList(Line, "#", 1)[0]
+ Line = GetSplitValueList(Line, "|", 1)[0]
+ PackageInfoList.append(Line)
+
+ return PackageInfoList
+
+def GetFileLineContent(FileName, WorkSpace, LineNo, OriginalString):
+
+ if not LineNo:
+ LineNo = -1
+
+ #
+ # Validate file name exist.
+ #
+ FullFileName = os.path.normpath(os.path.realpath(os.path.join(WorkSpace, FileName)))
+ if not (ValidFile(FullFileName)):
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_FILELIST_EXIST%(FileName),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=OriginalString)
+
+ #
+ # Validate file exist/format.
+ #
+ if IsValidPath(FileName, WorkSpace):
+ IsValidFileFlag = True
+ else:
+ Logger.Error("InfParser",
+ ToolError.FORMAT_INVALID,
+ ST.ERR_INF_PARSER_FILE_NOT_EXIST_OR_NAME_INVALID%(FileName),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=LineNo,
+ ExtraData=OriginalString)
+ return False
+
+ FileLinesList = []
+
+ if IsValidFileFlag:
+ try:
+ FullFileName = FullFileName.replace('\\', '/')
+ Inputfile = open(FullFileName, "rb", 0)
+ try:
+ FileLinesList = Inputfile.readlines()
+ except BaseException:
+ Logger.Error("InfParser", ToolError.FILE_READ_FAILURE, ST.ERR_FILE_OPEN_FAILURE, File=FullFileName)
+ finally:
+ Inputfile.close()
+ except BaseException:
+ Logger.Error("InfParser",
+ ToolError.FILE_READ_FAILURE,
+ ST.ERR_FILE_OPEN_FAILURE,
+ File=FullFileName)
+
+ FileLinesList = ProcessLineExtender(FileLinesList)
+
+ return FileLinesList
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py
new file mode 100644
index 0000000000..36142cf84a
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfBinarySectionParser.py
@@ -0,0 +1,217 @@
+## @file
+# This file contained the parser for [Binaries] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfBinarySectionParser
+'''
+##
+# Import Modules
+#
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Object.Parser.InfCommonObject import CurrentLine
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfBinarySectionParser(InfParserSectionRoot):
+ ## InfBinaryParser
+ #
+ #
+ def InfBinaryParser(self, SectionString, InfSectionObject, FileName):
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ ValueList = []
+ #
+ # For UI (UI, SEC_UI, UNI_UI) binaries
+ # One and only one UI section can be included
+ #
+ UiBinaryList = []
+ #
+ # For Version (VER, SEC_VER, UNI_VER).
+ # One and only one VER section on be included
+ #
+ VerBinaryList = []
+ #
+ # For other common type binaries
+ #
+ ComBinaryList = []
+
+ StillCommentFalg = False
+ HeaderComments = []
+ LineComment = None
+
+ AllSectionContent = ''
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ BinLineContent = Line[0]
+ BinLineNo = Line[1]
+
+ if BinLineContent.strip() == '':
+ continue
+
+ CurrentLineObj = CurrentLine()
+ CurrentLineObj.FileName = FileName
+ CurrentLineObj.LineString = BinLineContent
+ CurrentLineObj.LineNo = BinLineNo
+ #
+ # Found Header Comments
+ #
+ if BinLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ #
+ # Last line is comments, and this line go on.
+ #
+ if StillCommentFalg:
+ HeaderComments.append(Line)
+ AllSectionContent += BinLineContent + DT.END_OF_LINE
+ continue
+ #
+ # First time encounter comment
+ #
+ else:
+ #
+ # Clear original data
+ #
+ HeaderComments = []
+ HeaderComments.append(Line)
+ AllSectionContent += BinLineContent + DT.END_OF_LINE
+ StillCommentFalg = True
+ continue
+ else:
+ StillCommentFalg = False
+
+ if len(HeaderComments) >= 1:
+ LineComment = InfLineCommentObject()
+ LineCommentContent = ''
+ for Item in HeaderComments:
+ LineCommentContent += Item[0] + DT.END_OF_LINE
+ LineComment.SetHeaderComments(LineCommentContent)
+
+ #
+ # Find Tail comment.
+ #
+ if BinLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ TailComments = BinLineContent[BinLineContent.find(DT.TAB_COMMENT_SPLIT):]
+ BinLineContent = BinLineContent[:BinLineContent.find(DT.TAB_COMMENT_SPLIT)]
+ if LineComment == None:
+ LineComment = InfLineCommentObject()
+ LineComment.SetTailComments(TailComments)
+
+ #
+ # Find Macro
+ #
+ MacroDef = MacroParser((BinLineContent, BinLineNo),
+ FileName,
+ DT.MODEL_EFI_BINARY_FILE,
+ self.FileLocalMacros)
+ if MacroDef[0] != None:
+ SectionMacros[MacroDef[0]] = MacroDef[1]
+ LineComment = None
+ HeaderComments = []
+ continue
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ LineContent = InfExpandMacro(BinLineContent,
+ (FileName, BinLineContent, BinLineNo),
+ self.FileLocalMacros,
+ SectionMacros, True)
+
+ AllSectionContent += LineContent + DT.END_OF_LINE
+ TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Should equal to UI/SEC_UI/UNI_UI
+ #
+ ValueList[0] = ValueList[0].strip()
+ if ValueList[0] == DT.BINARY_FILE_TYPE_UNI_UI or \
+ ValueList[0] == DT.BINARY_FILE_TYPE_SEC_UI or \
+ ValueList[0] == DT.BINARY_FILE_TYPE_UI:
+ if len(ValueList) == 2:
+ TokenList = GetSplitValueList(ValueList[1],
+ DT.TAB_VALUE_SPLIT,
+ 2)
+ NewValueList = []
+ NewValueList.append(ValueList[0])
+ for Item in TokenList:
+ NewValueList.append(Item)
+ UiBinaryList.append((NewValueList,
+ LineComment,
+ CurrentLineObj))
+ #
+ # Should equal to VER/SEC_VER/UNI_VER
+ #
+ elif ValueList[0] == DT.BINARY_FILE_TYPE_UNI_VER or \
+ ValueList[0] == DT.BINARY_FILE_TYPE_SEC_VER or \
+ ValueList[0] == DT.BINARY_FILE_TYPE_VER:
+ if len(ValueList) == 2:
+ TokenList = GetSplitValueList(ValueList[1],
+ DT.TAB_VALUE_SPLIT,
+ 2)
+ NewValueList = []
+ NewValueList.append(ValueList[0])
+ for Item in TokenList:
+ NewValueList.append(Item)
+ VerBinaryList.append((NewValueList,
+ LineComment,
+ CurrentLineObj))
+ else:
+ if len(ValueList) == 2:
+ TokenList = GetSplitValueList(ValueList[1],
+ DT.TAB_VALUE_SPLIT,
+ 4)
+ NewValueList = []
+ NewValueList.append(ValueList[0])
+ for Item in TokenList:
+ NewValueList.append(Item)
+ ComBinaryList.append((NewValueList,
+ LineComment,
+ CurrentLineObj))
+
+ ValueList = []
+ LineComment = None
+ TailComments = ''
+ HeaderComments = []
+ continue
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ for Item in self.LastSectionHeaderContent:
+ if Item[1] not in ArchList:
+ ArchList.append(Item[1])
+ InfSectionObject.SetSupArchList(Item[1])
+
+ InfSectionObject.SetAllContent(AllSectionContent)
+ if not InfSectionObject.SetBinary(UiBinaryList,
+ VerBinaryList,
+ ComBinaryList,
+ ArchList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[Binaries]"),
+ File=FileName,
+ Line=Item[3])
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py
new file mode 100644
index 0000000000..941641a845
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfBuildOptionSectionParser.py
@@ -0,0 +1,218 @@
+## @file
+# This file contained the parser for BuildOption sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+InfBuildOptionSectionParser
+'''
+##
+# Import Modules
+#
+from Library import DataType as DT
+from Library import GlobalData
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library.Misc import GetSplitValueList
+from Parser.InfParserMisc import IsAsBuildOptionInfo
+from Library.Misc import GetHelpStringByRemoveHashKey
+from Library.ParserValidate import IsValidFamily
+from Library.ParserValidate import IsValidBuildOptionName
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfBuildOptionSectionParser(InfParserSectionRoot):
+ ## InfBuildOptionParser
+ #
+ #
+ def InfBuildOptionParser(self, SectionString, InfSectionObject, FileName):
+
+ BuildOptionList = []
+ SectionContent = ''
+
+ if not GlobalData.gIS_BINARY_INF:
+ ValueList = []
+ LineNo = 0
+
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+ TailComments = ''
+ ReplaceFlag = False
+
+ if LineContent.strip() == '':
+ SectionContent += LineContent + DT.END_OF_LINE
+ continue
+ #
+ # Found Comment
+ #
+ if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ SectionContent += LineContent + DT.END_OF_LINE
+ continue
+
+ #
+ # Find Tail comment.
+ #
+ if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ TailComments = LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):]
+ LineContent = LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_DEQUAL_SPLIT, 1)
+ if len(TokenList) == 2:
+ #
+ # "Replace" type build option
+ #
+ TokenList.append('True')
+ ReplaceFlag = True
+ else:
+ TokenList = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)
+ #
+ # "Append" type build option
+ #
+ if len(TokenList) == 2:
+ TokenList.append('False')
+ else:
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
+ ExtraData=LineContent,
+ File=FileName,
+ Line=LineNo)
+
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with [Defines] section Macro
+ #
+ ValueList[0] = InfExpandMacro(ValueList[0], (FileName, LineContent, LineNo),
+ self.FileLocalMacros, None)
+ ValueList[1] = InfExpandMacro(ValueList[1], (FileName, LineContent, LineNo),
+ self.FileLocalMacros, None, True)
+ EqualString = ''
+ if not ReplaceFlag:
+ EqualString = ' = '
+ else:
+ EqualString = ' == '
+
+ SectionContent += ValueList[0] + EqualString + ValueList[1] + TailComments + DT.END_OF_LINE
+
+ Family = GetSplitValueList(ValueList[0], DT.TAB_COLON_SPLIT, 1)
+ if len(Family) == 2:
+ if not IsValidFamily(Family[0]):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
+ ExtraData=LineContent,
+ File=FileName,
+ Line=LineNo)
+ if not IsValidBuildOptionName(Family[1]):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
+ ExtraData=LineContent,
+ File=FileName,
+ Line=LineNo)
+ if len(Family) == 1:
+ if not IsValidBuildOptionName(Family[0]):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
+ ExtraData=LineContent,
+ File=FileName,
+ Line=LineNo)
+
+ BuildOptionList.append(ValueList)
+ ValueList = []
+ continue
+ else:
+ BuildOptionList = InfAsBuiltBuildOptionParser(SectionString, FileName)
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ LastItem = ''
+ for Item in self.LastSectionHeaderContent:
+ LastItem = Item
+ if not (Item[1] == '' or Item[1] == '') and Item[1] not in ArchList:
+ ArchList.append(Item[1])
+ InfSectionObject.SetSupArchList(Item[1])
+
+ InfSectionObject.SetAllContent(SectionContent)
+ if not InfSectionObject.SetBuildOptions(BuildOptionList, ArchList, SectionContent):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[BuilOptions]"),
+ File=FileName,
+ Line=LastItem[3])
+
+## InfBuildOptionParser
+#
+#
+def InfAsBuiltBuildOptionParser(SectionString, FileName):
+ BuildOptionList = []
+ #
+ # AsBuild Binary INF file.
+ #
+ AsBuildOptionFlag = False
+ BuildOptionItem = []
+ Count = 0
+ for Line in SectionString:
+ Count += 1
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ #
+ # The last line
+ #
+ if len(SectionString) == Count:
+ if LineContent.strip().startswith("##") and AsBuildOptionFlag:
+ BuildOptionList.append(BuildOptionItem)
+ BuildOptionList.append([GetHelpStringByRemoveHashKey(LineContent)])
+ elif LineContent.strip().startswith("#") and AsBuildOptionFlag:
+ BuildOptionInfo = GetHelpStringByRemoveHashKey(LineContent)
+ BuildOptionItem.append(BuildOptionInfo)
+ BuildOptionList.append(BuildOptionItem)
+ else:
+ if len(BuildOptionItem) > 0:
+ BuildOptionList.append(BuildOptionItem)
+
+ break
+
+ if LineContent.strip() == '':
+ AsBuildOptionFlag = False
+ continue
+
+ if LineContent.strip().startswith("##") and AsBuildOptionFlag:
+ if len(BuildOptionItem) > 0:
+ BuildOptionList.append(BuildOptionItem)
+
+ BuildOptionItem = []
+
+ if not LineContent.strip().startswith("#"):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_BO_CONTATIN_ASBUILD_AND_COMMON,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=LineContent)
+
+ if IsAsBuildOptionInfo(LineContent):
+ AsBuildOptionFlag = True
+ continue
+
+ if AsBuildOptionFlag:
+ BuildOptionInfo = GetHelpStringByRemoveHashKey(LineContent)
+ BuildOptionItem.append(BuildOptionInfo)
+
+ return BuildOptionList \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
new file mode 100644
index 0000000000..d00087a128
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfDefineSectionParser.py
@@ -0,0 +1,197 @@
+## @file
+# This file contained the parser for define sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+InfDefineSectionParser
+'''
+##
+# Import Modules
+#
+import re
+
+from Library import DataType as DT
+from Library import GlobalData
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Library.ParserValidate import IsValidArch
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Object.Parser.InfDefineObject import InfDefMember
+from Parser.InfParserMisc import InfExpandMacro
+from Object.Parser.InfMisc import ErrorInInf
+from Logger import StringTable as ST
+from Parser.InfParserMisc import InfParserSectionRoot
+
+## __GetValidateArchList
+#
+#
+def GetValidateArchList(LineContent):
+
+ TempArch = ''
+ ArchList = []
+ ValidateAcrhPatten = re.compile(r"^\s*#\s*VALID_ARCHITECTURES\s*=\s*.*$", re.DOTALL)
+
+ if ValidateAcrhPatten.match(LineContent):
+ TempArch = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)[1]
+
+ TempArch = GetSplitValueList(TempArch, '(', 1)[0]
+
+ ArchList = re.split('\s+', TempArch)
+ NewArchList = []
+ for Arch in ArchList:
+ if IsValidArch(Arch):
+ NewArchList.append(Arch)
+
+ ArchList = NewArchList
+
+ return ArchList
+
+class InfDefinSectionParser(InfParserSectionRoot):
+ def InfDefineParser(self, SectionString, InfSectionObject, FileName, SectionComment):
+
+ if SectionComment:
+ pass
+ #
+ # Parser Defines section content and fill self._ContentList dict.
+ #
+ StillCommentFalg = False
+ HeaderComments = []
+ SectionContent = ''
+ ArchList = []
+ _ContentList = []
+ _ValueList = []
+ #
+ # Add WORKSPACE to global Marco dict.
+ #
+ self.FileLocalMacros['WORKSPACE'] = GlobalData.gWORKSPACE
+
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+ TailComments = ''
+ LineComment = None
+
+ LineInfo = ['', -1, '']
+ LineInfo[0] = FileName
+ LineInfo[1] = LineNo
+ LineInfo[2] = LineContent
+
+ if LineContent.strip() == '':
+ continue
+ #
+ # The first time encountered VALIDATE_ARCHITECHERS will be considered as support arch list.
+ #
+ if not ArchList:
+ ArchList = GetValidateArchList(LineContent)
+
+ #
+ # Parser Comment
+ #
+ if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ #
+ # Last line is comments, and this line go on.
+ #
+ if StillCommentFalg:
+ HeaderComments.append(Line)
+ SectionContent += LineContent + DT.END_OF_LINE
+ continue
+ #
+ # First time encounter comment
+ #
+ else:
+ #
+ # Clear original data
+ #
+ HeaderComments = []
+ HeaderComments.append(Line)
+ StillCommentFalg = True
+ SectionContent += LineContent + DT.END_OF_LINE
+ continue
+ else:
+ StillCommentFalg = False
+
+ if len(HeaderComments) >= 1:
+ LineComment = InfLineCommentObject()
+ LineCommentContent = ''
+ for Item in HeaderComments:
+ LineCommentContent += Item[0] + DT.END_OF_LINE
+ LineComment.SetHeaderComments(LineCommentContent)
+
+ #
+ # Find Tail comment.
+ #
+ if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ TailComments = LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):]
+ LineContent = LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
+ if LineComment == None:
+ LineComment = InfLineCommentObject()
+ LineComment.SetTailComments(TailComments)
+
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((LineContent, LineNo),
+ FileName,
+ DT.MODEL_META_DATA_HEADER,
+ self.FileLocalMacros)
+ if Name != None:
+ self.FileLocalMacros[Name] = Value
+ continue
+
+ #
+ # Replace with [Defines] section Macro
+ #
+ LineContent = InfExpandMacro(LineContent,
+ (FileName, LineContent, LineNo),
+ self.FileLocalMacros,
+ None, True)
+
+ SectionContent += LineContent + DT.END_OF_LINE
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)
+ if len(TokenList) < 2:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
+ LineInfo=LineInfo)
+ _ValueList[0:len(TokenList)] = TokenList
+ if not _ValueList[0]:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_NAME,
+ LineInfo=LineInfo)
+ if not _ValueList[1]:
+ ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
+ LineInfo=LineInfo)
+
+ Name, Value = _ValueList[0], _ValueList[1]
+
+ InfDefMemberObj = InfDefMember(Name, Value)
+ if (LineComment != None):
+ InfDefMemberObj.Comments.SetHeaderComments(LineComment.GetHeaderComments())
+ InfDefMemberObj.Comments.SetTailComments(LineComment.GetTailComments())
+
+ InfDefMemberObj.CurrentLine.SetFileName(self.FullPath)
+ InfDefMemberObj.CurrentLine.SetLineString(LineContent)
+ InfDefMemberObj.CurrentLine.SetLineNo(LineNo)
+
+ _ContentList.append(InfDefMemberObj)
+ HeaderComments = []
+ TailComments = ''
+
+ #
+ # Current Define section archs
+ #
+ if not ArchList:
+ ArchList = ['COMMON']
+
+ InfSectionObject.SetAllContent(SectionContent)
+
+ InfSectionObject.SetDefines(_ContentList, Arch=ArchList)
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py
new file mode 100644
index 0000000000..5cafc80ca5
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfDepexSectionParser.py
@@ -0,0 +1,104 @@
+## @file
+# This file contained the parser for [Depex] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfDepexSectionParser
+'''
+##
+# Import Modules
+#
+import re
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library.Misc import GetSplitValueList
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfDepexSectionParser(InfParserSectionRoot):
+ ## InfDepexParser
+ #
+ # For now, only separate Depex String and comments.
+ # Have two types of section header.
+ # 1. [Depex.Arch.ModuleType, ...]
+ # 2. [Depex.Arch|FFE, ...]
+ #
+ def InfDepexParser(self, SectionString, InfSectionObject, FileName):
+ DepexContent = []
+ DepexComment = []
+ ValueList = []
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ #
+ # Found comment
+ #
+ if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ DepexComment.append((LineContent, LineNo))
+ continue
+ #
+ # Replace with [Defines] section Macro
+ #
+ LineContent = InfExpandMacro(LineContent,
+ (FileName, LineContent, Line[1]),
+ self.FileLocalMacros,
+ None, True)
+
+ CommentCount = LineContent.find(DT.TAB_COMMENT_SPLIT)
+
+ if CommentCount > -1:
+ DepexComment.append((LineContent[CommentCount:], LineNo))
+ LineContent = LineContent[:CommentCount-1]
+
+
+ CommentCount = -1
+ DepexContent.append((LineContent, LineNo))
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_COMMENT_SPLIT)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Current section archs
+ #
+ KeyList = []
+ LastItem = ''
+ for Item in self.LastSectionHeaderContent:
+ LastItem = Item
+ if (Item[1], Item[2], Item[3]) not in KeyList:
+ KeyList.append((Item[1], Item[2], Item[3]))
+
+ NewCommentList = []
+ FormatCommentLn = -1
+ ReFormatComment = re.compile(r"""#(?:\s*)\[(.*?)\](?:.*)""", re.DOTALL)
+ for CommentItem in DepexComment:
+ CommentContent = CommentItem[0]
+ if ReFormatComment.match(CommentContent) != None:
+ FormatCommentLn = CommentItem[1] + 1
+ continue
+
+ if CommentItem[1] != FormatCommentLn:
+ NewCommentList.append(CommentContent)
+ else:
+ FormatCommentLn = CommentItem[1] + 1
+
+ if not InfSectionObject.SetDepex(DepexContent, KeyList = KeyList, CommentList = NewCommentList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[Depex]"),
+ File=FileName,
+ Line=LastItem[3]) \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py
new file mode 100644
index 0000000000..9c3d703ad1
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfGuidPpiProtocolSectionParser.py
@@ -0,0 +1,382 @@
+## @file
+# This file contained the parser for [Guids], [Ppis], [Protocols] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfGuidPpiProtocolSectionParser
+'''
+##
+# Import Modules
+#
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library import GlobalData
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Library.ParserValidate import IsValidIdString
+from Library.ParserValidate import IsValidUserId
+from Library.ParserValidate import IsValidArch
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfGuidPpiProtocolSectionParser(InfParserSectionRoot):
+ ## InfGuidParser
+ #
+ #
+ def InfGuidParser(self, SectionString, InfSectionObject, FileName):
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ ValueList = []
+ GuidList = []
+ CommentsList = []
+ CurrentLineVar = None
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ if LineContent.strip() == '':
+ CommentsList = []
+ continue
+
+ if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ CommentsList.append(Line)
+ continue
+ else:
+ #
+ # Encounter a GUID entry
+ #
+ if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ CommentsList.append((
+ LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
+ LineNo))
+ LineContent = \
+ LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
+
+ if LineContent != '':
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((LineContent, LineNo),
+ FileName,
+ DT.MODEL_EFI_GUID,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ CommentsList = []
+ ValueList = []
+ continue
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo),
+ self.FileLocalMacros, SectionMacros, True)
+ for Value in ValueList]
+
+ CurrentLineVar = (LineContent, LineNo, FileName)
+
+
+ if len(ValueList) >= 1:
+ GuidList.append((ValueList, CommentsList, CurrentLineVar))
+ CommentsList = []
+ ValueList = []
+ continue
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ LineIndex = -1
+ for Item in self.LastSectionHeaderContent:
+ LineIndex = Item[3]
+ if Item[1] not in ArchList:
+ ArchList.append(Item[1])
+
+ if not InfSectionObject.SetGuid(GuidList, Arch=ArchList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Guid]"),
+ File=FileName,
+ Line=LineIndex)
+
+ ## InfPpiParser
+ #
+ #
+ def InfPpiParser(self, SectionString, InfSectionObject, FileName):
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ ValueList = []
+ PpiList = []
+ CommentsList = []
+ CurrentLineVar = None
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ if LineContent.strip() == '':
+ CommentsList = []
+ continue
+
+ if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ CommentsList.append(Line)
+ continue
+ else:
+ #
+ # Encounter a PPI entry
+ #
+ if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ CommentsList.append((
+ LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
+ LineNo))
+ LineContent = \
+ LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
+
+ if LineContent != '':
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((LineContent, LineNo),
+ FileName,
+ DT.MODEL_EFI_PPI,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ ValueList = []
+ CommentsList = []
+ continue
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros)
+ for Value in ValueList]
+
+ CurrentLineVar = (LineContent, LineNo, FileName)
+
+ if len(ValueList) >= 1:
+ PpiList.append((ValueList, CommentsList, CurrentLineVar))
+ ValueList = []
+ CommentsList = []
+ continue
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ LineIndex = -1
+ for Item in self.LastSectionHeaderContent:
+ LineIndex = Item[3]
+ if Item[1] not in ArchList:
+ ArchList.append(Item[1])
+
+ if not InfSectionObject.SetPpi(PpiList, Arch=ArchList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Ppis]"),
+ File=FileName,
+ Line=LineIndex)
+
+ ## InfUserExtensionParser
+ #
+ #
+ def InfUserExtensionParser(self, SectionString, InfSectionObject, FileName):
+
+ UserExtensionContent = ''
+
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ if LineContent.strip() == '':
+ continue
+ #
+ # Replace with [Defines] section Macro
+ #
+ LineContent = InfExpandMacro(LineContent,
+ (FileName, LineContent, LineNo),
+ self.FileLocalMacros,
+ None)
+
+ UserExtensionContent += LineContent + DT.END_OF_LINE
+
+ continue
+
+ #
+ # Current section UserId, IdString
+ #
+ IdContentList = []
+ LastItem = ''
+ SectionLineNo = None
+ for Item in self.LastSectionHeaderContent:
+ UserId = Item[1]
+ IdString = Item[2]
+ Arch = Item[3]
+ SectionLineNo = Item[4]
+ if not IsValidArch(Arch):
+ Logger.Error(
+ 'InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (Arch),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=SectionLineNo,
+ ExtraData=None)
+
+ if (UserId, IdString, Arch) not in IdContentList:
+ #
+ # To check the UserId and IdString valid or not.
+ #
+ if not IsValidUserId(UserId):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UE_SECTION_USER_ID_ERROR % (Item[1]),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=SectionLineNo,
+ ExtraData=None)
+
+ if not IsValidIdString(IdString):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UE_SECTION_ID_STRING_ERROR % (IdString),
+ File=GlobalData.gINF_MODULE_NAME, Line=SectionLineNo,
+ ExtraData=None)
+ IdContentList.append((UserId, IdString, Arch))
+ else:
+ #
+ # Each UserExtensions section header must have a unique set
+ # of UserId, IdString and Arch values.
+ # This means that the same UserId can be used in more than one
+ # section header, provided the IdString or Arch values are
+ # different. The same IdString values can be used in more than
+ # one section header if the UserId or Arch values are
+ # different. The same UserId and the same IdString can be used
+ # in a section header if the Arch values are different in each
+ # of the section headers.
+ #
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UE_SECTION_DUPLICATE_ERROR % (
+ IdString),
+ File=GlobalData.gINF_MODULE_NAME,
+ Line=SectionLineNo,
+ ExtraData=None)
+ LastItem = Item
+
+ if not InfSectionObject.SetUserExtension(UserExtensionContent,
+ IdContent=IdContentList,
+ LineNo=SectionLineNo):
+ Logger.Error\
+ ('InfParser', FORMAT_INVALID, \
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[UserExtension]"), \
+ File=FileName, Line=LastItem[4])
+
+ def InfProtocolParser(self, SectionString, InfSectionObject, FileName):
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ ValueList = []
+ ProtocolList = []
+ CommentsList = []
+ CurrentLineVar = None
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ if LineContent.strip() == '':
+ CommentsList = []
+ continue
+
+ if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ CommentsList.append(Line)
+ continue
+ else:
+ #
+ # Encounter a Protocol entry
+ #
+ if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ CommentsList.append((
+ LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):],
+ LineNo))
+ LineContent = \
+ LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
+
+ if LineContent != '':
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((LineContent, LineNo),
+ FileName,
+ DT.MODEL_EFI_PROTOCOL,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ ValueList = []
+ CommentsList = []
+ continue
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT, 1)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ ValueList = [InfExpandMacro(Value, (FileName, LineContent, LineNo), self.FileLocalMacros, SectionMacros)
+ for Value in ValueList]
+
+ CurrentLineVar = (LineContent, LineNo, FileName)
+
+ if len(ValueList) >= 1:
+ ProtocolList.append((ValueList, CommentsList, CurrentLineVar))
+ ValueList = []
+ CommentsList = []
+ continue
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ LineIndex = -1
+ for Item in self.LastSectionHeaderContent:
+ LineIndex = Item[3]
+ if Item[1] not in ArchList:
+ ArchList.append(Item[1])
+
+ if not InfSectionObject.SetProtocol(ProtocolList, Arch=ArchList):
+ Logger.Error\
+ ('InfParser', FORMAT_INVALID, \
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Protocol]"), \
+ File=FileName, Line=LineIndex)
diff --git a/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py
new file mode 100644
index 0000000000..8f9427cf4f
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfLibrarySectionParser.py
@@ -0,0 +1,209 @@
+## @file
+# This file contained the parser for [Libraries] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfLibrarySectionParser
+'''
+##
+# Import Modules
+#
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Library import GlobalData
+from Parser.InfParserMisc import IsLibInstanceInfo
+from Parser.InfAsBuiltProcess import GetLibInstanceInfo
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfLibrarySectionParser(InfParserSectionRoot):
+ ## InfLibraryParser
+ #
+ #
+ def InfLibraryParser(self, SectionString, InfSectionObject, FileName):
+ #
+ # For Common INF file
+ #
+ if not GlobalData.gIS_BINARY_INF:
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ ValueList = []
+ LibraryList = []
+ LibStillCommentFalg = False
+ LibHeaderComments = []
+ LibLineComment = None
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ LibLineContent = Line[0]
+ LibLineNo = Line[1]
+
+ if LibLineContent.strip() == '':
+ continue
+
+ #
+ # Found Header Comments
+ #
+ if LibLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ #
+ # Last line is comments, and this line go on.
+ #
+ if LibStillCommentFalg:
+ LibHeaderComments.append(Line)
+ continue
+ #
+ # First time encounter comment
+ #
+ else:
+ #
+ # Clear original data
+ #
+ LibHeaderComments = []
+ LibHeaderComments.append(Line)
+ LibStillCommentFalg = True
+ continue
+ else:
+ LibStillCommentFalg = False
+
+ if len(LibHeaderComments) >= 1:
+ LibLineComment = InfLineCommentObject()
+ LineCommentContent = ''
+ for Item in LibHeaderComments:
+ LineCommentContent += Item[0] + DT.END_OF_LINE
+ LibLineComment.SetHeaderComments(LineCommentContent)
+
+ #
+ # Find Tail comment.
+ #
+ if LibLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ LibTailComments = LibLineContent[LibLineContent.find(DT.TAB_COMMENT_SPLIT):]
+ LibLineContent = LibLineContent[:LibLineContent.find(DT.TAB_COMMENT_SPLIT)]
+ if LibLineComment == None:
+ LibLineComment = InfLineCommentObject()
+ LibLineComment.SetTailComments(LibTailComments)
+
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((LibLineContent, LibLineNo),
+ FileName,
+ DT.MODEL_EFI_LIBRARY_CLASS,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ LibLineComment = None
+ LibHeaderComments = []
+ continue
+
+ TokenList = GetSplitValueList(LibLineContent, DT.TAB_VALUE_SPLIT, 1)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ ValueList = [InfExpandMacro(Value, (FileName, LibLineContent, LibLineNo),
+ self.FileLocalMacros, SectionMacros, True)
+ for Value in ValueList]
+
+ LibraryList.append((ValueList, LibLineComment,
+ (LibLineContent, LibLineNo, FileName)))
+ ValueList = []
+ LibLineComment = None
+ LibTailComments = ''
+ LibHeaderComments = []
+
+ continue
+
+ #
+ # Current section archs
+ #
+ KeyList = []
+ for Item in self.LastSectionHeaderContent:
+ if (Item[1], Item[2]) not in KeyList:
+ KeyList.append((Item[1], Item[2]))
+
+ if not InfSectionObject.SetLibraryClasses(LibraryList, KeyList = KeyList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Library]"),
+ File=FileName,
+ Line=Item[3])
+ #
+ # For Binary INF
+ #
+ else:
+ self.InfAsBuiltLibraryParser(SectionString, InfSectionObject, FileName)
+
+ def InfAsBuiltLibraryParser(self, SectionString, InfSectionObject, FileName):
+ LibraryList = []
+ LibInsFlag = False
+ for Line in SectionString:
+ LineContent = Line[0]
+ LineNo = Line[1]
+
+ if LineContent.strip() == '':
+ LibInsFlag = False
+ continue
+
+ if not LineContent.strip().startswith("#"):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_LIB_CONTATIN_ASBUILD_AND_COMMON,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=LineContent)
+
+ if IsLibInstanceInfo(LineContent):
+ LibInsFlag = True
+ continue
+
+ if LibInsFlag:
+ LibGuid, LibVer = GetLibInstanceInfo(LineContent, GlobalData.gWORKSPACE, LineNo)
+ #
+ # If the VERSION_STRING is missing from the INF file, tool should default to "0".
+ #
+ if LibVer == '':
+ LibVer = '0'
+ if LibGuid != '':
+ LibraryList.append((LibGuid, LibVer))
+ else:
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_LIB_INSTANCE_MISS_GUID,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=LineContent)
+
+ #
+ # Current section archs
+ #
+ KeyList = []
+ Item = ['', '', '']
+ for Item in self.LastSectionHeaderContent:
+ if (Item[1], Item[2]) not in KeyList:
+ KeyList.append((Item[1], Item[2]))
+
+ if not InfSectionObject.SetLibraryClasses(LibraryList, KeyList = KeyList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Library]"),
+ File=FileName,
+ Line=Item[3]) \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py
new file mode 100644
index 0000000000..67f1145322
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfPackageSectionParser.py
@@ -0,0 +1,140 @@
+## @file
+# This file contained the parser for [Packages] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfPackageSectionParser
+'''
+##
+# Import Modules
+#
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfPackageSectionParser(InfParserSectionRoot):
+ ## InfPackageParser
+ #
+ #
+ def InfPackageParser(self, SectionString, InfSectionObject, FileName):
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ ValueList = []
+ PackageList = []
+ StillCommentFalg = False
+ HeaderComments = []
+ LineComment = None
+ #
+ # Parse section content
+ #
+ for Line in SectionString:
+ PkgLineContent = Line[0]
+ PkgLineNo = Line[1]
+
+ if PkgLineContent.strip() == '':
+ continue
+
+ #
+ # Find Header Comments
+ #
+ if PkgLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ #
+ # Last line is comments, and this line go on.
+ #
+ if StillCommentFalg:
+ HeaderComments.append(Line)
+ continue
+ #
+ # First time encounter comment
+ #
+ else:
+ #
+ # Clear original data
+ #
+ HeaderComments = []
+ HeaderComments.append(Line)
+ StillCommentFalg = True
+ continue
+ else:
+ StillCommentFalg = False
+
+ if len(HeaderComments) >= 1:
+ LineComment = InfLineCommentObject()
+ LineCommentContent = ''
+ for Item in HeaderComments:
+ LineCommentContent += Item[0] + DT.END_OF_LINE
+ LineComment.SetHeaderComments(LineCommentContent)
+
+ #
+ # Find Tail comment.
+ #
+ if PkgLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ TailComments = PkgLineContent[PkgLineContent.find(DT.TAB_COMMENT_SPLIT):]
+ PkgLineContent = PkgLineContent[:PkgLineContent.find(DT.TAB_COMMENT_SPLIT)]
+ if LineComment == None:
+ LineComment = InfLineCommentObject()
+ LineComment.SetTailComments(TailComments)
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((PkgLineContent, PkgLineNo),
+ FileName,
+ DT.MODEL_META_DATA_PACKAGE,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ LineComment = None
+ HeaderComments = []
+ continue
+
+ TokenList = GetSplitValueList(PkgLineContent, DT.TAB_VALUE_SPLIT, 1)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ ValueList = [InfExpandMacro(Value, (FileName, PkgLineContent, PkgLineNo),
+ self.FileLocalMacros, SectionMacros, True)
+ for Value in ValueList]
+
+ PackageList.append((ValueList, LineComment,
+ (PkgLineContent, PkgLineNo, FileName)))
+ ValueList = []
+ LineComment = None
+ TailComments = ''
+ HeaderComments = []
+ continue
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ for Item in self.LastSectionHeaderContent:
+ if Item[1] not in ArchList:
+ ArchList.append(Item[1])
+
+ if not InfSectionObject.SetPackages(PackageList, Arch = ArchList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR\
+ %("[Packages]"),
+ File=FileName,
+ Line=Item[3]) \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfParser.py b/BaseTools/Source/Python/UPT/Parser/InfParser.py
new file mode 100644
index 0000000000..aa44e8038d
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfParser.py
@@ -0,0 +1,612 @@
+## @file
+# This file contained the parser for INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+InfParser
+'''
+
+##
+# Import Modules
+#
+import re
+import os
+from copy import deepcopy
+
+from Library.String import GetSplitValueList
+from Library.String import ConvertSpecialChar
+from Library.Misc import ProcessLineExtender
+from Library.Parsing import NormPath
+from Library.ParserValidate import IsValidInfMoudleTypeList
+from Library.ParserValidate import IsValidArch
+from Library import DataType as DT
+from Library import GlobalData
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Logger.ToolError import FILE_READ_FAILURE
+from Logger.ToolError import PARSER_ERROR
+
+from Object.Parser.InfCommonObject import InfSectionCommonDef
+from Parser.InfSectionParser import InfSectionParser
+from Parser.InfParserMisc import gINF_SECTION_DEF
+from Parser.InfParserMisc import IsBinaryInf
+
+## OpenInfFile
+#
+#
+def OpenInfFile(Filename):
+ FileLinesList = []
+
+ try:
+ FInputfile = open(Filename, "rb", 0)
+ try:
+ FileLinesList = FInputfile.readlines()
+ except BaseException:
+ Logger.Error("InfParser",
+ FILE_READ_FAILURE,
+ ST.ERR_FILE_OPEN_FAILURE,
+ File=Filename)
+ finally:
+ FInputfile.close()
+ except BaseException:
+ Logger.Error("InfParser",
+ FILE_READ_FAILURE,
+ ST.ERR_FILE_OPEN_FAILURE,
+ File=Filename)
+
+ return FileLinesList
+
+## InfParser
+#
+# This class defined the structure used in InfParser object
+#
+# @param InfObject: Inherited from InfSectionParser class
+# @param Filename: Input value for Filename of INF file, default is
+# None
+# @param WorkspaceDir: Input value for current workspace directory,
+# default is None
+#
+class InfParser(InfSectionParser):
+
+ def __init__(self, Filename = None, WorkspaceDir = None):
+
+ #
+ # Call parent class construct function
+ #
+ super(InfParser, self).__init__()
+
+ self.WorkspaceDir = WorkspaceDir
+ self.SupArchList = DT.ARCH_LIST
+ self.EventList = []
+ self.HobList = []
+ self.BootModeList = []
+
+ #
+ # Load Inf file if filename is not None
+ #
+ if Filename != None:
+ self.ParseInfFile(Filename)
+
+ ## Parse INF file
+ #
+ # Parse the file if it exists
+ #
+ # @param Filename: Input value for filename of INF file
+ #
+ def ParseInfFile(self, Filename):
+
+ Filename = NormPath(Filename)
+ (Path, Name) = os.path.split(Filename)
+ self.FullPath = Filename
+ self.RelaPath = Path
+ self.FileName = Name
+ GlobalData.gINF_MODULE_DIR = Path
+ GlobalData.gINF_MODULE_NAME = self.FullPath
+ GlobalData.gIS_BINARY_INF = False
+ #
+ # Initialize common data
+ #
+ LineNo = 0
+ CurrentSection = DT.MODEL_UNKNOWN
+ SectionLines = []
+
+ #
+ # Flags
+ #
+ HeaderCommentStart = False
+ HeaderCommentEnd = False
+
+ #
+ # While Section ends. parse whole section contents.
+ #
+ NewSectionStartFlag = False
+ FirstSectionStartFlag = False
+
+ #
+ # Parse file content
+ #
+ CommentBlock = []
+
+ #
+ # Variables for Event/Hob/BootMode
+ #
+ self.EventList = []
+ self.HobList = []
+ self.BootModeList = []
+ SectionType = ''
+
+ FileLinesList = OpenInfFile (Filename)
+
+ #
+ # One INF file can only has one [Defines] section.
+ #
+ DefineSectionParsedFlag = False
+
+ #
+ # Convert special characters in lines to space character.
+ #
+ FileLinesList = ConvertSpecialChar(FileLinesList)
+
+ #
+ # Process Line Extender
+ #
+ FileLinesList = ProcessLineExtender(FileLinesList)
+
+ #
+ # Judge whether the INF file is Binary INF or not
+ #
+ if IsBinaryInf(FileLinesList):
+ GlobalData.gIS_BINARY_INF = True
+
+ InfSectionCommonDefObj = None
+
+ for Line in FileLinesList:
+ LineNo = LineNo + 1
+ Line = Line.strip()
+ if (LineNo < len(FileLinesList) - 1):
+ NextLine = FileLinesList[LineNo].strip()
+
+ #
+ # blank line
+ #
+ if (Line == '' or not Line) and LineNo == len(FileLinesList):
+ LastSectionFalg = True
+
+ #
+ # check whether file header comment section started
+ #
+ if Line.startswith(DT.TAB_SPECIAL_COMMENT) and \
+ (Line.find(DT.TAB_HEADER_COMMENT) > -1) and \
+ not HeaderCommentStart:
+ if CurrentSection != DT.MODEL_UNKNOWN:
+ Logger.Error("Parser",
+ PARSER_ERROR,
+ ST.ERR_INF_PARSER_HEADER_FILE,
+ File=Filename,
+ Line=LineNo,
+ RaiseError = Logger.IS_RAISE_ERROR)
+ else:
+ CurrentSection = DT.MODEL_META_DATA_FILE_HEADER
+ #
+ # Append the first line to section lines.
+ #
+ SectionLines.append((Line, LineNo))
+ HeaderCommentStart = True
+ continue
+
+ #
+ # Collect Header content.
+ #
+ if (Line.startswith(DT.TAB_COMMENT_SPLIT) and CurrentSection == DT.MODEL_META_DATA_FILE_HEADER) and\
+ HeaderCommentStart and not Line.startswith(DT.TAB_SPECIAL_COMMENT) and not\
+ HeaderCommentEnd and NextLine != '':
+ SectionLines.append((Line, LineNo))
+ continue
+ #
+ # Header content end
+ #
+ if (Line.startswith(DT.TAB_SPECIAL_COMMENT) or not Line.strip().startswith("#")) and HeaderCommentStart \
+ and not HeaderCommentEnd:
+ SectionLines.append((Line, LineNo))
+ HeaderCommentStart = False
+ #
+ # Call Header comment parser.
+ #
+ self.InfHeaderParser(SectionLines, self.InfHeader, self.FileName)
+ SectionLines = []
+ HeaderCommentEnd = True
+ continue
+
+ #
+ # Find a new section tab
+ # Or at the last line of INF file,
+ # need to process the last section.
+ #
+ LastSectionFalg = False
+ if LineNo == len(FileLinesList):
+ LastSectionFalg = True
+
+ if Line.startswith(DT.TAB_COMMENT_SPLIT) and not Line.startswith(DT.TAB_SPECIAL_COMMENT):
+ SectionLines.append((Line, LineNo))
+ if not LastSectionFalg:
+ continue
+
+ #
+ # Encountered a section. start with '[' and end with ']'
+ #
+ if (Line.startswith(DT.TAB_SECTION_START) and \
+ Line.find(DT.TAB_SECTION_END) > -1) or LastSectionFalg:
+ if not LastSectionFalg:
+ #
+ # check to prevent '#' inside section header
+ #
+ HeaderContent = Line[1:Line.find(DT.TAB_SECTION_END)]
+ if HeaderContent.find(DT.TAB_COMMENT_SPLIT) != -1:
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID,
+ File=self.FullPath,
+ Line=LineNo,
+ ExtraData=Line)
+
+ #
+ # Keep last time section header content for section parser
+ # usage.
+ #
+ self.LastSectionHeaderContent = deepcopy(self.SectionHeaderContent)
+
+ #
+ # TailComments in section define.
+ #
+ TailComments = ''
+ CommentIndex = Line.find(DT.TAB_COMMENT_SPLIT)
+ if CommentIndex > -1:
+ TailComments = Line[CommentIndex:]
+ Line = Line[:CommentIndex]
+
+ InfSectionCommonDefObj = InfSectionCommonDef()
+ if TailComments != '':
+ InfSectionCommonDefObj.SetTailComments(TailComments)
+ if CommentBlock != '':
+ InfSectionCommonDefObj.SetHeaderComments(CommentBlock)
+ CommentBlock = []
+ #
+ # Call section parser before section header parer to avoid encounter EDKI INF file
+ #
+ if CurrentSection == DT.MODEL_META_DATA_DEFINE:
+ DefineSectionParsedFlag = self._CallSectionParsers(CurrentSection,
+ DefineSectionParsedFlag, SectionLines,
+ InfSectionCommonDefObj, LineNo)
+ #
+ # Compare the new section name with current
+ #
+ self.SectionHeaderParser(Line, self.FileName, LineNo)
+
+ self._CheckSectionHeaders(Line, LineNo)
+
+ SectionType = _ConvertSecNameToType(self.SectionHeaderContent[0][0])
+
+ if not FirstSectionStartFlag:
+ CurrentSection = SectionType
+ FirstSectionStartFlag = True
+ else:
+ NewSectionStartFlag = True
+ else:
+ SectionLines.append((Line, LineNo))
+ continue
+
+ if LastSectionFalg:
+ SectionLines, CurrentSection = self._ProcessLastSection(SectionLines, Line, LineNo, CurrentSection)
+
+ #
+ # End of section content collect.
+ # Parser the section content collected previously.
+ #
+ if NewSectionStartFlag or LastSectionFalg:
+ if CurrentSection != DT.MODEL_META_DATA_DEFINE or \
+ (LastSectionFalg and CurrentSection == DT.MODEL_META_DATA_DEFINE):
+ DefineSectionParsedFlag = self._CallSectionParsers(CurrentSection,
+ DefineSectionParsedFlag, SectionLines,
+ InfSectionCommonDefObj, LineNo)
+
+ CurrentSection = SectionType
+ #
+ # Clear section lines
+ #
+ SectionLines = []
+ #
+ # End of for
+ #
+ #
+ # Found the first section, No file header.
+ #
+ if not DefineSectionParsedFlag:
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_HEADER_MISSGING,
+ File=self.FullPath)
+
+ #
+ # extract [Event] [Hob] [BootMode] sections
+ #
+ self._ExtractEventHobBootMod(FileLinesList)
+
+ ## _CheckSectionHeaders
+ #
+ #
+ def _CheckSectionHeaders(self, Line, LineNo):
+ if len(self.SectionHeaderContent) == 0:
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_SECTION_HEADER_INVALID,
+ File=self.FullPath,
+ Line=LineNo, ExtraData=Line)
+ else:
+ for SectionItem in self.SectionHeaderContent:
+ ArchList = []
+ #
+ # Not cover Depex/UserExtension section header
+ # check.
+ #
+ if SectionItem[0].strip().upper() == DT.TAB_INF_FIXED_PCD.upper() or \
+ SectionItem[0].strip().upper() == DT.TAB_INF_PATCH_PCD.upper() or \
+ SectionItem[0].strip().upper() == DT.TAB_INF_PCD_EX.upper() or \
+ SectionItem[0].strip().upper() == DT.TAB_INF_PCD.upper() or \
+ SectionItem[0].strip().upper() == DT.TAB_INF_FEATURE_PCD.upper():
+ ArchList = GetSplitValueList(SectionItem[1].strip(), ' ')
+ else:
+ ArchList = [SectionItem[1].strip()]
+
+ for Arch in ArchList:
+ if (not IsValidArch(Arch)) and \
+ (SectionItem[0].strip().upper() != DT.TAB_DEPEX.upper()) and \
+ (SectionItem[0].strip().upper() != DT.TAB_USER_EXTENSIONS.upper()) and \
+ (SectionItem[0].strip().upper() != DT.TAB_COMMON_DEFINES.upper()):
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(SectionItem[1]),
+ File=self.FullPath,
+ Line=LineNo, ExtraData=Line)
+ #
+ # Check if the ModuleType is valid
+ #
+ ChkModSectionList = ['LIBRARYCLASSES']
+ if (self.SectionHeaderContent[0][0].upper() in ChkModSectionList):
+ if SectionItem[2].strip().upper():
+ MoudleTypeList = GetSplitValueList(
+ SectionItem[2].strip().upper())
+ if (not IsValidInfMoudleTypeList(MoudleTypeList)):
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID%(SectionItem[2]),
+ File=self.FullPath, Line=LineNo,
+ ExtraData=Line)
+
+ ## _CallSectionParsers
+ #
+ #
+ def _CallSectionParsers(self, CurrentSection, DefineSectionParsedFlag,
+ SectionLines, InfSectionCommonDefObj, LineNo):
+ if CurrentSection == DT.MODEL_META_DATA_DEFINE:
+ if not DefineSectionParsedFlag:
+ self.InfDefineParser(SectionLines,
+ self.InfDefSection,
+ self.FullPath,
+ InfSectionCommonDefObj)
+ DefineSectionParsedFlag = True
+ else:
+ Logger.Error("Parser",
+ PARSER_ERROR,
+ ST.ERR_INF_PARSER_MULTI_DEFINE_SECTION,
+ File=self.FullPath,
+ RaiseError = Logger.IS_RAISE_ERROR)
+
+ elif CurrentSection == DT.MODEL_META_DATA_BUILD_OPTION:
+ self.InfBuildOptionParser(SectionLines,
+ self.InfBuildOptionSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_LIBRARY_CLASS:
+ self.InfLibraryParser(SectionLines,
+ self.InfLibraryClassSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_META_DATA_PACKAGE:
+ self.InfPackageParser(SectionLines,
+ self.InfPackageSection,
+ self.FullPath)
+ #
+ # [Pcd] Sections, put it together
+ #
+ elif CurrentSection == DT.MODEL_PCD_FIXED_AT_BUILD or \
+ CurrentSection == DT.MODEL_PCD_PATCHABLE_IN_MODULE or \
+ CurrentSection == DT.MODEL_PCD_FEATURE_FLAG or \
+ CurrentSection == DT.MODEL_PCD_DYNAMIC_EX or \
+ CurrentSection == DT.MODEL_PCD_DYNAMIC:
+ self.InfPcdParser(SectionLines,
+ self.InfPcdSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_SOURCE_FILE:
+ self.InfSourceParser(SectionLines,
+ self.InfSourcesSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_META_DATA_USER_EXTENSION:
+ self.InfUserExtensionParser(SectionLines,
+ self.InfUserExtensionSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_PROTOCOL:
+ self.InfProtocolParser(SectionLines,
+ self.InfProtocolSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_PPI:
+ self.InfPpiParser(SectionLines,
+ self.InfPpiSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_GUID:
+ self.InfGuidParser(SectionLines,
+ self.InfGuidSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_DEPEX:
+ self.InfDepexParser(SectionLines,
+ self.InfDepexSection,
+ self.FullPath)
+
+ elif CurrentSection == DT.MODEL_EFI_BINARY_FILE:
+ self.InfBinaryParser(SectionLines,
+ self.InfBinariesSection,
+ self.FullPath)
+ #
+ # Unknown section type found, raise error.
+ #
+ else:
+ if len(self.SectionHeaderContent) >= 1:
+ Logger.Error("Parser",
+ PARSER_ERROR,
+ ST.ERR_INF_PARSER_UNKNOWN_SECTION,
+ File=self.FullPath, Line=LineNo,
+ RaiseError = Logger.IS_RAISE_ERROR)
+ else:
+ Logger.Error("Parser",
+ PARSER_ERROR,
+ ST.ERR_INF_PARSER_NO_SECTION_ERROR,
+ File=self.FullPath, Line=LineNo,
+ RaiseError = Logger.IS_RAISE_ERROR)
+
+ return DefineSectionParsedFlag
+
+ def _ExtractEventHobBootMod(self, FileLinesList):
+ SpecialSectionStart = False
+ CheckLocation = False
+ GFindSpecialCommentRe = \
+ re.compile(r"""#(?:\s*)\[(.*?)\](?:.*)""", re.DOTALL)
+ GFindNewSectionRe2 = \
+ re.compile(r"""#?(\s*)\[(.*?)\](.*)""", re.DOTALL)
+ LineNum = 0
+ Element = []
+ for Line in FileLinesList:
+ Line = Line.strip()
+ LineNum += 1
+ MatchObject = GFindSpecialCommentRe.search(Line)
+ if MatchObject:
+ SpecialSectionStart = True
+ Element = []
+ if MatchObject.group(1).upper().startswith("EVENT"):
+ List = self.EventList
+ elif MatchObject.group(1).upper().startswith("HOB"):
+ List = self.HobList
+ elif MatchObject.group(1).upper().startswith("BOOTMODE"):
+ List = self.BootModeList
+ else:
+ SpecialSectionStart = False
+ CheckLocation = False
+ if SpecialSectionStart:
+ Element.append([Line, LineNum])
+ List.append(Element)
+ else:
+ #
+ # if currently in special section, try to detect end of current section
+ #
+ MatchObject = GFindNewSectionRe2.search(Line)
+ if SpecialSectionStart:
+ if MatchObject:
+ SpecialSectionStart = False
+ CheckLocation = False
+ Element = []
+ elif not Line:
+ SpecialSectionStart = False
+ CheckLocation = True
+ Element = []
+ else:
+ if not Line.startswith(DT.TAB_COMMENT_SPLIT):
+ Logger.Warn("Parser",
+ ST.WARN_SPECIAL_SECTION_LOCATION_WRONG,
+ File=self.FullPath, Line=LineNum)
+ SpecialSectionStart = False
+ CheckLocation = False
+ Element = []
+ else:
+ Element.append([Line, LineNum])
+ else:
+ if CheckLocation:
+ if MatchObject:
+ CheckLocation = False
+ elif Line:
+ Logger.Warn("Parser",
+ ST.WARN_SPECIAL_SECTION_LOCATION_WRONG,
+ File=self.FullPath, Line=LineNum)
+ CheckLocation = False
+
+ if len(self.BootModeList) >= 1:
+ self.InfSpecialCommentParser(self.BootModeList,
+ self.InfSpecialCommentSection,
+ self.FileName,
+ DT.TYPE_BOOTMODE_SECTION)
+
+ if len(self.EventList) >= 1:
+ self.InfSpecialCommentParser(self.EventList,
+ self.InfSpecialCommentSection,
+ self.FileName,
+ DT.TYPE_EVENT_SECTION)
+
+ if len(self.HobList) >= 1:
+ self.InfSpecialCommentParser(self.HobList,
+ self.InfSpecialCommentSection,
+ self.FileName,
+ DT.TYPE_HOB_SECTION)
+ ## _ProcessLastSection
+ #
+ #
+ def _ProcessLastSection(self, SectionLines, Line, LineNo, CurrentSection):
+ #
+ # The last line is a section header. will discard it.
+ #
+ if not (Line.startswith(DT.TAB_SECTION_START) and Line.find(DT.TAB_SECTION_END) > -1):
+ SectionLines.append((Line, LineNo))
+
+ if len(self.SectionHeaderContent) >= 1:
+ TemSectionName = self.SectionHeaderContent[0][0].upper()
+ if TemSectionName.upper() not in gINF_SECTION_DEF.keys():
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UNKNOWN_SECTION,
+ File=self.FullPath,
+ Line=LineNo,
+ ExtraData=Line,
+ RaiseError = Logger.IS_RAISE_ERROR
+ )
+ else:
+ CurrentSection = gINF_SECTION_DEF[TemSectionName]
+ self.LastSectionHeaderContent = self.SectionHeaderContent
+
+ return SectionLines, CurrentSection
+
+## _ConvertSecNameToType
+#
+#
+def _ConvertSecNameToType(SectionName):
+ SectionType = ''
+ if SectionName.upper() not in gINF_SECTION_DEF.keys():
+ SectionType = DT.MODEL_UNKNOWN
+ else:
+ SectionType = gINF_SECTION_DEF[SectionName.upper()]
+
+ return SectionType
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py b/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
new file mode 100644
index 0000000000..7058e69da1
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfParserMisc.py
@@ -0,0 +1,218 @@
+## @file
+# This file contained the miscellaneous functions for INF parser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+InfParserMisc
+'''
+
+##
+# Import Modules
+#
+import re
+
+
+from Library import DataType as DT
+
+
+from Library.String import gMACRO_PATTERN
+from Library.String import ReplaceMacro
+from Object.Parser.InfMisc import ErrorInInf
+from Logger.StringTable import ERR_MARCO_DEFINITION_MISS_ERROR
+
+#
+# Global variable
+#
+
+#
+# Sections can exist in INF file
+#
+gINF_SECTION_DEF = {
+ DT.TAB_UNKNOWN.upper() : DT.MODEL_UNKNOWN,
+ DT.TAB_HEADER.upper() : DT.MODEL_META_DATA_FILE_HEADER,
+ DT.TAB_INF_DEFINES.upper() : DT.MODEL_META_DATA_DEFINE,
+ DT.TAB_BUILD_OPTIONS.upper() : DT.MODEL_META_DATA_BUILD_OPTION,
+ DT.TAB_LIBRARY_CLASSES.upper() : DT.MODEL_EFI_LIBRARY_CLASS,
+ DT.TAB_PACKAGES.upper() : DT.MODEL_META_DATA_PACKAGE,
+ DT.TAB_INF_FIXED_PCD.upper() : DT.MODEL_PCD_FIXED_AT_BUILD,
+ DT.TAB_INF_PATCH_PCD.upper() : DT.MODEL_PCD_PATCHABLE_IN_MODULE,
+ DT.TAB_INF_FEATURE_PCD.upper() : DT.MODEL_PCD_FEATURE_FLAG,
+ DT.TAB_INF_PCD_EX.upper() : DT.MODEL_PCD_DYNAMIC_EX,
+ DT.TAB_INF_PCD.upper() : DT.MODEL_PCD_DYNAMIC,
+ DT.TAB_SOURCES.upper() : DT.MODEL_EFI_SOURCE_FILE,
+ DT.TAB_GUIDS.upper() : DT.MODEL_EFI_GUID,
+ DT.TAB_PROTOCOLS.upper() : DT.MODEL_EFI_PROTOCOL,
+ DT.TAB_PPIS.upper() : DT.MODEL_EFI_PPI,
+ DT.TAB_DEPEX.upper() : DT.MODEL_EFI_DEPEX,
+ DT.TAB_BINARIES.upper() : DT.MODEL_EFI_BINARY_FILE,
+ DT.TAB_USER_EXTENSIONS.upper() : DT.MODEL_META_DATA_USER_EXTENSION
+ #
+ # EDK1 section
+ # TAB_NMAKE.upper() : MODEL_META_DATA_NMAKE
+ #
+ }
+
+## InfExpandMacro
+#
+# Expand MACRO definition with MACROs defined in [Defines] section and specific section.
+# The MACROs defined in specific section has high priority and will be expanded firstly.
+#
+# @param LineInfo Contain information of FileName, LineContent, LineNo
+# @param GlobalMacros MACROs defined in INF [Defines] section
+# @param SectionMacros MACROs defined in INF specific section
+# @param Flag If the flag set to True, need to skip macros in a quoted string
+#
+def InfExpandMacro(Content, LineInfo, GlobalMacros=None, SectionMacros=None, Flag=False):
+ if GlobalMacros == None:
+ GlobalMacros = {}
+ if SectionMacros == None:
+ SectionMacros = {}
+
+ FileName = LineInfo[0]
+ LineContent = LineInfo[1]
+ LineNo = LineInfo[2]
+
+ NewLineInfo = (FileName, LineNo, LineContent)
+
+ #
+ # First, replace MARCOs with value defined in specific section
+ #
+ Content = ReplaceMacro (Content,
+ SectionMacros,
+ False,
+ (LineContent, LineNo),
+ FileName,
+ Flag)
+ #
+ # Then replace MARCOs with value defined in [Defines] section
+ #
+ Content = ReplaceMacro (Content,
+ GlobalMacros,
+ False,
+ (LineContent, LineNo),
+ FileName,
+ Flag)
+
+ MacroUsed = gMACRO_PATTERN.findall(Content)
+ #
+ # no macro found in String, stop replacing
+ #
+ if len(MacroUsed) == 0:
+ return Content
+ else:
+ for Macro in MacroUsed:
+ gQuotedMacro = re.compile(".*\".*\$\(%s\).*\".*"%(Macro))
+ if not gQuotedMacro.match(Content):
+ #
+ # Still have MACROs can't be expanded.
+ #
+ ErrorInInf (ERR_MARCO_DEFINITION_MISS_ERROR,
+ LineInfo=NewLineInfo)
+
+ return Content
+
+
+## IsBinaryInf
+#
+# Judge whether the INF file is Binary INF or Common INF
+#
+# @param FileLineList A list contain all INF file content.
+#
+def IsBinaryInf(FileLineList):
+ if not FileLineList:
+ return False
+
+ ReIsSourcesSection = re.compile("^\s*\[Sources.*\]\s.*$", re.IGNORECASE)
+ ReIsBinarySection = re.compile("^\s*\[Binaries.*\]\s.*$", re.IGNORECASE)
+ BinarySectionFoundFlag = False
+
+ for Line in FileLineList:
+ if ReIsSourcesSection.match(Line):
+ return False
+ if ReIsBinarySection.match(Line):
+ BinarySectionFoundFlag = True
+
+ if BinarySectionFoundFlag:
+ return True
+
+ return False
+
+
+## IsLibInstanceInfo
+#
+# Judge whether the string contain the information of ## @LIB_INSTANCES.
+#
+# @param String
+#
+# @return Flag
+#
+def IsLibInstanceInfo(String):
+ ReIsLibInstance = re.compile("^\s*##\s*@LIB_INSTANCES\s*$")
+ if ReIsLibInstance.match(String):
+ return True
+ else:
+ return False
+
+
+## IsAsBuildOptionInfo
+#
+# Judge whether the string contain the information of ## @ASBUILD.
+#
+# @param String
+#
+# @return Flag
+#
+def IsAsBuildOptionInfo(String):
+ ReIsAsBuildInstance = re.compile("^\s*##\s*@AsBuilt\s*$")
+ if ReIsAsBuildInstance.match(String):
+ return True
+ else:
+ return False
+
+
+class InfParserSectionRoot(object):
+ def __init__(self):
+ #
+ # Macros defined in [Define] section are file scope global
+ #
+ self.FileLocalMacros = {}
+
+ #
+ # Current Section Header content.
+ #
+ self.SectionHeaderContent = []
+
+ #
+ # Last time Section Header content.
+ #
+ self.LastSectionHeaderContent = []
+
+ self.FullPath = ''
+
+ self.InfDefSection = None
+ self.InfBuildOptionSection = None
+ self.InfLibraryClassSection = None
+ self.InfPackageSection = None
+ self.InfPcdSection = None
+ self.InfSourcesSection = None
+ self.InfUserExtensionSection = None
+ self.InfProtocolSection = None
+ self.InfPpiSection = None
+ self.InfGuidSection = None
+ self.InfDepexSection = None
+ self.InfPeiDepexSection = None
+ self.InfDxeDepexSection = None
+ self.InfSmmDepexSection = None
+ self.InfBinariesSection = None
+ self.InfHeader = None
+ self.InfSpecialCommentSection = None
diff --git a/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py
new file mode 100644
index 0000000000..1011559450
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfPcdSectionParser.py
@@ -0,0 +1,184 @@
+## @file
+# This file contained the parser for [Pcds] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfPcdSectionParser
+'''
+##
+# Import Modules
+#
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Library import GlobalData
+from Library.String import SplitPcdEntry
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfPcdSectionParser(InfParserSectionRoot):
+ ## Section PCD related parser
+ #
+ # For 5 types of PCD list below, all use this function.
+ # 'FixedPcd', 'FeaturePcd', 'PatchPcd', 'Pcd', 'PcdEx'
+ #
+ # This is a INF independent parser, the validation in this parser only
+ # cover
+ # INF spec scope, will not cross DEC/DSC to check pcd value
+ #
+ def InfPcdParser(self, SectionString, InfSectionObject, FileName):
+ KeysList = []
+ PcdList = []
+ CommentsList = []
+ ValueList = []
+ #
+ # Current section archs
+ #
+ LineIndex = -1
+ for Item in self.LastSectionHeaderContent:
+ if (Item[0], Item[1], Item[3]) not in KeysList:
+ KeysList.append((Item[0], Item[1], Item[3]))
+ LineIndex = Item[3]
+
+ if (Item[0].upper() == DT.TAB_INF_FIXED_PCD.upper() or \
+ Item[0].upper() == DT.TAB_INF_FEATURE_PCD.upper() or \
+ Item[0].upper() == DT.TAB_INF_PCD.upper()) and GlobalData.gIS_BINARY_INF:
+ Logger.Error('InfParser', FORMAT_INVALID, ST.ERR_ASBUILD_PCD_SECTION_TYPE%("\"" + Item[0] + "\""),
+ File=FileName, Line=LineIndex)
+
+ #
+ # For Common INF file
+ #
+ if not GlobalData.gIS_BINARY_INF:
+ #
+ # Macro defined in this section
+ #
+ SectionMacros = {}
+ for Line in SectionString:
+ PcdLineContent = Line[0]
+ PcdLineNo = Line[1]
+ if PcdLineContent.strip() == '':
+ CommentsList = []
+ continue
+
+ if PcdLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ CommentsList.append(Line)
+ continue
+ else:
+ #
+ # Encounter a PCD entry
+ #
+ if PcdLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ CommentsList.append((
+ PcdLineContent[PcdLineContent.find(DT.TAB_COMMENT_SPLIT):],
+ PcdLineNo))
+ PcdLineContent = PcdLineContent[:PcdLineContent.find(DT.TAB_COMMENT_SPLIT)]
+
+ if PcdLineContent != '':
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((PcdLineContent, PcdLineNo),
+ FileName,
+ DT.MODEL_EFI_PCD,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ ValueList = []
+ CommentsList = []
+ continue
+
+ PcdEntryReturn = SplitPcdEntry(PcdLineContent)
+
+ if not PcdEntryReturn[1]:
+ TokenList = ['']
+ else:
+ TokenList = PcdEntryReturn[0]
+
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ ValueList = [InfExpandMacro(Value, (FileName, PcdLineContent, PcdLineNo),
+ self.FileLocalMacros, SectionMacros, True)
+ for Value in ValueList]
+
+ if len(ValueList) >= 1:
+ PcdList.append((ValueList, CommentsList, (PcdLineContent, PcdLineNo, FileName)))
+ ValueList = []
+ CommentsList = []
+ continue
+ #
+ # For Binary INF file
+ #
+ else:
+ for Line in SectionString:
+ LineContent = Line[0].strip()
+ LineNo = Line[1]
+
+ if LineContent == '':
+ CommentsList = []
+ continue
+
+ if LineContent.startswith(DT.TAB_COMMENT_SPLIT):
+ CommentsList.append(LineContent)
+ continue
+ #
+ # Have comments at tail.
+ #
+ CommentIndex = LineContent.find(DT.TAB_COMMENT_SPLIT)
+ if CommentIndex > -1:
+ CommentsList.append(LineContent[CommentIndex+1:])
+ LineContent = LineContent[:CommentIndex]
+
+ TokenList = GetSplitValueList(LineContent, DT.TAB_VALUE_SPLIT)
+ #
+ # PatchablePcd
+ # TokenSpace.CName | Value | Offset
+ #
+ if KeysList[0][0].upper() == DT.TAB_INF_PATCH_PCD.upper():
+ if len(TokenList) != 3:
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_ASBUILD_PATCHPCD_FORMAT_INVALID,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=LineContent)
+ #
+ elif KeysList[0][0].upper() == DT.TAB_INF_PCD_EX.upper():
+ if len(TokenList) != 2:
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_ASBUILD_PCDEX_FORMAT_INVALID,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=LineContent)
+ ValueList[0:len(TokenList)] = TokenList
+ if len(ValueList) >= 1:
+ PcdList.append((ValueList, CommentsList, (LineContent, LineNo, FileName)))
+ ValueList = []
+ CommentsList = []
+ continue
+
+ if not InfSectionObject.SetPcds(PcdList, KeysList = KeysList,
+ PackageInfo = self.InfPackageSection.GetPackages()):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[PCD]"),
+ File=FileName,
+ Line=LineIndex)
+ \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py
new file mode 100644
index 0000000000..879f924c45
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfSectionParser.py
@@ -0,0 +1,490 @@
+## @file
+# This file contained the parser for sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+InfSectionParser
+'''
+##
+# Import Modules
+#
+from copy import deepcopy
+import re
+
+from Library.String import GetSplitValueList
+from Library.CommentParsing import ParseHeaderCommentSection
+from Library.CommentParsing import ParseComment
+
+from Library import DataType as DT
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+
+from Object.Parser.InfDefineObject import InfDefObject
+from Object.Parser.InfBuildOptionObject import InfBuildOptionsObject
+from Object.Parser.InfLibraryClassesObject import InfLibraryClassObject
+from Object.Parser.InfPackagesObject import InfPackageObject
+from Object.Parser.InfPcdObject import InfPcdObject
+from Object.Parser.InfSoucesObject import InfSourcesObject
+from Object.Parser.InfUserExtensionObject import InfUserExtensionObject
+from Object.Parser.InfProtocolObject import InfProtocolObject
+from Object.Parser.InfPpiObject import InfPpiObject
+from Object.Parser.InfGuidObject import InfGuidObject
+from Object.Parser.InfDepexObject import InfDepexObject
+from Object.Parser.InfBinaryObject import InfBinariesObject
+from Object.Parser.InfHeaderObject import InfHeaderObject
+from Object.Parser.InfMisc import InfSpecialCommentObject
+from Object.Parser.InfMisc import InfHobObject
+from Object.Parser.InfMisc import InfBootModeObject
+from Object.Parser.InfMisc import InfEventObject
+from Parser.InfParserMisc import gINF_SECTION_DEF
+from Parser.InfDefineSectionParser import InfDefinSectionParser
+from Parser.InfBuildOptionSectionParser import InfBuildOptionSectionParser
+from Parser.InfSourceSectionParser import InfSourceSectionParser
+from Parser.InfLibrarySectionParser import InfLibrarySectionParser
+from Parser.InfPackageSectionParser import InfPackageSectionParser
+from Parser.InfGuidPpiProtocolSectionParser import InfGuidPpiProtocolSectionParser
+from Parser.InfBinarySectionParser import InfBinarySectionParser
+from Parser.InfPcdSectionParser import InfPcdSectionParser
+from Parser.InfDepexSectionParser import InfDepexSectionParser
+
+## GetSpecialStr2
+#
+# GetSpecialStr2
+#
+def GetSpecialStr2(ItemList, FileName, LineNo, SectionString):
+ Str2 = ''
+ #
+ # S2 may be Platform or ModuleType
+ #
+ if len(ItemList) == 3:
+ #
+ # Except [LibraryClass], [Depex]
+ # section can has more than 2 items in section header string,
+ # others should report error.
+ #
+ if not (ItemList[0].upper() == DT.TAB_LIBRARY_CLASSES.upper() or \
+ ItemList[0].upper() == DT.TAB_DEPEX.upper() or \
+ ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper()):
+ if ItemList[2] != '':
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID % (SectionString),
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+ Str2 = ItemList[2]
+ elif len(ItemList) == 4:
+ #
+ # Except [UserExtension]
+ # section can has 4 items in section header string,
+ # others should report error.
+ #
+ if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper() or ItemList[0].upper() == DT.TAB_DEPEX.upper():
+ if ItemList[3] != '':
+ Logger.Error('Parser', FORMAT_INVALID, ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID \
+ % (SectionString), File=FileName, Line=LineNo, ExtraData=SectionString)
+
+ if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
+ Str2 = ItemList[2] + ' | ' + ItemList[3]
+ else:
+ Str2 = ItemList[2]
+
+ elif len(ItemList) > 4:
+ Logger.Error('Parser', FORMAT_INVALID, ST.ERR_INF_PARSER_SOURCE_SECTION_SECTIONNAME_INVALID \
+ % (SectionString), File=FileName, Line=LineNo, ExtraData=SectionString)
+
+ return Str2
+
+## ProcessUseExtHeader
+#
+#
+def ProcessUseExtHeader(ItemList):
+ NewItemList = []
+ AppendContent = ''
+ CompleteFlag = False
+ for Item in ItemList:
+ if Item.startswith('\"') and not Item.endswith('\"'):
+ AppendContent = Item
+ CompleteFlag = True
+ elif Item.endswith('\"') and not Item.startswith('\"'):
+ #
+ # Should not have an userId or IdString not starts with " before but ends with ".
+ #
+ if not CompleteFlag:
+ return False, []
+ AppendContent = AppendContent + "." + Item
+ NewItemList.append(AppendContent)
+ CompleteFlag = False
+ AppendContent = ''
+ elif Item.endswith('\"') and Item.startswith('\"'):
+ #
+ # Common item, not need to combine the information
+ #
+ NewItemList.append(Item)
+ else:
+ if not CompleteFlag:
+ NewItemList.append(Item)
+ else:
+ AppendContent = AppendContent + "." + Item
+
+ if len(NewItemList) > 4:
+ return False, []
+
+ return True, NewItemList
+
+## GetArch
+#
+# GetArch
+#
+def GetArch(ItemList, ArchList, FileName, LineNo, SectionString):
+ #
+ # S1 is always Arch
+ #
+ if len(ItemList) > 1:
+ Arch = ItemList[1]
+ else:
+ Arch = 'COMMON'
+ ArchList.add(Arch)
+
+ #
+ # 'COMMON' must not be used with specific ARCHs at the same section
+ #
+ if 'COMMON' in ArchList and len(ArchList) > 1:
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_SECTION_ARCH_CONFLICT,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+
+ return Arch, ArchList
+
+## InfSectionParser
+#
+# Inherit from object
+#
+class InfSectionParser(InfDefinSectionParser,
+ InfBuildOptionSectionParser,
+ InfSourceSectionParser,
+ InfLibrarySectionParser,
+ InfPackageSectionParser,
+ InfGuidPpiProtocolSectionParser,
+ InfBinarySectionParser,
+ InfPcdSectionParser,
+ InfDepexSectionParser):
+ #
+ # Parser objects used to implement singleton
+ #
+ MetaFiles = {}
+
+ ## Factory method
+ #
+ # One file, one parser object. This factory method makes sure that there's
+ # only one object constructed for one meta file.
+ #
+ # @param Class class object of real AutoGen class
+ # (InfParser, DecParser or DscParser)
+ # @param FilePath The path of meta file
+ #
+ def __new__(cls, FilePath, *args, **kwargs):
+ if args:
+ pass
+ if kwargs:
+ pass
+ if FilePath in cls.MetaFiles:
+ return cls.MetaFiles[FilePath]
+ else:
+ ParserObject = super(InfSectionParser, cls).__new__(cls)
+ cls.MetaFiles[FilePath] = ParserObject
+ return ParserObject
+
+ def __init__(self):
+ InfDefinSectionParser.__init__(self)
+ InfBuildOptionSectionParser.__init__(self)
+ InfSourceSectionParser.__init__(self)
+ InfLibrarySectionParser.__init__(self)
+ InfPackageSectionParser.__init__(self)
+ InfGuidPpiProtocolSectionParser.__init__(self)
+ InfBinarySectionParser.__init__(self)
+ InfPcdSectionParser.__init__(self)
+ InfDepexSectionParser.__init__(self)
+ #
+ # Initialize all objects that an INF file will generated.
+ #
+ self.InfDefSection = InfDefObject()
+ self.InfBuildOptionSection = InfBuildOptionsObject()
+ self.InfLibraryClassSection = InfLibraryClassObject()
+ self.InfPackageSection = InfPackageObject()
+ self.InfPcdSection = InfPcdObject(self.MetaFiles.keys()[0])
+ self.InfSourcesSection = InfSourcesObject()
+ self.InfUserExtensionSection = InfUserExtensionObject()
+ self.InfProtocolSection = InfProtocolObject()
+ self.InfPpiSection = InfPpiObject()
+ self.InfGuidSection = InfGuidObject()
+ self.InfDepexSection = InfDepexObject()
+ self.InfPeiDepexSection = InfDepexObject()
+ self.InfDxeDepexSection = InfDepexObject()
+ self.InfSmmDepexSection = InfDepexObject()
+ self.InfBinariesSection = InfBinariesObject()
+ self.InfHeader = InfHeaderObject()
+ self.InfSpecialCommentSection = InfSpecialCommentObject()
+
+ #
+ # A List for store define section content.
+ #
+ self._PcdNameList = []
+ self._SectionName = ''
+ self._SectionType = 0
+ self.RelaPath = ''
+ self.FileName = ''
+
+ #
+ # File Header content parser
+ #
+ def InfHeaderParser(self, Content, InfHeaderObject2, FileName):
+ (Abstract, Description, Copyright, License) = ParseHeaderCommentSection(Content, FileName)
+ #
+ # Not process file name now, for later usage.
+ #
+ if self.FileName:
+ pass
+
+ #
+ # Insert Abstract, Description, CopyRight, License into header object
+ #
+ InfHeaderObject2.SetAbstract(Abstract)
+ InfHeaderObject2.SetDescription(Description)
+ InfHeaderObject2.SetCopyright(Copyright)
+ InfHeaderObject2.SetLicense(License)
+
+
+
+
+ ## Section header parser
+ #
+ # The section header is always in following format:
+ #
+ # [section_name.arch<.platform|module_type>]
+ #
+ # @param String A string contained the content need to be parsed.
+ #
+ def SectionHeaderParser(self, SectionString, FileName, LineNo):
+ _Scope = []
+ _SectionName = ''
+ ArchList = set()
+ _ValueList = []
+ _PcdNameList = [DT.TAB_INF_FIXED_PCD.upper(),
+ DT.TAB_INF_FEATURE_PCD.upper(),
+ DT.TAB_INF_PATCH_PCD.upper(),
+ DT.TAB_INF_PCD.upper(),
+ DT.TAB_INF_PCD_EX.upper()
+ ]
+ SectionString = SectionString.strip()
+ for Item in GetSplitValueList(SectionString[1:-1], DT.TAB_COMMA_SPLIT):
+ if Item == '':
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (""),
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+ ItemList = GetSplitValueList(Item, DT.TAB_SPLIT)
+ #
+ # different section should not mix in one section
+ # Allow different PCD type sections mixed together
+ #
+ if _SectionName.upper() not in _PcdNameList:
+ if _SectionName != '' and _SectionName.upper() != ItemList[0].upper():
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_SECTION_NAME_DUPLICATE,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+ elif _PcdNameList[1] in [_SectionName.upper(), ItemList[0].upper()] and \
+ (_SectionName.upper()!= ItemList[0].upper()):
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (""),
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+
+ _SectionName = ItemList[0]
+ if _SectionName.upper() in gINF_SECTION_DEF:
+ self._SectionType = gINF_SECTION_DEF[_SectionName.upper()]
+ else:
+ self._SectionType = DT.MODEL_UNKNOWN
+ Logger.Error("Parser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_UNKNOWN_SECTION,
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+
+ #
+ # Get Arch
+ #
+ Str1, ArchList = GetArch(ItemList, ArchList, FileName, LineNo, SectionString)
+
+ #
+ # For [Defines] section, do special check.
+ #
+ if ItemList[0].upper() == DT.TAB_COMMON_DEFINES.upper():
+ if len(ItemList) != 1:
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (SectionString),
+ File=FileName, Line=LineNo, ExtraData=SectionString)
+
+ #
+ # For [UserExtension] section, do special check.
+ #
+ if ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
+
+ RetValue = ProcessUseExtHeader(ItemList)
+
+ if not RetValue[0]:
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_FROMAT_INVALID % (SectionString),
+ File=FileName, Line=LineNo, ExtraData=SectionString)
+ else:
+ ItemList = RetValue[1]
+
+ if len(ItemList) == 3:
+ ItemList.append('COMMON')
+
+ Str1 = ItemList[1]
+
+ #
+ # For Library classes, need to check module type.
+ #
+ if ItemList[0].upper() == DT.TAB_LIBRARY_CLASSES.upper() and len(ItemList) == 3:
+ if ItemList[2] != '':
+ ModuleTypeList = GetSplitValueList(ItemList[2], DT.TAB_VALUE_SPLIT)
+ for Item in ModuleTypeList:
+ if Item.strip() not in DT.MODULE_LIST:
+ Logger.Error('Parser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_MODULETYPE_INVALID % (Item),
+ File=FileName,
+ Line=LineNo,
+ ExtraData=SectionString)
+ #
+ # GetSpecialStr2
+ #
+ Str2 = GetSpecialStr2(ItemList, FileName, LineNo, SectionString)
+
+ _Scope.append([Str1, Str2])
+
+ _NewValueList = []
+ _AppendFlag = True
+ if _SectionName.upper() in _PcdNameList:
+ for ValueItem in _ValueList:
+ if _SectionName.upper() == ValueItem[0].upper() and Str1.upper() not in ValueItem[1].split():
+ ValueItem[1] = ValueItem[1] + " " + Str1
+ _AppendFlag = False
+ elif _SectionName.upper() == ValueItem[0].upper() and Str1.upper() in ValueItem[1].split():
+ _AppendFlag = False
+
+ _NewValueList.append(ValueItem)
+
+ _ValueList = _NewValueList
+
+ if _AppendFlag:
+ if not ItemList[0].upper() == DT.TAB_USER_EXTENSIONS.upper():
+ _ValueList.append([_SectionName, Str1, Str2, LineNo])
+ else:
+ if len(ItemList) == 4:
+ _ValueList.append([_SectionName, Str1, Str2, ItemList[3], LineNo])
+
+ self.SectionHeaderContent = deepcopy(_ValueList)
+
+ ## GenSpecialSectionList
+ #
+ # @param SpecialSectionList: a list of list, of which item's format
+ # (Comment, LineNum)
+ # @param ContainerFile: Input value for filename of Inf file
+ #
+ def InfSpecialCommentParser (self, SpecialSectionList, InfSectionObject, ContainerFile, SectionType):
+ ReFindSpecialCommentRe = re.compile(r"""#(?:\s*)\[(.*?)\](?:.*)""", re.DOTALL)
+ ReFindHobArchRe = re.compile(r"""[Hh][Oo][Bb]\.([^,]*)""", re.DOTALL)
+ if self.FileName:
+ pass
+ SpecialObjectList = []
+ ArchList = []
+ if SectionType == DT.TYPE_EVENT_SECTION:
+ TokenDict = DT.EVENT_TOKENS
+ elif SectionType == DT.TYPE_HOB_SECTION:
+ TokenDict = DT.HOB_TOKENS
+ else:
+ TokenDict = DT.BOOTMODE_TOKENS
+
+ for List in SpecialSectionList:
+ #
+ # Hob has Arch attribute, need to be handled specially here
+ #
+ if SectionType == DT.TYPE_HOB_SECTION:
+
+ MatchObject = ReFindSpecialCommentRe.search(List[0][0])
+ HobSectionStr = MatchObject.group(1)
+ ArchList = []
+ for Match in ReFindHobArchRe.finditer(HobSectionStr):
+ Arch = Match.groups(1)[0].upper()
+ ArchList.append(Arch)
+ CommentSoFar = ''
+ for Index in xrange(1, len(List)):
+ Result = ParseComment(List[Index], DT.ALL_USAGE_TOKENS, TokenDict, [], False)
+ Usage = Result[0]
+ Type = Result[1]
+ HelpText = Result[3]
+
+ if Usage == DT.ITEM_UNDEFINED and Type == DT.ITEM_UNDEFINED:
+ if HelpText is None:
+ HelpText = ''
+ if not HelpText.endswith('\n'):
+ HelpText += '\n'
+ CommentSoFar += HelpText
+ else:
+ if HelpText:
+ CommentSoFar += HelpText
+ if SectionType == DT.TYPE_EVENT_SECTION:
+ SpecialObject = InfEventObject()
+ SpecialObject.SetEventType(Type)
+ SpecialObject.SetUsage(Usage)
+ SpecialObject.SetHelpString(CommentSoFar)
+ elif SectionType == DT.TYPE_HOB_SECTION:
+ SpecialObject = InfHobObject()
+ SpecialObject.SetHobType(Type)
+ SpecialObject.SetUsage(Usage)
+ SpecialObject.SetHelpString(CommentSoFar)
+ if len(ArchList) >= 1:
+ SpecialObject.SetSupArchList(ArchList)
+ else:
+ SpecialObject = InfBootModeObject()
+ SpecialObject.SetSupportedBootModes(Type)
+ SpecialObject.SetUsage(Usage)
+ SpecialObject.SetHelpString(CommentSoFar)
+
+ SpecialObjectList.append(SpecialObject)
+ CommentSoFar = ''
+ if not InfSectionObject.SetSpecialComments(SpecialObjectList,
+ SectionType):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % (SectionType),
+ ContainerFile
+ )
diff --git a/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py b/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py
new file mode 100644
index 0000000000..51db796035
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/InfSourceSectionParser.py
@@ -0,0 +1,145 @@
+## @file
+# This file contained the parser for [Sources] sections in INF file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfSourceSectionParser
+'''
+##
+# Import Modules
+#
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import FORMAT_INVALID
+from Parser.InfParserMisc import InfExpandMacro
+from Library import DataType as DT
+from Library.Parsing import MacroParser
+from Library.Misc import GetSplitValueList
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Parser.InfParserMisc import InfParserSectionRoot
+
+class InfSourceSectionParser(InfParserSectionRoot):
+ ## InfSourceParser
+ #
+ #
+ def InfSourceParser(self, SectionString, InfSectionObject, FileName):
+ SectionMacros = {}
+ ValueList = []
+ SourceList = []
+ StillCommentFalg = False
+ HeaderComments = []
+ LineComment = None
+ SectionContent = ''
+ for Line in SectionString:
+ SrcLineContent = Line[0]
+ SrcLineNo = Line[1]
+
+ if SrcLineContent.strip() == '':
+ continue
+
+ #
+ # Found Header Comments
+ #
+ if SrcLineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
+ #
+ # Last line is comments, and this line go on.
+ #
+ if StillCommentFalg:
+ HeaderComments.append(Line)
+ SectionContent += SrcLineContent + DT.END_OF_LINE
+ continue
+ #
+ # First time encounter comment
+ #
+ else:
+ #
+ # Clear original data
+ #
+ HeaderComments = []
+ HeaderComments.append(Line)
+ StillCommentFalg = True
+ SectionContent += SrcLineContent + DT.END_OF_LINE
+ continue
+ else:
+ StillCommentFalg = False
+
+ if len(HeaderComments) >= 1:
+ LineComment = InfLineCommentObject()
+ LineCommentContent = ''
+ for Item in HeaderComments:
+ LineCommentContent += Item[0] + DT.END_OF_LINE
+ LineComment.SetHeaderComments(LineCommentContent)
+
+ #
+ # Find Tail comment.
+ #
+ if SrcLineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
+ TailComments = SrcLineContent[SrcLineContent.find(DT.TAB_COMMENT_SPLIT):]
+ SrcLineContent = SrcLineContent[:SrcLineContent.find(DT.TAB_COMMENT_SPLIT)]
+ if LineComment == None:
+ LineComment = InfLineCommentObject()
+ LineComment.SetTailComments(TailComments)
+
+ #
+ # Find Macro
+ #
+ Name, Value = MacroParser((SrcLineContent, SrcLineNo),
+ FileName,
+ DT.MODEL_EFI_SOURCE_FILE,
+ self.FileLocalMacros)
+ if Name != None:
+ SectionMacros[Name] = Value
+ LineComment = None
+ HeaderComments = []
+ continue
+
+ #
+ # Replace with Local section Macro and [Defines] section Macro.
+ #
+ SrcLineContent = InfExpandMacro(SrcLineContent,
+ (FileName, SrcLineContent, SrcLineNo),
+ self.FileLocalMacros,
+ SectionMacros)
+
+ TokenList = GetSplitValueList(SrcLineContent, DT.TAB_VALUE_SPLIT, 4)
+ ValueList[0:len(TokenList)] = TokenList
+
+ #
+ # Store section content string after MACRO replaced.
+ #
+ SectionContent += SrcLineContent + DT.END_OF_LINE
+
+ SourceList.append((ValueList, LineComment,
+ (SrcLineContent, SrcLineNo, FileName)))
+ ValueList = []
+ LineComment = None
+ TailComments = ''
+ HeaderComments = []
+ continue
+
+ #
+ # Current section archs
+ #
+ ArchList = []
+ for Item in self.LastSectionHeaderContent:
+ if Item[1] not in ArchList:
+ ArchList.append(Item[1])
+ InfSectionObject.SetSupArchList(Item[1])
+
+ InfSectionObject.SetAllContent(SectionContent)
+ if not InfSectionObject.SetSources(SourceList, Arch = ArchList):
+ Logger.Error('InfParser',
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR % ("[Sources]"),
+ File=FileName,
+ Line=Item[3]) \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Parser/__init__.py b/BaseTools/Source/Python/UPT/Parser/__init__.py
new file mode 100644
index 0000000000..151f9ed433
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Parser/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Parser' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Parser
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py b/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
new file mode 100644
index 0000000000..cb8aa18788
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/PomAdapter/DecPomAlignment.py
@@ -0,0 +1,607 @@
+## @file DecPomAlignment.py
+# This file contained the adapter for convert INF parser object to POM Object
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+DecPomAlignment
+'''
+
+##
+# Import Modules
+#
+import os.path
+from os import sep
+import platform
+
+import Logger.Log as Logger
+from Logger import StringTable as ST
+from Logger.ToolError import UPT_MUL_DEC_ERROR
+
+from Library.Parsing import NormPath
+from Library.DataType import ARCH_LIST
+from Library.DataType import TAB_GUIDS
+from Library.DataType import TAB_PROTOCOLS
+from Library.DataType import TAB_PPIS
+from Library.DataType import TAB_DEC_DEFINES_PACKAGE_NAME
+from Library.DataType import TAB_DEC_DEFINES_PACKAGE_GUID
+from Library.DataType import TAB_DEC_DEFINES_PACKAGE_VERSION
+from Library.DataType import TAB_DEC_DEFINES_DEC_SPECIFICATION
+from Library.DataType import TAB_ARCH_COMMON
+from Library.CommentParsing import ParseHeaderCommentSection
+from Library.DataType import TAB_INCLUDES
+from Library.CommentParsing import ParseGenericComment
+from Library.DataType import TAB_LIBRARY_CLASSES
+from Library.DataType import TAB_PCDS
+from Library.DataType import TAB_PCDS_FIXED_AT_BUILD_NULL
+from Library.DataType import TAB_PCDS_PATCHABLE_IN_MODULE_NULL
+from Library.DataType import TAB_PCDS_FEATURE_FLAG_NULL
+from Library.DataType import TAB_PCDS_DYNAMIC_EX_NULL
+from Library.DataType import TAB_PCDS_DYNAMIC_NULL
+from Library.DataType import TAB_PTR_TYPE_PCD
+from Library.DataType import ITEM_UNDEFINED
+from Library.CommentParsing import ParseDecPcdGenericComment
+from Library.CommentParsing import ParseDecPcdTailComment
+from Library.Misc import GetFiles
+from Library.Misc import Sdict
+from Parser.DecParser import Dec
+
+from Object.POM.PackageObject import PackageObject
+from Object.POM.CommonObject import UserExtensionObject
+from Object.POM.CommonObject import IncludeObject
+from Object.POM.CommonObject import GuidObject
+from Object.POM.CommonObject import ProtocolObject
+from Object.POM.CommonObject import PpiObject
+from Object.POM.CommonObject import LibraryClassObject
+from Object.POM.CommonObject import PcdObject
+from Object.POM.CommonObject import TextObject
+
+
+## DecPomAlignment
+#
+# Inherited from PackageObject
+#
+class DecPomAlignment(PackageObject):
+ def __init__(self, Filename, WorkspaceDir = None, CheckMulDec = False):
+ PackageObject.__init__(self)
+ self.UserExtensions = ''
+ self.WorkspaceDir = WorkspaceDir
+ self.SupArchList = ARCH_LIST
+ self.CheckMulDec = CheckMulDec
+ self.DecParser = None
+
+ #
+ # Load Dec file
+ #
+ self.LoadDecFile(Filename)
+
+ #
+ # Transfer to Package Object if IsToPackage is True
+ #
+ self.DecToPackage()
+
+ ## Load Dec file
+ #
+ # Load the file if it exists
+ #
+ # @param Filename: Input value for filename of Dec file
+ #
+ def LoadDecFile(self, Filename):
+ #
+ # Insert a record for file
+ #
+ Filename = NormPath(Filename)
+ (Path, Name) = os.path.split(Filename)
+ self.SetFullPath(Filename)
+ self.SetRelaPath(Path)
+ self.SetFileName(Name)
+ self.SetPackagePath(Path[Path.upper().find(self.WorkspaceDir.upper()) + len(self.WorkspaceDir) + 1:])
+ self.SetCombinePath(Filename[Filename.upper().find(self.WorkspaceDir.upper()) + len(self.WorkspaceDir) + 1:])
+
+ self.DecParser = Dec(Filename)
+
+ ## Transfer to Package Object
+ #
+ # Transfer all contents of a Dec file to a standard Package Object
+ #
+ def DecToPackage(self):
+ #
+ # Init global information for the file
+ #
+ ContainerFile = self.GetFullPath()
+
+ #
+ # Generate Package Header
+ #
+ self.GenPackageHeader(ContainerFile)
+
+ #
+ # Generate Includes
+ #
+ self.GenIncludes(ContainerFile)
+
+ #
+ # Generate Guids
+ #
+ self.GenGuidProtocolPpis(TAB_GUIDS, ContainerFile)
+
+ #
+ # Generate Protocols
+ #
+ self.GenGuidProtocolPpis(TAB_PROTOCOLS, ContainerFile)
+
+ #
+ # Generate Ppis
+ #
+ self.GenGuidProtocolPpis(TAB_PPIS, ContainerFile)
+
+ #
+ # Generate LibraryClasses
+ #
+ self.GenLibraryClasses(ContainerFile)
+
+ #
+ # Generate Pcds
+ #
+ self.GenPcds(ContainerFile)
+
+ #
+ # Generate Module File list, will be used later on to generate
+ # distribution
+ #
+ self.GenModuleFileList(ContainerFile)
+
+ #
+ # Generate user extensions
+ #
+ self.GenUserExtensions()
+
+ ## Generate user extention
+ #
+ #
+ def GenUserExtensions(self):
+ UEObj = self.DecParser.GetUserExtensionSectionObject()
+ UEList = UEObj.GetAllUserExtensions()
+ for Item in UEList:
+ if not Item.UserString:
+ continue
+ UserExtension = UserExtensionObject()
+ UserId = Item.UserId
+ if UserId.startswith('"') and UserId.endswith('"'):
+ UserId = UserId[1:-1]
+ UserExtension.SetUserID(UserId)
+ Identifier = Item.IdString
+ if Identifier.startswith('"') and Identifier.endswith('"'):
+ Identifier = Identifier[1:-1]
+ UserExtension.SetIdentifier(Identifier)
+ UserExtension.SetStatement(Item.UserString)
+ UserExtension.SetSupArchList(
+ Item.ArchAndModuleType
+ )
+ self.SetUserExtensionList(
+ self.GetUserExtensionList() + [UserExtension]
+ )
+
+ ## Generate Package Header
+ #
+ # Gen Package Header of Dec as <Key> = <Value>
+ #
+ # @param ContainerFile: The Dec file full path
+ #
+ def GenPackageHeader(self, ContainerFile):
+ Logger.Debug(2, "Generate PackageHeader ...")
+ DefinesDict = {}
+
+ #
+ # Update all defines item in database
+ #
+ DefObj = self.DecParser.GetDefineSectionObject()
+ for Item in DefObj.GetDefines():
+ #
+ # put items into Dict except for PackageName, Guid, Version, DEC_SPECIFICATION
+ #
+ SkipItemList = [TAB_DEC_DEFINES_PACKAGE_NAME, \
+ TAB_DEC_DEFINES_PACKAGE_GUID, TAB_DEC_DEFINES_PACKAGE_VERSION, TAB_DEC_DEFINES_DEC_SPECIFICATION]
+ if Item.Key in SkipItemList:
+ continue
+ DefinesDict['%s = %s' % (Item.Key, Item.Value)] = TAB_ARCH_COMMON
+
+ self.SetBaseName(DefObj.GetPackageName())
+ self.SetVersion(DefObj.GetPackageVersion())
+# self.SetName(DefObj.GetPackageName() + ' Version ' + \
+# DefObj.GetPackageVersion())
+ self.SetName(os.path.splitext(self.GetFileName())[0])
+ self.SetGuid(DefObj.GetPackageGuid())
+
+ if DefinesDict:
+ UserExtension = UserExtensionObject()
+ UserExtension.SetDefinesDict(DefinesDict)
+ UserExtension.SetIdentifier('DefineModifiers')
+ UserExtension.SetUserID('EDK2')
+ self.SetUserExtensionList(
+ self.GetUserExtensionList() + [UserExtension]
+ )
+
+ #
+ # Get All header comment section information
+ #
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(self.DecParser.GetHeadComment(),
+ ContainerFile)
+ self.SetAbstract(Abstract)
+ self.SetDescription(Description)
+ self.SetCopyright(Copyright)
+ self.SetLicense(License)
+
+ ## GenIncludes
+ #
+ # Gen Includes of Dec
+ #
+ # @param ContainerFile: The Dec file full path
+ #
+ def GenIncludes(self, ContainerFile):
+ if ContainerFile:
+ pass
+ Logger.Debug(2, "Generate %s ..." % TAB_INCLUDES)
+ IncludesDict = Sdict()
+
+ IncObj = self.DecParser.GetIncludeSectionObject()
+ for Item in IncObj.GetAllIncludes():
+ IncludePath = os.path.normpath(Item.File)
+ if platform.system() != 'Windows':
+ IncludePath = IncludePath.replace('\\', '/')
+ if IncludePath in IncludesDict:
+ if Item.GetArchList() == [TAB_ARCH_COMMON] or IncludesDict[IncludePath] == [TAB_ARCH_COMMON]:
+ IncludesDict[IncludePath] = [TAB_ARCH_COMMON]
+ else:
+ IncludesDict[IncludePath] = IncludesDict[IncludePath] + Item.GetArchList()
+ else:
+ IncludesDict[IncludePath] = Item.GetArchList()
+
+ #
+ # get the standardIncludeFileList(industry), packageIncludeFileList
+ # (others) for PackageObject
+ #
+ PackagePath = os.path.split(self.GetFullPath())[0]
+ IncludePathList = \
+ [os.path.normpath(Path) + sep for Path in IncludesDict.keys()]
+ IncludePathList.sort()
+
+ #
+ # get a non-overlap set of include path, IncludePathList should be
+ # sorted, and path should be end with path seperator '\'
+ #
+ NonOverLapList = []
+ for Path1 in IncludePathList:
+ for Path2 in NonOverLapList:
+ if Path1.startswith(Path2):
+ break
+ else:
+ NonOverLapList.append(Path1)
+ #
+ # revert the list so the longest path shown first in list, also need
+ # to remove the extra path seperator '\'
+ # as this list is used to search the supported Arch info
+ #
+ for IndexN in range (0, len(IncludePathList)):
+ IncludePathList[IndexN] = os.path.normpath(IncludePathList[IndexN])
+ IncludePathList.sort()
+ IncludePathList.reverse()
+ #
+ # save the include path list for later usage
+ #
+ self.SetIncludePathList(IncludePathList)
+ StandardIncludeFileList = []
+ PackageIncludeFileList = []
+
+ IncludeFileList = []
+ for Path in NonOverLapList:
+ FileList = GetFiles(os.path.join(PackagePath, Path), ['CVS', '.svn'], False)
+ IncludeFileList += [os.path.normpath(os.path.join(Path, File)) for File in FileList]
+ for Includefile in IncludeFileList:
+ ExtName = os.path.splitext(Includefile)[1]
+ if ExtName.upper() == '.DEC' and self.CheckMulDec:
+ Logger.Error('MkPkg',
+ UPT_MUL_DEC_ERROR,
+ ST.ERR_MUL_DEC_ERROR%(os.path.dirname(ContainerFile),
+ os.path.basename(ContainerFile),
+ Includefile))
+
+ FileCombinePath = os.path.dirname(Includefile)
+ Include = IncludeObject()
+ for Path in IncludePathList:
+ if FileCombinePath.startswith(Path):
+ SupArchList = IncludesDict[Path]
+ break
+ Include.SetFilePath(Includefile)
+ Include.SetSupArchList(SupArchList)
+ if Includefile.find('IndustryStandard') != -1:
+ StandardIncludeFileList.append(Include)
+ else:
+ PackageIncludeFileList.append(Include)
+
+ self.SetStandardIncludeFileList(StandardIncludeFileList)
+
+ #
+ # put include path into the PackageIncludeFileList
+ #
+ PackagePathList = []
+ IncObj = self.DecParser.GetIncludeSectionObject()
+ for Item in IncObj.GetAllIncludes():
+ IncludePath = Item.File
+ Include = IncludeObject()
+ Include.SetFilePath(IncludePath)
+ Include.SetSupArchList(Item.GetArchList())
+ PackagePathList.append(Include)
+ self.SetPackageIncludeFileList(PackagePathList + PackageIncludeFileList)
+
+ ## GenPpis
+ #
+ # Gen Ppis of Dec
+ # <CName>=<GuidValue>
+ #
+ # @param ContainerFile: The Dec file full path
+ #
+ def GenGuidProtocolPpis(self, Type, ContainerFile):
+ if ContainerFile:
+ pass
+ Logger.Debug(2, "Generate %s ..." % Type)
+
+ Obj = None
+ Factory = None
+ if Type == TAB_GUIDS:
+ Obj = self.DecParser.GetGuidSectionObject()
+ def CreateGuidObject():
+ Object = GuidObject()
+ Object.SetGuidTypeList([])
+ Object.SetUsage(None)
+ Object.SetName(None)
+ return Object
+ Factory = CreateGuidObject
+ elif Type == TAB_PROTOCOLS:
+ Obj = self.DecParser.GetProtocolSectionObject()
+
+ def CreateProtocolObject():
+ return ProtocolObject()
+ Factory = CreateProtocolObject
+ elif Type == TAB_PPIS:
+ Obj = self.DecParser.GetPpiSectionObject()
+
+ def CreatePpiObject():
+ return PpiObject()
+ Factory = CreatePpiObject
+ else:
+ #
+ # Should not be here
+ #
+ return
+
+ DeclarationsList = []
+
+ #
+ # Go through each arch
+ #
+ for Item in Obj.GetGuidStyleAllItems():
+ Name = Item.GuidCName
+ Value = Item.GuidString
+ HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
+ Item.GetTailComment())
+
+ ListObject = Factory()
+ ListObject.SetCName(Name)
+ ListObject.SetGuid(Value)
+ ListObject.SetSupArchList(Item.GetArchList())
+ if HelpTxt:
+ ListObject.SetHelpTextList([HelpTxt])
+
+ DeclarationsList.append(ListObject)
+
+ #
+ #GuidTypeList is abstracted from help
+ #
+ if Type == TAB_GUIDS:
+ self.SetGuidList(self.GetGuidList() + DeclarationsList)
+ elif Type == TAB_PROTOCOLS:
+ self.SetProtocolList(self.GetProtocolList() + DeclarationsList)
+ elif Type == TAB_PPIS:
+ self.SetPpiList(self.GetPpiList() + DeclarationsList)
+
+ ## GenLibraryClasses
+ #
+ # Gen LibraryClasses of Dec
+ # <CName>=<GuidValue>
+ #
+ # @param ContainerFile: The Dec file full path
+ #
+ def GenLibraryClasses(self, ContainerFile):
+ if ContainerFile:
+ pass
+ Logger.Debug(2, "Generate %s ..." % TAB_LIBRARY_CLASSES)
+ LibraryClassDeclarations = []
+
+ LibObj = self.DecParser.GetLibraryClassSectionObject()
+ for Item in LibObj.GetAllLibraryclasses():
+ LibraryClass = LibraryClassObject()
+ LibraryClass.SetLibraryClass(Item.Libraryclass)
+ LibraryClass.SetSupArchList(Item.GetArchList())
+ LibraryClass.SetIncludeHeader(Item.File)
+ HelpTxt = ParseGenericComment(Item.GetHeadComment() + \
+ Item.GetTailComment(), None, '@libraryclass')
+ if HelpTxt:
+ LibraryClass.SetHelpTextList([HelpTxt])
+ LibraryClassDeclarations.append(LibraryClass)
+
+ self.SetLibraryClassList(self.GetLibraryClassList() + \
+ LibraryClassDeclarations)
+
+ ## GenPcds
+ #
+ # Gen Pcds of Dec
+ # <TokenSpcCName>.<TokenCName>|<Value>|<DatumType>|<Token>
+ #
+ # @param ContainerFile: The Dec file full path
+ #
+ def GenPcds(self, ContainerFile):
+ Logger.Debug(2, "Generate %s ..." % TAB_PCDS)
+
+ PcdObj = self.DecParser.GetPcdSectionObject()
+ #
+ # Get all Pcds
+ #
+ PcdDeclarations = []
+ IterList = [
+ (TAB_PCDS_FIXED_AT_BUILD_NULL, 'FixedPcd'),
+ (TAB_PCDS_PATCHABLE_IN_MODULE_NULL, 'PatchPcd'),
+ (TAB_PCDS_FEATURE_FLAG_NULL, 'FeaturePcd'),
+ (TAB_PCDS_DYNAMIC_EX_NULL, 'PcdEx'),
+ (TAB_PCDS_DYNAMIC_NULL, 'Pcd')]
+ #
+ # For each PCD type
+ #
+ for PcdType, Type in IterList:
+ #
+ # Go through all archs
+ #
+ # for Arch in self.SupArchList + [TAB_ARCH_COMMON]:
+ #
+ for Item in PcdObj.GetPcdsByType(PcdType.upper()):
+ PcdDeclaration = GenPcdDeclaration(
+ ContainerFile,
+ (Item.TokenSpaceGuidCName, Item.TokenCName,
+ Item.DefaultValue, Item.DatumType, Item.TokenValue,
+ Type, Item.GetHeadComment(), Item.GetTailComment(),
+ '')
+ )
+ PcdDeclaration.SetSupArchList(Item.GetArchListOfType(PcdType))
+ PcdDeclarations.append(PcdDeclaration)
+
+ self.SetPcdList(self.GetPcdList() + PcdDeclarations)
+
+
+ ## GenModuleFileList
+ #
+ def GenModuleFileList(self, ContainerFile):
+ ModuleFileList = []
+ ContainerFileName = os.path.basename(ContainerFile)
+ ContainerFilePath = os.path.dirname(ContainerFile)
+ for Item in GetFiles(ContainerFilePath,
+ ['CVS', '.svn'] + self.GetIncludePathList(), False):
+ ExtName = os.path.splitext(Item)[1]
+ if ExtName.lower() == '.inf':
+ ModuleFileList.append(Item)
+ elif ExtName.upper() == '.DEC' and self.CheckMulDec:
+ if Item == ContainerFileName:
+ continue
+ Logger.Error('MkPkg',
+ UPT_MUL_DEC_ERROR,
+ ST.ERR_MUL_DEC_ERROR%(ContainerFilePath,
+ ContainerFileName,
+ Item))
+
+ self.SetModuleFileList(ModuleFileList)
+
+ ## Show detailed information of Package
+ #
+ # Print all members and their values of Package class
+ #
+ def ShowPackage(self):
+ print '\nName =', self.GetName()
+ print '\nBaseName =', self.GetBaseName()
+ print '\nVersion =', self.GetVersion()
+ print '\nGuid =', self.GetGuid()
+
+ print '\nStandardIncludes = %d ' \
+ % len(self.GetStandardIncludeFileList()),
+ for Item in self.GetStandardIncludeFileList():
+ print Item.GetFilePath(), ' ', Item.GetSupArchList()
+ print '\nPackageIncludes = %d \n' \
+ % len(self.GetPackageIncludeFileList()),
+ for Item in self.GetPackageIncludeFileList():
+ print Item.GetFilePath(), ' ', Item.GetSupArchList()
+
+ print '\nGuids =', self.GetGuidList()
+ for Item in self.GetGuidList():
+ print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
+ print '\nProtocols =', self.GetProtocolList()
+ for Item in self.GetProtocolList():
+ print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
+ print '\nPpis =', self.GetPpiList()
+ for Item in self.GetPpiList():
+ print Item.GetCName(), Item.GetGuid(), Item.GetSupArchList()
+ print '\nLibraryClasses =', self.GetLibraryClassList()
+ for Item in self.GetLibraryClassList():
+ print Item.GetLibraryClass(), Item.GetRecommendedInstance(), \
+ Item.GetSupArchList()
+ print '\nPcds =', self.GetPcdList()
+ for Item in self.GetPcdList():
+ print 'CName=', Item.GetCName(), 'TokenSpaceGuidCName=', \
+ Item.GetTokenSpaceGuidCName(), \
+ 'DefaultValue=', Item.GetDefaultValue(), \
+ 'ValidUsage=', Item.GetValidUsage(), \
+ 'SupArchList', Item.GetSupArchList(), \
+ 'Token=', Item.GetToken(), 'DatumType=', Item.GetDatumType()
+
+ for Item in self.GetMiscFileList():
+ print Item.GetName()
+ for FileObjectItem in Item.GetFileList():
+ print FileObjectItem.GetURI()
+ print '****************\n'
+
+## GenPcdDeclaration
+#
+# @param ContainerFile: File name of the DEC file
+# @param PcdInfo: Pcd information, of format (TokenGuidCName,
+# TokenName, Value, DatumType, Token, Type,
+# GenericComment, TailComment, Arch)
+#
+def GenPcdDeclaration(ContainerFile, PcdInfo):
+ HelpStr = ''
+ TailHelpStr = ''
+ TokenGuidCName, TokenName, Value, DatumType, Token, Type, \
+ GenericComment, TailComment, Arch = PcdInfo
+ Pcd = PcdObject()
+ Pcd.SetCName(TokenName)
+ Pcd.SetToken(Token)
+ Pcd.SetTokenSpaceGuidCName(TokenGuidCName)
+ Pcd.SetDatumType(DatumType)
+ Pcd.SetDefaultValue(Value)
+ Pcd.SetValidUsage(Type)
+ #
+ # MaxDatumSize is required field for 'VOID*' PCD
+ #
+ if DatumType == TAB_PTR_TYPE_PCD:
+ Pcd.SetMaxDatumSize(ITEM_UNDEFINED)
+
+ SupArchList = [Arch]
+ Pcd.SetSupArchList(SupArchList)
+
+ if GenericComment:
+ HelpStr, PcdErr = ParseDecPcdGenericComment(GenericComment,
+ ContainerFile)
+ if PcdErr:
+ Pcd.SetPcdErrorsList([PcdErr])
+
+ if TailComment:
+ SupModuleList, TailHelpStr = ParseDecPcdTailComment(TailComment,
+ ContainerFile)
+ if SupModuleList:
+ Pcd.SetSupModuleList(SupModuleList)
+
+ if HelpStr and (not HelpStr.endswith('\n')) and TailHelpStr:
+ HelpStr += '\n'
+ HelpStr += TailHelpStr
+ if HelpStr:
+ HelpTxtObj = TextObject()
+ HelpTxtObj.SetString(HelpStr)
+ Pcd.SetHelpTextList([HelpTxtObj])
+
+ return Pcd
diff --git a/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py
new file mode 100644
index 0000000000..20daff0d32
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignment.py
@@ -0,0 +1,972 @@
+## @file InfPomAlignment.py
+# This file contained the adapter for convert INF parser object to POM Object
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+'''
+InfPomAlignment
+'''
+##
+# Import modules
+#
+import os.path
+
+from Logger import StringTable as ST
+import Logger.Log as Logger
+
+from Library.String import FORMAT_INVALID
+from Library.String import PARSER_ERROR
+from Library.String import NormPath
+from Library.String import GetSplitValueList
+from Library.Misc import ConvertVersionToDecimal
+from Library.Misc import GetHelpStringByRemoveHashKey
+from Library.Misc import ConvertArchList
+from Library.Parsing import GetPkgInfoFromDec
+from Library import DataType as DT
+from Library import GlobalData
+
+from Object.POM import CommonObject
+from Object.POM.ModuleObject import ModuleObject
+from Object.POM.ModuleObject import ExternObject
+from Object.POM.ModuleObject import HobObject
+from Object.POM.ModuleObject import EventObject
+from Object.POM.ModuleObject import BootModeObject
+from Object.POM.ModuleObject import PackageDependencyObject
+from Object.POM.ModuleObject import SourceFileObject
+from Object.POM.ModuleObject import DepexObject
+from Object.POM.ModuleObject import AsBuildLibraryClassObject
+from Object.POM.ModuleObject import AsBuiltObject
+from PomAdapter.InfPomAlignmentMisc import GenModuleHeaderUserExt
+from PomAdapter.InfPomAlignmentMisc import GenBinaryData
+from Parser import InfParser
+
+
+
+## InfPomAlignment
+#
+# Inherit from ModuleObject
+#
+class InfPomAlignment(ModuleObject):
+ ## Construct of InfPomAlignment
+ # Skip means that UPT don't care the syntax of INF, this may be the not
+ # distributed INF files during creation or the INF files checked for
+ # dependency rule during remove.
+ #
+ def __init__(self, FileName, WorkSpace=None, PackagePath='', Skip=False):
+ ModuleObject.__init__(self)
+
+ self.Parser = None
+ self.FileName = FileName
+ self.WorkSpace = WorkSpace
+ self.CombinePath = ''
+ self.LibModuleTypeList = []
+ self.FullPath = ''
+ self.ModulePath = ''
+ self.WorkspaceDir = " "
+ self.CustomMakefile = []
+
+ self.SetPackagePath(PackagePath)
+ #
+ # Call GenInfPomObjects function to fill POM object.
+ #
+ if Skip:
+ OrigConfig = Logger.SUPRESS_ERROR
+ Logger.SUPRESS_ERROR = True
+ self._GenInfPomObjects(Skip)
+ Logger.SUPRESS_ERROR = OrigConfig
+ else:
+ self._GenInfPomObjects(Skip)
+
+ ##
+ # Generate all POM objects, the original input comes
+ # from INF parser's output
+ #
+ def _GenInfPomObjects(self, Skip):
+ #
+ # Call INF Parser to get information from INF file
+ #
+ self.Parser = InfParser.InfParser(self.FileName, self.WorkSpace)
+ self.FullPath = self.Parser.FullPath
+ self.GetFullPath()
+ self._GenModuleHeader()
+ #
+ # Call GenBinaries after Module Header for Binary INF consideration.
+ #
+ self._GenBinaries()
+ self._GenBuildOptions()
+ self._GenLibraryClasses()
+ self._GenPackages(Skip)
+ self._GenPcds()
+ self._GenSources()
+ self._GenUserExtensions()
+ self._GenGuidProtocolPpis(DT.TAB_GUIDS)
+ self._GenGuidProtocolPpis(DT.TAB_PROTOCOLS)
+ self._GenGuidProtocolPpis(DT.TAB_PPIS)
+ self._GenDepexes()
+ self._GenMiscFiles(self.FullPath, Skip)
+
+ ## Convert [Defines] section content to InfDefObject
+ #
+ # Convert [Defines] section content to InfDefObject
+ #
+ # @param Defines The content under [Defines] section
+ # @param ModuleHeader An object of ModuleHeaderClass
+ # @param Arch The supported ARCH
+ #
+ def _GenModuleHeader(self):
+ Logger.Debug(2, "Generate ModuleHeader ...")
+ #
+ # Get all defines information form InfParser Object
+ #
+ RecordSet = self.Parser.InfDefSection.Defines
+ #
+ # Should only have one ArchString Item.
+ #
+ ArchString = RecordSet.keys()[0]
+ ArchList = GetSplitValueList(ArchString, ' ')
+ ArchList = ConvertArchList(ArchList)
+ HasCalledFlag = False
+
+ #
+ # Get data from Sdict()
+ #
+ ValueList = RecordSet[ArchString]
+ self.SetFileName(self.FileName)
+ self.SetFullPath(self.FullPath)
+ #
+ # The INF's filename (without the directory path or the extension)
+ # must be used for the value of the
+ # ModuleSurfaceArea.Header.Name element
+ #
+ self.SetName(os.path.splitext(os.path.basename(self.FileName))[0])
+
+ self.WorkspaceDir = " "
+ #
+ # CombinePath and ModulePath
+ #
+ PathCount = self.FullPath.upper().find(self.WorkSpace.upper()) + len(self.WorkSpace) + 1
+ CombinePath = self.FullPath[PathCount:]
+ self.SetCombinePath(CombinePath)
+
+ ModulePath = os.path.split(CombinePath)[0]
+ ModuleRelativePath = ModulePath
+ if self.GetPackagePath() != '':
+ ModuleRelativePath = ModulePath[ModulePath.find(self.GetPackagePath()) + len(self.GetPackagePath()) + 1:]
+ self.SetModulePath(ModuleRelativePath)
+
+ #
+ # For Define Seciton Items.
+ #
+ DefineObj = ValueList
+
+ #
+ # Convert UEFI/PI version to decimal number
+ #
+ if DefineObj.GetUefiSpecificationVersion() != None:
+ __UefiVersion = DefineObj.GetUefiSpecificationVersion().GetValue()
+ __UefiVersion = ConvertVersionToDecimal(__UefiVersion)
+ self.SetUefiSpecificationVersion(str(__UefiVersion))
+ if DefineObj.GetPiSpecificationVersion() != None:
+ __PiVersion = DefineObj.GetPiSpecificationVersion().GetValue()
+ __PiVersion = ConvertVersionToDecimal(__PiVersion)
+
+ self.SetPiSpecificationVersion(str(__PiVersion))
+
+ SpecList = DefineObj.GetSpecification()
+ NewSpecList = []
+ for SpecItem in SpecList:
+ NewSpecList.append((SpecItem[0], ConvertVersionToDecimal(SpecItem[1])))
+ self.SetSpecList(NewSpecList)
+
+ #
+ # must exist items in INF define section
+ # MODULE_TYPE/BASE_NAME/INF_VERSION/FILE_GUID/VERSION_STRING
+ #
+ if DefineObj.GetModuleType() == None:
+ Logger.Error("InfParser", FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("MODULE_TYPE"), File=self.FullPath)
+ else:
+ self.SetModuleType(DefineObj.GetModuleType().GetValue())
+ ModuleType = DefineObj.GetModuleType().GetValue()
+ if ModuleType:
+ #
+ # Drivers and applications are not allowed to have a MODULE_TYPE of "BASE". Only
+ # libraries are permitted to a have a MODULE_TYPE of "BASE".
+ #
+ if len(DefineObj.LibraryClass) == 0 and ModuleType == 'BASE':
+ Logger.Error("InfParser",
+ FORMAT_INVALID,
+ ST.ERR_INF_PARSER_MODULETYPE_INVALID,
+ File=self.FullPath,
+ Line=DefineObj.ModuleType.CurrentLine.LineNo,
+ ExtraData=DefineObj.ModuleType.CurrentLine.LineString)
+ self.LibModuleTypeList.append(ModuleType)
+ if DefineObj.GetBaseName() == None:
+ Logger.Error("InfParser", FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("BASE_NAME"), File=self.FullPath)
+ else:
+ self.SetBaseName(DefineObj.GetBaseName().GetValue())
+ if DefineObj.GetInfVersion() == None:
+ Logger.Error("InfParser", FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("INF_VERSION"), File=self.FullPath)
+ else:
+ self.SetVersion(DefineObj.GetInfVersion().GetValue())
+ if DefineObj.GetFileGuid() == None:
+ Logger.Error("InfParser", FORMAT_INVALID,
+ ST.ERR_INF_PARSER_DEFINE_SECTION_MUST_ITEM_NOT_EXIST % ("FILE_GUID"), File=self.FullPath)
+ else:
+ self.SetGuid(DefineObj.GetFileGuid().GetValue())
+ if DefineObj.GetVersionString() == None:
+ #
+ # VERSION_STRING is missing from the [Defines] section, tools must assume that the module's version is 0.
+ #
+ self.SetVersion('0')
+ else:
+ #
+ # Get version of INF
+ #
+ if DefineObj.GetVersionString().GetValue() != "":
+ #
+ # EDK2 inf
+ #
+ VersionString = DefineObj.GetVersionString().GetValue()
+ if len(VersionString) > 0:
+ VersionString = ConvertVersionToDecimal(VersionString)
+ self.SetVersion(VersionString)
+ else:
+ #
+ # EDK1 inf
+ #
+ Logger.Error("Parser", PARSER_ERROR, ST.ERR_INF_PARSER_NOT_SUPPORT_EDKI_INF, ExtraData=self.FullPath,
+ RaiseError=Logger.IS_RAISE_ERROR)
+
+ #
+ # if there is Shadow, Should judge the MODULE_TYPE in
+ # SEC, PEI_CORE and PEIM
+ #
+ if DefineObj.GetShadow():
+ ModuleTypeValue = DefineObj.GetModuleType().GetValue()
+ if not (ModuleTypeValue == 'SEC' or ModuleTypeValue == 'PEI_CORE' or ModuleTypeValue == 'PEIM'):
+ Logger.Error("InfParser", FORMAT_INVALID, ST.ERR_INF_PARSER_DEFINE_SHADOW_INVALID, File=self.FullPath)
+
+ if DefineObj.GetPcdIsDriver() != None:
+ self.SetPcdIsDriver(DefineObj.GetPcdIsDriver().GetValue())
+
+ #
+ # LIBRARY_CLASS
+ #
+ self._GenModuleHeaderLibClass(DefineObj, ArchList)
+
+ #
+ # CUSTOM_MAKEFILE
+ #
+ self.CustomMakefile = DefineObj.GetCustomMakefile()
+ #
+ # Externs in Defines section
+ # Only one define section, so just call once.
+ #
+ if not HasCalledFlag:
+ self._GenModuleHeaderExterns(DefineObj)
+ HasCalledFlag = True
+
+ #
+ # each module has only one module header
+ #
+ self.SetSupArchList(ArchList)
+ #
+ # Get Hob/BootMode/EventList information
+ #
+ self._GenSpecialComments()
+ #
+ # put all define statement into user-extension sections
+ #
+ DefinesDictNew = GenModuleHeaderUserExt(DefineObj, ArchString)
+
+ if DefinesDictNew:
+ UserExtension = CommonObject.UserExtensionObject()
+ UserExtension.SetDefinesDict(DefinesDictNew)
+ UserExtension.SetIdentifier('DefineModifiers')
+ UserExtension.SetUserID('EDK2')
+ self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
+
+ #
+ # Get all meta-file header information
+ # the record is list of items formated:
+ # [LineValue, Arch, StartLine, ID, Third]
+ #
+
+ InfHeaderObj = self.Parser.InfHeader
+ #
+ # Put header information into POM object
+ #
+ self.SetAbstract(InfHeaderObj.GetAbstract())
+ self.SetDescription(InfHeaderObj.GetDescription())
+ self.SetCopyright(InfHeaderObj.GetCopyright())
+ self.SetLicense(InfHeaderObj.GetLicense())
+
+ ## GenModuleHeaderLibClass
+ #
+ #
+ def _GenModuleHeaderLibClass(self, DefineObj, ArchList):
+ LibraryList = DefineObj.GetLibraryClass()
+ for LibraryItem in LibraryList:
+ Lib = CommonObject.LibraryClassObject()
+ Lib.SetLibraryClass(LibraryItem.GetLibraryName())
+ Lib.SetUsage(DT.USAGE_ITEM_PRODUCES)
+ SupModuleList = LibraryItem.GetTypes()
+ self.LibModuleTypeList += SupModuleList
+ Lib.SetSupModuleList(SupModuleList)
+ Lib.SetSupArchList(ArchList)
+ self.SetLibraryClassList(self.GetLibraryClassList() + [Lib])
+ self.SetIsLibrary(True)
+ self.SetIsLibraryModList(self.GetIsLibraryModList() + SupModuleList)
+
+ ## GenModuleHeaderExterns
+ #
+ #
+ def _GenModuleHeaderExterns(self, DefineObj):
+ EntryPointList = DefineObj.GetEntryPoint()
+ for EntryPoint in EntryPointList:
+ Image = ExternObject()
+ Image.SetEntryPoint(EntryPoint.GetCName())
+ #
+ # Future enhancement
+ #
+ self.SetExternList(self.GetExternList() + [Image])
+ #
+ # UNLOAD_IMAGE
+ #
+ UnloadImageList = DefineObj.GetUnloadImages()
+ for UnloadImage in UnloadImageList:
+ Image = ExternObject()
+ #
+ # Future enhancement
+ #
+ Image.SetUnloadImage(UnloadImage.GetCName())
+ self.SetExternList(self.GetExternList() + [Image])
+ #
+ # CONSTRUCTOR
+ #
+ ConstructorList = DefineObj.GetConstructor()
+ for ConstructorItem in ConstructorList:
+ Image = ExternObject()
+ #
+ # Future enhancement
+ #
+ Image.SetConstructor(ConstructorItem.GetCName())
+ self.SetExternList(self.GetExternList() + [Image])
+ #
+ # DESTRUCTOR
+ #
+ DestructorList = DefineObj.GetDestructor()
+ for DestructorItem in DestructorList:
+ Image = ExternObject()
+ #
+ # Future enhancement
+ #
+ Image.SetDestructor(DestructorItem.GetCName())
+ self.SetExternList(self.GetExternList() + [Image])
+
+ ## GenModuleHeaderExterns
+ # BootMode/HOB/Event
+ #
+ def _GenSpecialComments(self):
+ SpecialCommentsList = self.Parser.InfSpecialCommentSection.GetSpecialComments()
+ for Key in SpecialCommentsList:
+ if Key == DT.TYPE_HOB_SECTION:
+ HobList = []
+ for Item in SpecialCommentsList[Key]:
+ Hob = HobObject()
+ Hob.SetHobType(Item.GetHobType())
+ Hob.SetUsage(Item.GetUsage())
+ Hob.SetSupArchList(Item.GetSupArchList())
+ if Item.GetHelpString():
+ HelpTextObj = CommonObject.TextObject()
+ HelpTextObj.SetString(Item.GetHelpString())
+ Hob.SetHelpTextList([HelpTextObj])
+ HobList.append(Hob)
+ self.SetHobList(HobList)
+ elif Key == DT.TYPE_EVENT_SECTION:
+ EventList = []
+ for Item in SpecialCommentsList[Key]:
+ Event = EventObject()
+ Event.SetEventType(Item.GetEventType())
+ Event.SetUsage(Item.GetUsage())
+ if Item.GetHelpString():
+ HelpTextObj = CommonObject.TextObject()
+ HelpTextObj.SetString(Item.GetHelpString())
+ Event.SetHelpTextList([HelpTextObj])
+ EventList.append(Event)
+ self.SetEventList(EventList)
+ elif Key == DT.TYPE_BOOTMODE_SECTION:
+ BootModeList = []
+ for Item in SpecialCommentsList[Key]:
+ BootMode = BootModeObject()
+ BootMode.SetSupportedBootModes(Item.GetSupportedBootModes())
+ BootMode.SetUsage(Item.GetUsage())
+ if Item.GetHelpString():
+ HelpTextObj = CommonObject.TextObject()
+ HelpTextObj.SetString(Item.GetHelpString())
+ BootMode.SetHelpTextList([HelpTextObj])
+ BootModeList.append(BootMode)
+ self.SetBootModeList(BootModeList)
+
+ ## GenBuildOptions
+ #
+ # Gen BuildOptions of Inf
+ # [<Family>:]<ToolFlag>=Flag
+ #
+ #
+ def _GenBuildOptions(self):
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_BUILD_OPTIONS)
+ #
+ # Get all BuildOptions
+ #
+ BuildOptionsList = self.Parser.InfBuildOptionSection.GetBuildOptions()
+ if not GlobalData.gIS_BINARY_INF:
+ BuildOptionDict = {}
+
+ for BuildOptionObj in BuildOptionsList:
+ ArchList = BuildOptionObj.GetSupArchList()
+ ArchList = ConvertArchList(ArchList)
+ BuildOptionsContent = BuildOptionObj.GetContent()
+ ArchString = ' '.join(ArchList)
+
+ if not BuildOptionsContent:
+ continue
+
+ BuildOptionDict[ArchString] = BuildOptionsContent
+
+ if not BuildOptionDict:
+ return
+ UserExtension = CommonObject.UserExtensionObject()
+ UserExtension.SetBuildOptionDict(BuildOptionDict)
+ UserExtension.SetIdentifier('BuildOptionModifiers')
+ UserExtension.SetUserID('EDK2')
+ self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
+ else:
+ #
+ # Not process this information, will be processed in GenBinaries()
+ #
+ pass
+
+ ## GenLibraryClasses
+ #
+ # Get LibraryClass of Inf
+ # <LibraryClassKeyWord>|<LibraryInstance>
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenLibraryClasses(self):
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_LIBRARY_CLASSES)
+ if not GlobalData.gIS_BINARY_INF:
+ #
+ # Get all LibraryClasses
+ #
+ LibClassObj = self.Parser.InfLibraryClassSection.LibraryClasses
+ Keys = LibClassObj.keys()
+
+ for Key in Keys:
+ LibraryClassData = LibClassObj[Key]
+ for Item in LibraryClassData:
+ LibraryClass = CommonObject.LibraryClassObject()
+ LibraryClass.SetUsage(DT.USAGE_ITEM_CONSUMES)
+ LibraryClass.SetLibraryClass(Item.GetLibName())
+ LibraryClass.SetRecommendedInstance(None)
+ LibraryClass.SetFeatureFlag(Item.GetFeatureFlagExp())
+ LibraryClass.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
+ LibraryClass.SetSupModuleList(Item.GetSupModuleList())
+ HelpStringObj = Item.GetHelpString()
+
+ if HelpStringObj != None:
+ CommentString = GetHelpStringByRemoveHashKey(HelpStringObj.HeaderComments +
+ HelpStringObj.TailComments)
+ HelpTextHeaderObj = CommonObject.TextObject()
+ HelpTextHeaderObj.SetString(CommentString)
+ LibraryClass.SetHelpTextList([HelpTextHeaderObj])
+
+ self.SetLibraryClassList(self.GetLibraryClassList() + [LibraryClass])
+
+ ## GenPackages
+ #
+ # Gen Packages of Inf
+ #
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenPackages(self, Skip):
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_PACKAGES)
+ #
+ # Get all Packages
+ #
+ PackageObj = self.Parser.InfPackageSection.Packages
+
+ #
+ # Go through each arch
+ #
+ for PackageItemObj in PackageObj:
+ #
+ # Need package information for dependency check usage
+ #
+ PackageDependency = PackageDependencyObject()
+ PackageDependency.SetPackageFilePath(NormPath(PackageItemObj.GetPackageName()))
+ PackageDependency.SetSupArchList(ConvertArchList(PackageItemObj.GetSupArchList()))
+ PackageDependency.SetFeatureFlag(PackageItemObj.GetFeatureFlagExp())
+
+ PkgInfo = GetPkgInfoFromDec(os.path.normpath(os.path.join(self.WorkSpace,
+ NormPath(PackageItemObj.GetPackageName()))))
+ if PkgInfo[1] and PkgInfo[2]:
+ PackageDependency.SetGuid(PkgInfo[1])
+ PackageDependency.SetVersion(PkgInfo[2])
+ elif Skip:
+ continue
+ else:
+ Logger.Error("\nUPT", PARSER_ERROR,
+ ST.ERR_INF_GET_PKG_DEPENDENCY_FAIL % PackageItemObj.GetPackageName(), File=self.FullPath)
+
+ PackageDependencyList = self.GetPackageDependencyList()
+ PackageDependencyList.append(PackageDependency)
+ self.SetPackageDependencyList(PackageDependencyList)
+
+ ## GenPcds
+ #
+ # Gen Pcds of Inf
+ # <TokenSpaceGuidCName>.<PcdCName>[|<Value> [|<FFE>]]
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenPcds(self):
+ if not GlobalData.gIS_BINARY_INF:
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_PCDS)
+
+ #
+ # Get all Pcds
+ #
+ PcdObj = self.Parser.InfPcdSection.Pcds
+ KeysList = PcdObj.keys()
+
+ #
+ # Go through each arch
+ #
+ for (PcdType, PcdKey) in KeysList:
+ PcdData = PcdObj[PcdType, PcdKey]
+ for PcdItemObj in PcdData:
+ CommentList = PcdItemObj.GetHelpStringList()
+ if CommentList:
+ for CommentItem in CommentList:
+ Pcd = CommonObject.PcdObject()
+ Pcd.SetCName(PcdItemObj.GetCName())
+ Pcd.SetTokenSpaceGuidCName(PcdItemObj.GetTokenSpaceGuidCName())
+ Pcd.SetDefaultValue(PcdItemObj.GetDefaultValue())
+ Pcd.SetItemType(PcdType)
+ Pcd.SetValidUsage(CommentItem.GetUsageItem())
+ Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp())
+ Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList()))
+ HelpTextObj = CommonObject.TextObject()
+ HelpTextObj.SetString(CommentItem.GetHelpStringItem())
+ Pcd.SetHelpTextList([HelpTextObj])
+ PcdList = self.GetPcdList()
+ PcdList.append(Pcd)
+ self.SetPcdList(PcdList)
+
+ ## GenSources
+ #
+ # Gen Sources of Inf
+ # <Filename>[|<Family>[|<TagName>[|<ToolCode>[|<PcdFeatureFlag>]]]]
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenSources(self):
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_SOURCES)
+
+ #
+ # Get all SourceFiles
+ #
+ SourceObj = self.Parser.InfSourcesSection.Sources
+ DataList = SourceObj.keys()
+ #
+ # Go through each arch
+ #
+ SourceList = []
+ for Key in DataList:
+ SourceData = SourceObj[Key]
+ for Item in SourceData:
+ SourceFile = Item.GetSourceFileName()
+ Family = Item.GetFamily()
+ FeatureFlag = Item.GetFeatureFlagExp()
+ SupArchList = ConvertArchList(Item.GetSupArchList())
+ SupArchList.sort()
+ Source = SourceFileObject()
+ Source.SetSourceFile(SourceFile)
+ Source.SetFamily(Family)
+ Source.SetFeatureFlag(FeatureFlag)
+ Source.SetSupArchList(SupArchList)
+ SourceList.append(Source)
+
+ self.SetSourceFileList(self.GetSourceFileList() + SourceList)
+
+
+ ## GenUserExtensions
+ #
+ # Gen UserExtensions of Inf
+ #
+ def _GenUserExtensions(self):
+ #
+ # UserExtensions
+ #
+ UserExtensionObj = self.Parser.InfUserExtensionSection.UserExtension
+ Keys = UserExtensionObj.keys()
+
+ for Key in Keys:
+ UserExtensionData = UserExtensionObj[Key]
+ for UserExtensionDataObj in UserExtensionData:
+ UserExtension = CommonObject.UserExtensionObject()
+ UserId = UserExtensionDataObj.GetUserId()
+ if UserId.startswith('"') and UserId.endswith('"'):
+ UserId = UserId[1:-1]
+ UserExtension.SetUserID(UserId)
+ Identifier = UserExtensionDataObj.GetIdString()
+ if Identifier.startswith('"') and Identifier.endswith('"'):
+ Identifier = Identifier[1:-1]
+ UserExtension.SetIdentifier(Identifier)
+ UserExtension.SetStatement(UserExtensionDataObj.GetContent())
+ UserExtension.SetSupArchList(ConvertArchList(UserExtensionDataObj.GetSupArchList()))
+ self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
+
+ def _GenDepexesList(self, SmmDepexList, DxeDepexList, PeiDepexList):
+ if SmmDepexList:
+ self.SetSmmDepex(SmmDepexList)
+ if DxeDepexList:
+ self.SetDxeDepex(DxeDepexList)
+ if PeiDepexList:
+ self.SetPeiDepex(PeiDepexList)
+
+ ## GenDepexes
+ #
+ # Gen Depex of Inf
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenDepexes(self):
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_DEPEX)
+
+ PEI_LIST = [DT.SUP_MODULE_PEIM]
+ SMM_LIST = [DT.SUP_MODULE_DXE_SMM_DRIVER]
+ DXE_LIST = [DT.SUP_MODULE_DXE_DRIVER, DT.SUP_MODULE_DXE_SAL_DRIVER,
+ DT.SUP_MODULE_DXE_RUNTIME_DRIVER]
+
+ IsLibraryClass = self.GetIsLibrary()
+ #
+ # Get all Depexes
+ #
+ DepexData = self.Parser.InfDepexSection.GetDepex()
+ SmmDepexList = []
+ DxeDepexList = []
+ PeiDepexList = []
+ for Depex in DepexData:
+ ModuleType = Depex.GetModuleType()
+ ModuleTypeList = []
+ if IsLibraryClass:
+ if not self.GetIsLibraryModList():
+ Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_LIBRARY_CLASS,
+ self.GetFullPath(), RaiseError=True)
+ if ModuleType and ModuleType not in self.GetIsLibraryModList():
+ Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED,
+ self.GetFullPath(), RaiseError=True)
+ if ModuleType:
+ ModuleTypeList = [ModuleType]
+ else:
+ for ModuleTypeInList in self.GetIsLibraryModList():
+ if ModuleTypeInList in DT.VALID_DEPEX_MODULE_TYPE_LIST:
+ ModuleTypeList.append(ModuleTypeInList)
+ if not ModuleTypeList:
+ Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED,
+ self.GetFullPath(), RaiseError=True)
+ else:
+ if not ModuleType:
+ ModuleType = self.ModuleType
+ if ModuleType not in DT.VALID_DEPEX_MODULE_TYPE_LIST:
+ Logger.Error("\nMkPkg", PARSER_ERROR,
+ ST.ERR_INF_PARSER_DEPEX_SECTION_MODULE_TYPE_ERROR % (ModuleType),
+ self.GetFullPath(), RaiseError=True)
+ if ModuleType != self.ModuleType:
+ Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_NOT_DETERMINED,
+ self.GetFullPath(), RaiseError=True)
+ ModuleTypeList = [ModuleType]
+ for ModuleType in ModuleTypeList:
+ DepexIns = DepexObject()
+ DepexIns.SetDepex(Depex.GetDepexContent())
+ if IsLibraryClass:
+ DepexIns.SetModuleType(ModuleType)
+ else:
+ if Depex.GetModuleType():
+ DepexIns.SetModuleType(Depex.GetModuleType())
+ DepexIns.SetSupArchList(ConvertArchList([Depex.GetSupArch()]))
+ DepexIns.SetFeatureFlag(Depex.GetFeatureFlagExp())
+ if Depex.HelpString:
+ HelpIns = CommonObject.TextObject()
+ HelpIns.SetString(GetHelpStringByRemoveHashKey(Depex.HelpString))
+ DepexIns.SetHelpText(HelpIns)
+
+ if ModuleType in SMM_LIST:
+ SmmDepexList.append(DepexIns)
+ if ModuleType in DXE_LIST:
+ DxeDepexList.append(DepexIns)
+ if ModuleType in PEI_LIST:
+ PeiDepexList.append(DepexIns)
+ if ModuleType == DT.SUP_MODULE_UEFI_DRIVER:
+ if IsLibraryClass:
+ DxeDepexList.append(DepexIns)
+ else:
+ Logger.Error("\nMkPkg", PARSER_ERROR, ST.ERR_INF_PARSER_DEPEX_SECTION_INVALID_FOR_DRIVER,
+ self.GetFullPath(), RaiseError=True)
+
+ #End of for ModuleType in ModuleTypeList
+ self._GenDepexesList(SmmDepexList, DxeDepexList, PeiDepexList)
+ #End of for Depex in DepexData
+
+ ## GenBinaries
+ #
+ # Gen Binary of Inf, must be called after Pcd/Library is generated
+ # <FileType>|<Filename>|<Target>[|<TokenSpaceGuidCName>.<PcdCName>]
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenBinaries(self):
+ Logger.Debug(2, "Generate %s ..." % DT.TAB_BINARIES)
+ BinariesDict = {}
+
+ #
+ # Get all Binary data
+ #
+ BinaryObj = self.Parser.InfBinariesSection.GetBinary()
+
+ BinaryData = BinaryObj.keys()
+ BinaryData.sort()
+
+ #
+ # If the INF file does not contain a [Sources] section, and the INF file does contain a [Binaries] section,
+ # then the ModuleSurfaceArea.BinaryModule attribute must be set to true. Otherwise, do not use the attribute
+ #
+ if BinaryObj and not self.Parser.InfSourcesSection.GetSources():
+ self.BinaryModule = True
+ else:
+ self.BinaryModule = False
+
+ BinaryFileObjectList = []
+ AsBuildLibraryClassList = []
+ AsBuildBuildOptionList = []
+ AsBuildIns = AsBuiltObject()
+ #
+ # Library AsBuild Info
+ #
+ for LibItem in self.Parser.InfLibraryClassSection.GetLibraryClasses():
+ AsBuildLibIns = AsBuildLibraryClassObject()
+ AsBuildLibIns.SetLibGuid(LibItem.GetFileGuid())
+ AsBuildLibIns.SetLibVersion(LibItem.GetVersion())
+ AsBuildLibraryClassList.append(AsBuildLibIns)
+ AsBuildIns.SetLibraryInstancesList(AsBuildLibraryClassList)
+
+ #
+ # BuildOption AsBuild Info
+ #
+ for BuildOptionItem in self.Parser.InfBuildOptionSection.GetBuildOptions():
+ AsBuildBuildOptionList += BuildOptionItem.GetAsBuildList()
+ AsBuildIns.SetBuildFlagsList(AsBuildBuildOptionList)
+
+ #
+ # PatchPcd and PcdEx
+ #
+ AsBuildIns = self._GenAsBuiltPcds(self.Parser.InfPcdSection.GetPcds(), AsBuildIns)
+
+ BinariesDict, AsBuildIns, BinaryFileObjectList = GenBinaryData(BinaryData, BinaryObj,
+ BinariesDict,
+ AsBuildIns,
+ BinaryFileObjectList,
+ self.GetSupArchList(),
+ self.BinaryModule)
+
+ BinariesDict2 = {}
+ for Key in BinariesDict:
+ ValueList = BinariesDict[Key]
+ if len(ValueList) > 1:
+ BinariesDict2[Key] = ValueList
+ else:
+ #
+ # if there is no TagName, ToolCode, HelpStr,
+ # then do not need to put them into userextension
+ #
+ (Target, Family, TagName, HelpStr) = ValueList[0]
+ if not (Target or Family or TagName or HelpStr):
+ continue
+ else:
+ BinariesDict2[Key] = ValueList
+
+ self.SetBinaryFileList(self.GetBinaryFileList() + BinaryFileObjectList)
+
+ if BinariesDict2:
+ UserExtension = CommonObject.UserExtensionObject()
+ UserExtension.SetBinariesDict(BinariesDict2)
+ UserExtension.SetIdentifier('BinaryFileModifiers')
+ UserExtension.SetUserID('EDK2')
+ self.SetUserExtensionList(self.GetUserExtensionList() + [UserExtension])
+
+ ## GenAsBuiltPcds
+ #
+ #
+ def _GenAsBuiltPcds(self, PcdList, AsBuildIns):
+ AsBuildPatchPcdList = []
+ AsBuildPcdExList = []
+ #
+ # Pcd AsBuild Info
+ #
+ for PcdItem in PcdList:
+ if PcdItem[0].upper() == DT.TAB_INF_PATCH_PCD.upper():
+ PcdItemObj = PcdItem[1]
+ Pcd = CommonObject.PcdObject()
+ Pcd.SetCName(PcdItemObj.GetCName())
+ Pcd.SetTokenSpaceGuidCName(PcdItemObj.GetTokenSpaceGuidCName())
+ if PcdItemObj.GetTokenSpaceGuidValue() == '' and self.BinaryModule:
+ Logger.Error("\nMkPkg",
+ PARSER_ERROR,
+ ST.ERR_ASBUILD_PCD_TOKENSPACE_GUID_VALUE_MISS % \
+ (PcdItemObj.GetTokenSpaceGuidCName()),
+ self.GetFullPath(), RaiseError=True)
+ else:
+ Pcd.SetTokenSpaceGuidValue(PcdItemObj.GetTokenSpaceGuidValue())
+ if (PcdItemObj.GetToken() == '' or PcdItemObj.GetDatumType() == '') and self.BinaryModule:
+ Logger.Error("\nMkPkg",
+ PARSER_ERROR,
+ ST.ERR_ASBUILD_PCD_DECLARITION_MISS % \
+ (PcdItemObj.GetTokenSpaceGuidCName() + '.' + PcdItemObj.GetCName()),
+ self.GetFullPath(), RaiseError=True)
+ Pcd.SetToken(PcdItemObj.GetToken())
+ Pcd.SetDatumType(PcdItemObj.GetDatumType())
+ Pcd.SetMaxDatumSize(PcdItemObj.GetMaxDatumSize())
+ Pcd.SetDefaultValue(PcdItemObj.GetDefaultValue())
+ Pcd.SetOffset(PcdItemObj.GetOffset())
+ Pcd.SetItemType(PcdItem[0])
+ Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp())
+ Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList()))
+ HelpTextObj = CommonObject.TextObject()
+ HelpTextObj.SetString(PcdItemObj.GetHelpStringList())
+ Pcd.SetHelpTextList([HelpTextObj])
+ AsBuildPatchPcdList.append(Pcd)
+ else:
+ PcdItemObj = PcdItem[1]
+ Pcd = CommonObject.PcdObject()
+ Pcd.SetTokenSpaceGuidValue(PcdItemObj.GetTokenSpaceGuidValue())
+ Pcd.SetToken(PcdItemObj.GetToken())
+ Pcd.SetDatumType(PcdItemObj.GetDatumType())
+ Pcd.SetMaxDatumSize(PcdItemObj.GetMaxDatumSize())
+ Pcd.SetDefaultValue(PcdItemObj.GetDefaultValue())
+ Pcd.SetItemType(PcdItem[0])
+ Pcd.SetFeatureFlag(PcdItemObj.GetFeatureFlagExp())
+ Pcd.SetSupArchList(ConvertArchList(PcdItemObj.GetSupportArchList()))
+ HelpTextObj = CommonObject.TextObject()
+ HelpTextObj.SetString(PcdItemObj.GetHelpStringList())
+ Pcd.SetHelpTextList([HelpTextObj])
+ AsBuildPcdExList.append(Pcd)
+ AsBuildIns.SetPatchPcdList(AsBuildPatchPcdList)
+ AsBuildIns.SetPcdExList(AsBuildPcdExList)
+
+ return AsBuildIns
+
+ ## GenGuidProtocolPpis
+ #
+ # Gen Guids/Protocol/Ppis of INF
+ # <CName>=<GuidValue>
+ #
+ def _GenGuidProtocolPpis(self, Type):
+ Logger.Debug(2, "Generate %s ..." % Type)
+ #
+ # Get all Guid/Protocol/Ppis data
+ #
+ GuidObj = self.Parser.InfGuidSection.GetGuid()
+ ProtocolObj = self.Parser.InfProtocolSection.GetProtocol()
+ PpisObj = self.Parser.InfPpiSection.GetPpi()
+
+ GuidProtocolPpiList = []
+
+ if Type == DT.TAB_GUIDS:
+ GuidData = GuidObj.keys()
+ for Item in GuidData:
+ CommentList = Item.GetCommentList()
+ #
+ # Depend on CommentList content
+ # generate muti-guid-obj
+ #
+ if CommentList:
+ for GuidComentItem in CommentList:
+ ListObject = CommonObject.GuidObject()
+ ListObject.SetGuidTypeList([GuidComentItem.GetGuidTypeItem()])
+ ListObject.SetVariableName(GuidComentItem.GetVariableNameItem())
+ ListObject.SetUsage(GuidComentItem.GetUsageItem())
+ ListObject.SetName(Item.GetName())
+ ListObject.SetCName(Item.GetName())
+ ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
+ ListObject.SetFeatureFlag(Item.GetFeatureFlagExp())
+ HelpString = GuidComentItem.GetHelpStringItem()
+ HelpTxtTailObj = CommonObject.TextObject()
+ HelpTxtTailObj.SetString(HelpString)
+
+ ListObject.SetHelpTextList([HelpTxtTailObj])
+
+ GuidProtocolPpiList.append(ListObject)
+ elif Type == DT.TAB_PROTOCOLS:
+ ProtocolData = ProtocolObj.keys()
+ for Item in ProtocolData:
+ CommentList = Item.GetCommentList()
+ for CommentItem in CommentList:
+ ListObject = CommonObject.ProtocolObject()
+ ListObject.SetCName(Item.GetName())
+ ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
+ ListObject.SetFeatureFlag(Item.GetFeatureFlagExp())
+ ListObject.SetNotify(CommentItem.GetNotify())
+ ListObject.SetUsage(CommentItem.GetUsageItem())
+ HelpTxtObj = CommonObject.TextObject()
+ HelpString = CommentItem.GetHelpStringItem()
+ HelpTxtObj.SetString(HelpString)
+ ListObject.SetHelpTextList([HelpTxtObj])
+ GuidProtocolPpiList.append(ListObject)
+ elif Type == DT.TAB_PPIS:
+ PpiData = PpisObj.keys()
+ for Item in PpiData:
+ CommentList = Item.GetCommentList()
+ for CommentItem in CommentList:
+ ListObject = CommonObject.PpiObject()
+ ListObject.SetCName(Item.GetName())
+ ListObject.SetSupArchList(ConvertArchList(Item.GetSupArchList()))
+ ListObject.SetFeatureFlag(Item.GetFeatureFlagExp())
+ ListObject.SetNotify(CommentItem.GetNotify())
+ ListObject.SetUsage(CommentItem.GetUsage())
+ HelpTextObj = CommonObject.TextObject()
+ HelpString = CommentItem.GetHelpStringItem()
+ HelpTextObj.SetString(HelpString)
+ ListObject.SetHelpTextList([HelpTextObj])
+ GuidProtocolPpiList.append(ListObject)
+
+ if Type == DT.TAB_GUIDS:
+ self.SetGuidList(self.GetGuidList() + GuidProtocolPpiList)
+ elif Type == DT.TAB_PROTOCOLS:
+ self.SetProtocolList(self.GetProtocolList() + GuidProtocolPpiList)
+ elif Type == DT.TAB_PPIS:
+ self.SetPpiList(self.GetPpiList() + GuidProtocolPpiList)
+
+ ## GenMiscFiles
+ #
+ # Gen MiscellaneousFiles of Inf
+ #
+ # @param ContainerFile: The Inf file full path
+ #
+ def _GenMiscFiles(self, ContainerFile, Skip):
+ pass
+
diff --git a/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py
new file mode 100644
index 0000000000..7369d64672
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/PomAdapter/InfPomAlignmentMisc.py
@@ -0,0 +1,221 @@
+## @file InfPomAlignmentMisc.py
+# This file contained the routines for InfPomAlignment
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+InfPomAlignmentMisc
+'''
+
+##
+# Import modules
+#
+import Logger.Log as Logger
+from Library import DataType as DT
+from Library.Misc import ConvertArchList
+from Object.POM.ModuleObject import BinaryFileObject
+from Object.POM import CommonObject
+
+## GenModuleHeaderUserExt
+#
+#
+def GenModuleHeaderUserExt(DefineObj, ArchString):
+ DefinesDictNew = {}
+ EdkReleaseVersion = DefineObj.GetEdkReleaseVersion()
+ Shadow = DefineObj.GetShadow()
+ DpxSource = DefineObj.GetDpxSource()
+ PciVendorId = DefineObj.GetPciVendorId()
+ PciDeviceId = DefineObj.GetPciDeviceId()
+ PciClassCode = DefineObj.GetPciClassCode()
+ PciRevision = DefineObj.GetPciRevision()
+ PciCompress = DefineObj.GetPciCompress()
+ CustomMakefile = DefineObj.GetCustomMakefile()
+ UefiHiiResourceSection = DefineObj.GetUefiHiiResourceSection()
+
+ if EdkReleaseVersion != None:
+ Name = DT.TAB_INF_DEFINES_EDK_RELEASE_VERSION
+ Value = EdkReleaseVersion.GetValue()
+ Statement = _GenInfDefineStateMent(EdkReleaseVersion.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ EdkReleaseVersion.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if Shadow != None:
+ Name = DT.TAB_INF_DEFINES_SHADOW
+ Value = Shadow.GetValue()
+ Statement = _GenInfDefineStateMent(Shadow.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ Shadow.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if DpxSource != None:
+ Name = DT.TAB_INF_DEFINES_DPX_SOURCE
+ for DpxSourceItem in DpxSource:
+ Value = DpxSourceItem[0]
+ Statement = _GenInfDefineStateMent(DpxSourceItem[1].GetHeaderComments(),
+ Name,
+ Value,
+ DpxSourceItem[1].GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if PciVendorId != None:
+ Name = DT.TAB_INF_DEFINES_PCI_VENDOR_ID
+ Value = PciVendorId.GetValue()
+ Statement = _GenInfDefineStateMent(PciVendorId.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ PciVendorId.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if PciDeviceId != None:
+ Name = DT.TAB_INF_DEFINES_PCI_DEVICE_ID
+ Value = PciDeviceId.GetValue()
+ Statement = _GenInfDefineStateMent(PciDeviceId.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ PciDeviceId.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if PciClassCode != None:
+ Name = DT.TAB_INF_DEFINES_PCI_CLASS_CODE
+ Value = PciClassCode.GetValue()
+ Statement = _GenInfDefineStateMent(PciClassCode.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ PciClassCode.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if PciRevision != None:
+ Name = DT.TAB_INF_DEFINES_PCI_REVISION
+ Value = PciRevision.GetValue()
+ Statement = _GenInfDefineStateMent(PciRevision.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ PciRevision.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if PciCompress != None:
+ Name = DT.TAB_INF_DEFINES_PCI_COMPRESS
+ Value = PciCompress.GetValue()
+ Statement = _GenInfDefineStateMent(PciCompress.Comments.GetHeaderComments(),
+ Name,
+ Value,
+ PciCompress.Comments.GetTailComments())
+ DefinesDictNew[Statement] = ArchString
+
+ if len(CustomMakefile) >= 1:
+ for CustomMakefileItem in CustomMakefile:
+ Name = DT.TAB_INF_DEFINES_CUSTOM_MAKEFILE
+ #
+ # Not with Feature Flag Expression
+ #
+ if len(CustomMakefileItem) == 3:
+ if CustomMakefileItem[0] != '':
+ Value = CustomMakefileItem[0] + ' | ' + CustomMakefileItem[1]
+ else:
+ Value = CustomMakefileItem[1]
+
+ Comments = CustomMakefileItem[2]
+ Statement = _GenInfDefineStateMent(Comments.GetHeaderComments(),
+ Name,
+ Value,
+ Comments.GetTailComments())
+
+ DefinesDictNew[Statement] = ArchString
+
+ if UefiHiiResourceSection != None:
+ Name = DT.TAB_INF_DEFINES_UEFI_HII_RESOURCE_SECTION
+ Value = UefiHiiResourceSection.GetValue()
+ HeaderComment = UefiHiiResourceSection.Comments.GetHeaderComments()
+ TailComment = UefiHiiResourceSection.Comments.GetTailComments()
+ Statement = _GenInfDefineStateMent(HeaderComment,
+ Name,
+ Value,
+ TailComment)
+ DefinesDictNew[Statement] = ""
+
+ return DefinesDictNew
+
+
+## Generate the define statement that will be put into userextension
+# Not support comments.
+#
+# @param HeaderComment: the original header comment (# not remvoed)
+# @param Name: the definition keyword, should not be empty or none
+# @param Value: the definition keyword value
+# @param TailComment: the original Tail comment (# not remvoed)
+#
+# @return: the regenerated define statement
+#
+def _GenInfDefineStateMent(HeaderComment, Name, Value, TailComment):
+ Logger.Debug(5, HeaderComment + TailComment)
+ Statement = '%s = %s' % (Name, Value)
+
+ return Statement
+
+## GenBinaryData
+#
+#
+def GenBinaryData(BinaryData, BinaryObj, BinariesDict, AsBuildIns, BinaryFileObjectList, SupArchList, BinaryModule):
+ if BinaryModule:
+ pass
+ OriSupArchList = SupArchList
+ for Item in BinaryData:
+ ItemObj = BinaryObj[Item][0][0]
+ if ItemObj.GetType() not in DT.BINARY_FILE_TYPE_UI_LIST + DT.BINARY_FILE_TYPE_VER_LIST:
+ TagName = ItemObj.GetTagName()
+ Family = ItemObj.GetFamily()
+ else:
+ TagName = ''
+ Family = ''
+ FFE = ItemObj.GetFeatureFlagExp()
+
+ #
+ # If have architecturie specified, then use the specified architecturie;
+ # If the section tag does not have an architecture modifier or the modifier is "common" (case in-sensitive),
+ # and the VALID_ARCHITECTURES comment exists, the list from the VALID_ARCHITECTURES comment
+ # can be used for the attribute.
+ # If both not have VALID_ARCHITECTURE comment and no architecturie specified, then keep it empty.
+ #
+ SupArchList = ConvertArchList(ItemObj.GetSupArchList())
+ SupArchList.sort()
+ if len(SupArchList) == 1 and SupArchList[0] == 'COMMON':
+ if not (len(OriSupArchList) == 1 or OriSupArchList[0] == 'COMMON'):
+ SupArchList = OriSupArchList
+ else:
+ SupArchList = ['COMMON']
+
+ FileNameObj = CommonObject.FileNameObject()
+ FileNameObj.SetFileType(ItemObj.GetType())
+ FileNameObj.SetFilename(ItemObj.GetFileName())
+ FileNameObj.SetFeatureFlag(FFE)
+ FileNameObj.SetSupArchList(SupArchList)
+ FileNameList = [FileNameObj]
+
+ BinaryFile = BinaryFileObject()
+ BinaryFile.SetFileNameList(FileNameList)
+ BinaryFile.SetAsBuiltList(AsBuildIns)
+ BinaryFileObjectList.append(BinaryFile)
+
+ SupArchStr = ' '.join(SupArchList)
+ Key = (ItemObj.GetFileName(), ItemObj.GetType(), FFE, SupArchStr)
+ ValueItem = (ItemObj.GetTarget(), Family, TagName, '')
+ if Key in BinariesDict:
+ ValueList = BinariesDict[Key]
+ ValueList.append(ValueItem)
+ BinariesDict[Key] = ValueList
+ else:
+ BinariesDict[Key] = [ValueItem]
+
+ return BinariesDict, AsBuildIns, BinaryFileObjectList
diff --git a/BaseTools/Source/Python/UPT/PomAdapter/__init__.py b/BaseTools/Source/Python/UPT/PomAdapter/__init__.py
new file mode 100644
index 0000000000..e477b97baa
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/PomAdapter/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Parser' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+PomAdapter
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/RmPkg.py b/BaseTools/Source/Python/UPT/RmPkg.py
new file mode 100644
index 0000000000..3817812168
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/RmPkg.py
@@ -0,0 +1,246 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+RmPkg
+'''
+
+##
+# Import Modules
+#
+import os.path
+from stat import S_IWUSR
+from traceback import format_exc
+from platform import python_version
+import md5
+from sys import stdin
+from sys import platform
+
+from Core.DependencyRules import DependencyRules
+from Library.Misc import CheckEnvVariable
+from Library import GlobalData
+from Logger import StringTable as ST
+import Logger.Log as Logger
+from Logger.ToolError import OPTION_MISSING
+from Logger.ToolError import UNKNOWN_ERROR
+from Logger.ToolError import ABORT_ERROR
+from Logger.ToolError import CODE_ERROR
+from Logger.ToolError import FatalError
+
+
+## CheckDpDepex
+#
+# Check if the Depex is satisfied
+# @param Dep: Dep
+# @param Guid: Guid of Dp
+# @param Version: Version of Dp
+# @param WorkspaceDir: Workspace Dir
+#
+def CheckDpDepex(Dep, Guid, Version, WorkspaceDir):
+ (Removable, DependModuleList) = Dep.CheckDpDepexForRemove(Guid, Version)
+ if not Removable:
+ Logger.Info(ST.MSG_CONFIRM_REMOVE)
+ Logger.Info(ST.MSG_USER_DELETE_OP)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
+ return 1
+ else:
+ #
+ # report list of modules that are not valid due to force
+ # remove,
+ # also generate a log file for reference
+ #
+ Logger.Info(ST.MSG_INVALID_MODULE_INTRODUCED)
+ LogFilePath = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gINVALID_MODULE_FILE))
+ Logger.Info(ST.MSG_CHECK_LOG_FILE % LogFilePath)
+ try:
+ LogFile = open(LogFilePath, 'w')
+ try:
+ for ModulePath in DependModuleList:
+ LogFile.write("%s\n"%ModulePath)
+ Logger.Info(ModulePath)
+ except IOError:
+ Logger.Warn("\nRmPkg", ST.ERR_FILE_WRITE_FAILURE,
+ File=LogFilePath)
+ except IOError:
+ Logger.Warn("\nRmPkg", ST.ERR_FILE_OPEN_FAILURE,
+ File=LogFilePath)
+ finally:
+ LogFile.close()
+
+## Remove Path
+#
+# removing readonly file on windows will get "Access is denied"
+# error, so before removing, change the mode to be writeable
+#
+# @param Path: The Path to be removed
+#
+def RemovePath(Path):
+ Logger.Info(ST.MSG_REMOVE_FILE % Path)
+ if not os.access(Path, os.W_OK):
+ os.chmod(Path, S_IWUSR)
+ os.remove(Path)
+ try:
+ os.removedirs(os.path.split(Path)[0])
+ except OSError:
+ pass
+## GetCurrentFileList
+#
+# @param DataBase: DataBase of UPT
+# @param Guid: Guid of Dp
+# @param Version: Version of Dp
+# @param WorkspaceDir: Workspace Dir
+#
+def GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir):
+ NewFileList = []
+ for Dir in DataBase.GetDpInstallDirList(Guid, Version):
+ RootDir = os.path.normpath(os.path.join(WorkspaceDir, Dir))
+ for Root, Dirs, Files in os.walk(RootDir):
+ Logger.Debug(0, Dirs)
+ for File in Files:
+ FilePath = os.path.join(Root, File)
+ if FilePath not in NewFileList:
+ NewFileList.append(FilePath)
+ return NewFileList
+
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+# @param Options: command option
+#
+def Main(Options = None):
+
+ try:
+ DataBase = GlobalData.gDB
+ if not Options.DistributionFile:
+ Logger.Error("RmPkg",
+ OPTION_MISSING,
+ ExtraData=ST.ERR_SPECIFY_PACKAGE)
+ CheckEnvVariable()
+ WorkspaceDir = GlobalData.gWORKSPACE
+ #
+ # Prepare check dependency
+ #
+ Dep = DependencyRules(DataBase)
+
+ if Options.DistributionFile:
+ (Guid, Version, NewDpFileName) = \
+ DataBase.GetDpByName(os.path.split(Options.DistributionFile)[1])
+ if not Guid:
+ Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_PACKAGE_NOT_INSTALLED % Options.DistributionFile)
+ else:
+ Guid = Options.PackageGuid
+ Version = Options.PackageVersion
+ #
+ # Check Dp existing
+ #
+ if not Dep.CheckDpExists(Guid, Version):
+ Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_DISTRIBUTION_NOT_INSTALLED)
+ #
+ # Check for Distribution files existence in /conf/upt, if not exist,
+ # Warn user and go on.
+ #
+ StoredDistFile = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR, NewDpFileName))
+ if not os.path.isfile(StoredDistFile):
+ Logger.Warn("RmPkg", ST.WRN_DIST_NOT_FOUND%StoredDistFile)
+ StoredDistFile = None
+
+ #
+ # Check Dp depex
+ #
+ CheckDpDepex(Dep, Guid, Version, WorkspaceDir)
+
+ #
+ # Get Current File List
+ #
+ NewFileList = GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir)
+
+ #
+ # Remove all files
+ #
+ MissingFileList = []
+ for (Path, Md5Sum) in DataBase.GetDpFileList(Guid, Version):
+ if os.path.isfile(Path):
+ if Path in NewFileList:
+ NewFileList.remove(Path)
+ if not Options.Yes:
+ #
+ # check whether modified by users
+ #
+ Md5Sigature = md5.new(open(str(Path), 'rb').read())
+ if Md5Sum != Md5Sigature.hexdigest():
+ Logger.Info(ST.MSG_CONFIRM_REMOVE2 % Path)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ continue
+ RemovePath(Path)
+ else:
+ MissingFileList.append(Path)
+
+ for Path in NewFileList:
+ if os.path.isfile(Path):
+ if (not Options.Yes) and (not os.path.split(Path)[1].startswith('.')):
+ Logger.Info(ST.MSG_CONFIRM_REMOVE3 % Path)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ continue
+ RemovePath(Path)
+
+ #
+ # Remove distribution files in /Conf/.upt
+ #
+ if StoredDistFile is not None:
+ os.remove(StoredDistFile)
+
+ #
+ # update database
+ #
+ Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)
+ DataBase.RemoveDpObj(Guid, Version)
+ Logger.Quiet(ST.MSG_FINISH)
+
+ ReturnCode = 0
+
+ except FatalError, XExcept:
+ ReturnCode = XExcept.args[0]
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
+ format_exc())
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
+ format_exc())
+ except:
+ Logger.Error(
+ "\nRmPkg",
+ CODE_ERROR,
+ ST.ERR_UNKNOWN_FATAL_REMOVING_ERR,
+ ExtraData=ST.MSG_SEARCH_FOR_HELP,
+ RaiseError=False
+ )
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
+ format_exc())
+ ReturnCode = CODE_ERROR
+ return ReturnCode
+
+
diff --git a/BaseTools/Source/Python/UPT/UPT.py b/BaseTools/Source/Python/UPT/UPT.py
new file mode 100644
index 0000000000..bf936e9a26
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/UPT.py
@@ -0,0 +1,238 @@
+## @file
+#
+# This file is the main entry for UPT
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+UPT
+'''
+
+## import modules
+#
+import sys
+import os.path
+from os import environ
+from sys import platform
+from optparse import OptionParser
+from traceback import format_exc
+from platform import python_version
+
+from Logger import StringTable as ST
+import Logger.Log as Logger
+from Logger.StringTable import MSG_VERSION
+from Logger.StringTable import MSG_DESCRIPTION
+from Logger.StringTable import MSG_USAGE
+from Logger.ToolError import FILE_NOT_FOUND
+from Logger.ToolError import OPTION_MISSING
+from Logger.ToolError import FILE_TYPE_MISMATCH
+from Logger.ToolError import OPTION_CONFLICT
+from Logger.ToolError import FatalError
+import MkPkg
+import InstallPkg
+import RmPkg
+from Library.Misc import CheckEnvVariable
+from Library import GlobalData
+from Core.IpiDb import IpiDatabase
+
+##
+# Version and Copyright
+#
+#VersionNumber = "1.0"
+#__version__ = "Revision " + VersionNumber
+#__copyright__ = "Copyright (c) 2011 Intel Corporation All Rights Reserved."
+
+## CheckConflictOption
+#
+# CheckConflictOption
+#
+def CheckConflictOption(Opt):
+ if (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove):
+ Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION)
+ elif Opt.PackFileToCreate and Opt.PackFileToInstall:
+ Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE)
+ elif Opt.PackFileToInstall and Opt.PackFileToRemove:
+ Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_R_EXCLUSIVE)
+ elif Opt.PackFileToCreate and Opt.PackFileToRemove:
+ Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)
+
+## SetLogLevel
+#
+def SetLogLevel(Opt):
+ if Opt.opt_verbose:
+ Logger.SetLevel(Logger.VERBOSE)
+ elif Opt.opt_quiet:
+ Logger.SetLevel(Logger.QUIET + 1)
+ elif Opt.debug_level != None:
+ if Opt.debug_level < 0 or Opt.debug_level > 9:
+ Logger.Warn("UPT", ST.ERR_DEBUG_LEVEL)
+ Logger.SetLevel(Logger.INFO)
+ else:
+ Logger.SetLevel(Opt.debug_level + 1)
+ elif Opt.opt_slient:
+ Logger.SetLevel(Logger.SILENT)
+ else:
+ Logger.SetLevel(Logger.INFO)
+
+## Main
+#
+# Main
+#
+def Main():
+ Logger.Initialize()
+
+ Parser = OptionParser(version=MSG_VERSION, description=MSG_DESCRIPTION,
+ prog="UPT.exe", usage=MSG_USAGE)
+
+ Parser.add_option("-d", "--debug", action="store", type="int", dest="debug_level", help=ST.HLP_PRINT_DEBUG_INFO)
+
+ Parser.add_option("-v", "--verbose", action="store_true", dest="opt_verbose",
+ help=ST.HLP_PRINT_INFORMATIONAL_STATEMENT)
+
+ Parser.add_option("-s", "--silent", action="store_true", dest="opt_slient", help=ST.HLP_RETURN_NO_DISPLAY)
+
+ Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", help=ST.HLP_RETURN_AND_DISPLAY)
+
+ Parser.add_option("-i", "--install", action="store", type="string", dest="Install_Distribution_Package_File",
+ help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL)
+
+ Parser.add_option("-c", "--create", action="store", type="string", dest="Create_Distribution_Package_File",
+ help=ST.HLP_SPECIFY_PACKAGE_NAME_CREATE)
+
+ Parser.add_option("-r", "--remove", action="store", type="string", dest="Remove_Distribution_Package_File",
+ help=ST.HLP_SPECIFY_PACKAGE_NAME_REMOVE)
+
+ Parser.add_option("-t", "--template", action="store", type="string", dest="Package_Information_Data_File",
+ help=ST.HLP_SPECIFY_TEMPLATE_NAME_CREATE)
+
+ Parser.add_option("-p", "--dec-filename", action="append", type="string", dest="EDK2_DEC_Filename",
+ help=ST.HLP_SPECIFY_DEC_NAME_CREATE)
+
+ Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename",
+ help=ST.HLP_SPECIFY_INF_NAME_CREATE)
+
+ Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT)
+
+ Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT)
+
+ Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK)
+
+ Opt = Parser.parse_args()[0]
+
+ Var2Var = [
+ ("PackageInformationDataFile", Opt.Package_Information_Data_File),
+ ("PackFileToInstall", Opt.Install_Distribution_Package_File),
+ ("PackFileToCreate", Opt.Create_Distribution_Package_File),
+ ("PackFileToRemove", Opt.Remove_Distribution_Package_File),
+ ("PackageFileList", Opt.EDK2_DEC_Filename),
+ ("ModuleFileList", Opt.EDK2_INF_Filename)
+ ]
+ for Var in Var2Var:
+ setattr(Opt, Var[0], Var[1])
+
+ try:
+ CheckEnvVariable()
+ except FatalError, XExcept:
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc())
+ return XExcept.args[0]
+
+ GlobalData.gWORKSPACE = os.path.normpath(environ["WORKSPACE"])
+ WorkspaceDir = GlobalData.gWORKSPACE
+
+ SetLogLevel(Opt)
+
+ GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db")))
+ GlobalData.gDB.InitDatabase(Opt.SkipLock)
+
+ #
+ # Make sure the Db will get closed correctly
+ #
+ try:
+ ReturnCode = 0
+ CheckConflictOption(Opt)
+
+ RunModule = None
+ if Opt.PackFileToCreate:
+ if Opt.PackageInformationDataFile:
+ if not os.path.exists(Opt.PackageInformationDataFile):
+ if not os.path.exists(os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)):
+ Logger.Error("\nUPT", FILE_NOT_FOUND, ST.ERR_NO_TEMPLATE_FILE % Opt.PackageInformationDataFile)
+ else:
+ Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)
+ else:
+ Logger.Error("UPT", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_T_OPTION)
+ if not Opt.PackFileToCreate.endswith('.dist'):
+ Logger.Error("CreatePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToCreate)
+ RunModule = MkPkg.Main
+
+ elif Opt.PackFileToInstall:
+ if not Opt.PackFileToInstall.endswith('.dist'):
+ Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall)
+
+ #
+ # check file existence, if not absolute path, then try current working directory, then $(WORKSPACE)
+ #
+ Existed = True
+ if os.path.isabs(Opt.PackFileToInstall):
+ if not (os.path.exists(Opt.PackFileToInstall) and os.path.isfile(Opt.PackFileToInstall)):
+ Existed = False
+ else:
+ AbsPath = os.path.normpath(os.path.join(os.getcwd(), Opt.PackFileToInstall))
+ if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
+ AbsPath = os.path.normpath(os.path.join(WorkspaceDir, Opt.PackFileToInstall))
+ if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
+ Existed = False
+
+ if Existed:
+ Opt.PackFileToInstall = AbsPath
+
+ if not Existed:
+ Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)
+
+ setattr(Opt, 'PackageFile', Opt.PackFileToInstall)
+ RunModule = InstallPkg.Main
+
+ elif Opt.PackFileToRemove:
+ if not Opt.PackFileToRemove.endswith('.dist'):
+ Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove)
+ head, tail = os.path.split(Opt.PackFileToRemove)
+ if head or not tail:
+ Logger.Error("RemovePkg",
+ FILE_TYPE_MISMATCH,
+ ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove)
+
+ setattr(Opt, 'DistributionFile', Opt.PackFileToRemove)
+ RunModule = RmPkg.Main
+ else:
+ Parser.print_usage()
+ return OPTION_MISSING
+
+ ReturnCode = RunModule(Opt)
+ except FatalError, XExcept:
+ ReturnCode = XExcept.args[0]
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
+ format_exc())
+ finally:
+ GlobalData.gDB.CloseDb()
+
+ return ReturnCode
+
+if __name__ == '__main__':
+ RETVAL = Main()
+ #
+ # 0-127 is a safe return range, and 1 is a standard default error
+ #
+ if RETVAL < 0 or RETVAL > 127:
+ RETVAL = 1
+ sys.exit(RETVAL)
diff --git a/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py b/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py
new file mode 100644
index 0000000000..72a909db0e
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/UnitTest/CommentGeneratingUnitTest.py
@@ -0,0 +1,1419 @@
+## @file
+# This file contain unit test for CommentParsing
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+import os
+import unittest
+
+import Logger.Log as Logger
+from GenMetaFile.GenInfFile import GenGuidSections
+from GenMetaFile.GenInfFile import GenProtocolPPiSections
+from GenMetaFile.GenInfFile import GenPcdSections
+from GenMetaFile.GenInfFile import GenSpecialSections
+from Library.CommentGenerating import GenGenericCommentF
+from Library.CommentGenerating import _GetHelpStr
+from Object.POM.CommonObject import TextObject
+from Object.POM.CommonObject import GuidObject
+from Object.POM.CommonObject import ProtocolObject
+from Object.POM.CommonObject import PpiObject
+from Object.POM.CommonObject import PcdObject
+from Object.POM.ModuleObject import HobObject
+
+from Library.String import GetSplitValueList
+from Library.DataType import TAB_SPACE_SPLIT
+from Library.DataType import LANGUAGE_EN_US
+from Library.DataType import ITEM_UNDEFINED
+from Library.DataType import TAB_INF_FEATURE_PCD
+from Library import GlobalData
+from Library.Misc import CreateDirectory
+
+#
+# Test _GetHelpStr
+#
+class _GetHelpStrTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # Normal case1: have one help text object with Lang = 'en-US'
+ #
+ def testNormalCase1(self):
+ HelpStr = 'Hello world'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang(LANGUAGE_EN_US)
+ HelpTextObj.SetString(HelpStr)
+
+ HelpTextList = [HelpTextObj]
+ Result = _GetHelpStr(HelpTextList)
+ self.assertEqual(Result, HelpStr)
+
+ #
+ # Normal case2: have two help text object with Lang = 'en-US' and other
+ #
+ def testNormalCase2(self):
+ HelpStr = 'Hello world'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('eng')
+ HelpTextObj.SetString(HelpStr)
+
+ HelpTextList = [HelpTextObj]
+
+ ExpectedStr = 'Hello world1'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang(LANGUAGE_EN_US)
+ HelpTextObj.SetString(ExpectedStr)
+
+ HelpTextList.append(HelpTextObj)
+
+ Result = _GetHelpStr(HelpTextList)
+ self.assertEqual(Result, ExpectedStr)
+
+ #
+ # Normal case3: have two help text object with Lang = '' and 'eng'
+ #
+ def testNormalCase3(self):
+ HelpStr = 'Hello world'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+
+ HelpTextList = [HelpTextObj]
+
+ ExpectedStr = 'Hello world1'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('eng')
+ HelpTextObj.SetString(ExpectedStr)
+
+ HelpTextList.append(HelpTextObj)
+
+ Result = _GetHelpStr(HelpTextList)
+ self.assertEqual(Result, ExpectedStr)
+
+ #
+ # Normal case4: have two help text object with Lang = '' and ''
+ #
+ def testNormalCase4(self):
+
+ ExpectedStr = 'Hello world1'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('eng')
+ HelpTextObj.SetString(ExpectedStr)
+ HelpTextList = [HelpTextObj]
+
+ HelpStr = 'Hello world'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ HelpTextList.append(HelpTextObj)
+
+ Result = _GetHelpStr(HelpTextList)
+ self.assertEqual(Result, ExpectedStr)
+
+ #
+ # Normal case: have three help text object with Lang = '','en', 'en-US'
+ #
+ def testNormalCase5(self):
+
+ ExpectedStr = 'Hello world1'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang(LANGUAGE_EN_US)
+ HelpTextObj.SetString(ExpectedStr)
+ HelpTextList = [HelpTextObj]
+
+ HelpStr = 'Hello unknown world'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ HelpTextList.append(HelpTextObj)
+
+ HelpStr = 'Hello mysterious world'
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ HelpTextList.append(HelpTextObj)
+
+ Result = _GetHelpStr(HelpTextList)
+ self.assertEqual(Result, ExpectedStr)
+
+ HelpTextList.sort()
+ self.assertEqual(Result, ExpectedStr)
+
+ HelpTextList.sort(reverse=True)
+ self.assertEqual(Result, ExpectedStr)
+
+
+#
+# Test GenGuidSections
+#
+class GenGuidSectionsTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # This is the API to generate Guid Object to help UnitTest
+ #
+ def GuidFactory(self, CName, FFE, Usage, GuidType, VariableName, HelpStr):
+ Guid = GuidObject()
+ Guid.SetCName(CName)
+ Guid.SetFeatureFlag(FFE)
+ Guid.SetGuidTypeList([GuidType])
+ Guid.SetUsage(Usage)
+ Guid.SetVariableName(VariableName)
+
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ Guid.SetHelpTextList([HelpTextObj])
+
+ return Guid
+
+ #
+ # Normal case: have two GuidObject
+ #
+ def testNormalCase1(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 1'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'CONSUMES'
+ GuidType = 'Variable'
+ VariableName = ''
+ HelpStr = 'Usage comment line 2'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+## PRODUCES ## Event # Usage comment line 1
+## CONSUMES ## Variable: # Usage comment line 2
+Guid1|FFE1'''
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # Normal case: have two GuidObject
+ #
+ def testNormalCase2(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 1'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = 'Generic comment line 1\n Generic comment line 2'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+## PRODUCES ## Event # Usage comment line 1
+# Generic comment line 1
+# Generic comment line 2
+Guid1|FFE1'''
+
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # Normal case: have two GuidObject, one help goes to generic help,
+ # the other go into usage comment
+ #
+ def testNormalCase3(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = 'Generic comment'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 1'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+# Generic comment
+## PRODUCES ## Event # Usage comment line 1
+Guid1|FFE1'''
+
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # Normal case: have one GuidObject, generic comment multiple lines
+ #
+ def testNormalCase5(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = 'Generic comment line1 \n generic comment line 2'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+# Generic comment line1
+# generic comment line 2
+Guid1|FFE1'''
+
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # Normal case: have one GuidObject, usage comment multiple lines
+ #
+ def testNormalCase6(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 1\n Usage comment line 2'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+Guid1|FFE1 ## PRODUCES ## Event # Usage comment line 1 Usage comment line 2
+'''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+ #
+ # Normal case: have one GuidObject, usage comment one line
+ #
+ def testNormalCase7(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = 'Usage comment line 1'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+Guid1|FFE1 # Usage comment line 1
+'''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+ #
+ # Normal case: have two GuidObject
+ #
+ def testNormalCase8(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 1\n Usage comment line 2'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 3'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+## PRODUCES ## Event # Usage comment line 1 Usage comment line 2
+## PRODUCES ## Event # Usage comment line 3
+Guid1|FFE1
+'''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+ #
+ # Normal case: have no GuidObject
+ #
+ def testNormalCase9(self):
+ GuidList = []
+
+ Result = GenGuidSections(GuidList)
+ Expected = ''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+ #
+ # Normal case: have one GuidObject with no comment generated
+ #
+ def testNormalCase10(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = ''
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+Guid1|FFE1
+'''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+ #
+ # Normal case: have three GuidObject
+ #
+ def testNormalCase11(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = 'general comment line 1'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = 'Usage comment line 3'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'UNDEFINED'
+ GuidType = 'UNDEFINED'
+ VariableName = ''
+ HelpStr = 'general comment line 2'
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+# general comment line 1
+## PRODUCES ## Event # Usage comment line 3
+# general comment line 2
+Guid1|FFE1
+'''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+ #
+ # Normal case: have three GuidObject, with Usage/Type and no help
+ #
+ def testNormalCase12(self):
+ GuidList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'GUID'
+ VariableName = ''
+ HelpStr = ''
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'PRODUCES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = ''
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+ Usage = 'CONSUMES'
+ GuidType = 'Event'
+ VariableName = ''
+ HelpStr = ''
+ Guid1 = self.GuidFactory(CName, FFE, Usage, GuidType,
+ VariableName, HelpStr)
+ GuidList.append(Guid1)
+
+ Result = GenGuidSections(GuidList)
+ Expected = '''[Guids]
+## PRODUCES ## GUID
+## PRODUCES ## Event
+## CONSUMES ## Event
+Guid1|FFE1
+'''
+ self.assertEqual(Result.strip(), Expected.strip())
+
+#
+# Test GenProtocolPPiSections
+#
+class GenProtocolPPiSectionsTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # This is the API to generate Protocol/Ppi Object to help UnitTest
+ #
+ def ObjectFactory(self, CName, FFE, Usage, Notify, HelpStr, IsProtocol):
+ if IsProtocol:
+ Object = ProtocolObject()
+ else:
+ Object = PpiObject()
+
+ Object.SetCName(CName)
+ Object.SetFeatureFlag(FFE)
+ Object.SetUsage(Usage)
+ Object.SetNotify(Notify)
+
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ Object.SetHelpTextList([HelpTextObj])
+
+ return Object
+
+ # Usage Notify Help INF Comment
+ #1 UNDEFINED true Present ## UNDEFINED ## NOTIFY # Help
+ #2 UNDEFINED true Not Present ## UNDEFINED ## NOTIFY
+ #3 UNDEFINED false Present ## UNDEFINED # Help
+ #4 UNDEFINED false Not Present ## UNDEFINED
+ #5 UNDEFINED Not Present Present # Help
+ #6 UNDEFINED Not Present Not Present <empty>
+ #7 Other true Present ## Other ## NOTIFY # Help
+ #8 Other true Not Present ## Other ## NOTIFY
+ #9 Other false Present ## Other # Help
+ #A Other false Not Present ## Other
+ #B Other Not Present Present ## Other # Help
+ #C Other Not Present Not Present ## Other
+
+ def testNormalCase1(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'UNDEFINED'
+ Notify = True
+ HelpStr = 'Help'
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## UNDEFINED ## NOTIFY # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ IsProtocol = False
+ ObjectList = []
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Ppis]
+Guid1|FFE1 ## UNDEFINED ## NOTIFY # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase2(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'UNDEFINED'
+ Notify = True
+ HelpStr = ''
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## UNDEFINED ## NOTIFY'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase3(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'UNDEFINED'
+ Notify = False
+ HelpStr = 'Help'
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## UNDEFINED # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase4(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'UNDEFINED'
+ Notify = False
+ HelpStr = ''
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## UNDEFINED'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase5(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'UNDEFINED'
+ Notify = ''
+ HelpStr = 'Help'
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase6(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'UNDEFINED'
+ Notify = ''
+ HelpStr = ''
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase7(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'PRODUCES'
+ Notify = True
+ HelpStr = 'Help'
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## PRODUCES ## NOTIFY # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase8(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'PRODUCES'
+ Notify = True
+ HelpStr = ''
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## PRODUCES ## NOTIFY'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase9(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'PRODUCES'
+ Notify = False
+ HelpStr = 'Help'
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## PRODUCES # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCaseA(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'PRODUCES'
+ Notify = False
+ HelpStr = ''
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## PRODUCES'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCaseB(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'PRODUCES'
+ Notify = ''
+ HelpStr = 'Help'
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## PRODUCES # Help'''
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCaseC(self):
+ ObjectList = []
+
+ CName = 'Guid1'
+ FFE = 'FFE1'
+
+ Usage = 'PRODUCES'
+ Notify = ''
+ HelpStr = ''
+ IsProtocol = True
+ Object = self.ObjectFactory(CName, FFE, Usage, Notify,
+ HelpStr, IsProtocol)
+ ObjectList.append(Object)
+
+
+ Result = GenProtocolPPiSections(ObjectList, IsProtocol)
+ Expected = '''[Protocols]
+Guid1|FFE1 ## PRODUCES'''
+ self.assertEqual(Result.strip(), Expected)
+
+#
+# Test GenPcdSections
+#
+class GenPcdSectionsTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # This is the API to generate Pcd Object to help UnitTest
+ #
+ def ObjectFactory(self, ItemType, TSCName, CName, DValue, FFE, Usage, Str):
+ Object = PcdObject()
+ HelpStr = Str
+
+ Object.SetItemType(ItemType)
+ Object.SetTokenSpaceGuidCName(TSCName)
+ Object.SetCName(CName)
+ Object.SetDefaultValue(DValue)
+ Object.SetFeatureFlag(FFE)
+ Object.SetValidUsage(Usage)
+
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ Object.SetHelpTextList([HelpTextObj])
+
+ return Object
+
+
+ # Usage Help INF Comment
+ #1 UNDEFINED Present # Help
+ #2 UNDEFINED Not Present <empty>
+ #3 Other Present ## Other # Help
+ #4 Other Not Present ## Other
+
+ def testNormalCase1(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'UNDEFINED'
+ Str = 'Help'
+
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = \
+ '[Pcd]\n' + \
+ 'TSCName.CName|DValue|FFE # Help'
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase2(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'UNDEFINED'
+ Str = ''
+
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '[Pcd]\nTSCName.CName|DValue|FFE'
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase3(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'CONSUMES'
+ Str = 'Help'
+
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '[Pcd]\nTSCName.CName|DValue|FFE ## CONSUMES # Help'
+ self.assertEqual(Result.strip(), Expected)
+
+ def testNormalCase4(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'CONSUMES'
+ Str = ''
+
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '[Pcd]\nTSCName.CName|DValue|FFE ## CONSUMES'
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # multiple lines for normal usage
+ #
+ def testNormalCase5(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'CONSUMES'
+ Str = 'commment line 1\ncomment line 2'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '''[Pcd]
+TSCName.CName|DValue|FFE ## CONSUMES # commment line 1 comment line 2'''
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # multiple lines for UNDEFINED usage
+ #
+ def testNormalCase6(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'UNDEFINED'
+ Str = 'commment line 1\ncomment line 2'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Usage = 'UNDEFINED'
+ Str = 'commment line 3'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '''[Pcd]
+# commment line 1
+# comment line 2
+# commment line 3
+TSCName.CName|DValue|FFE'''
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # multiple lines for UNDEFINED and normal usage
+ #
+ def testNormalCase7(self):
+ ObjectList = []
+ ItemType = 'Pcd'
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'UNDEFINED'
+ Str = 'commment line 1\ncomment line 2'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Usage = 'CONSUMES'
+ Str = 'Foo'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Usage = 'UNDEFINED'
+ Str = 'commment line 3'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '''[Pcd]
+# commment line 1
+# comment line 2
+## CONSUMES # Foo
+# commment line 3
+TSCName.CName|DValue|FFE'''
+ self.assertEqual(Result.strip(), Expected)
+
+ # Usage Help INF Comment
+ # CONSUMES Present # Help (keep <EOL> and insert '#' at beginning of each new line)
+ # CONSUMES Not Present <empty>
+
+ #
+ # TAB_INF_FEATURE_PCD
+ #
+ def testNormalCase8(self):
+ ObjectList = []
+ ItemType = TAB_INF_FEATURE_PCD
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'CONSUMES'
+ Str = 'commment line 1\ncomment line 2'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '''[FeaturePcd]
+# commment line 1
+# comment line 2
+TSCName.CName|DValue|FFE'''
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # TAB_INF_FEATURE_PCD
+ #
+ def testNormalCase9(self):
+ ObjectList = []
+ ItemType = TAB_INF_FEATURE_PCD
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'CONSUMES'
+ Str = ''
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '''[FeaturePcd]
+TSCName.CName|DValue|FFE'''
+ self.assertEqual(Result.strip(), Expected)
+
+ #
+ # TAB_INF_FEATURE_PCD
+ #
+ def testNormalCase10(self):
+ ObjectList = []
+ ItemType = TAB_INF_FEATURE_PCD
+ TSCName = 'TSCName'
+ CName = 'CName'
+ DValue = 'DValue'
+ FFE = 'FFE'
+
+ Usage = 'PRODUCES'
+ Str = 'commment line 1\ncomment line 2'
+ Object = self.ObjectFactory(ItemType, TSCName, CName, DValue, FFE,
+ Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenPcdSections(ObjectList)
+ Expected = '''
+
+[FeaturePcd]
+# commment line 1
+# comment line 2
+TSCName.CName|DValue|FFE
+'''
+ self.assertEqual(Result, Expected)
+
+
+#
+# Test GenSpecialSections of Hob
+#
+class GenHobSectionsTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # This is the API to generate Event Object to help UnitTest
+ #
+ def ObjectFactory(self, SupArchList, Type, Usage, Str):
+ Object = HobObject()
+ HelpStr = Str
+
+ Object.SetHobType(Type)
+ Object.SetUsage(Usage)
+ Object.SetSupArchList(SupArchList)
+
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang('')
+ HelpTextObj.SetString(HelpStr)
+ Object.SetHelpTextList([HelpTextObj])
+
+ return Object
+
+ def testNormalCase1(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = 'Help'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# # Help
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase2(self):
+ ObjectList = []
+ SupArchList = []
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = 'Help'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob]
+# ##
+# # Help
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase3(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\nComment Line 1\n\n'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# # Comment Line 1
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase4(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\nComment Line 1\n'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# # Comment Line 1
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase5(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = 'Comment Line 1\n\n'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# # Comment Line 1
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase6(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = ''
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase7(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\nNew Stack HoB'
+
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# # New Stack HoB
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase8(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\nNew Stack HoB\n\nTail Comment'
+
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# # New Stack HoB
+# #
+# # Tail Comment
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase9(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\n\n'
+
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# #
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase10(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\n'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# #
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase11(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\n\n\n'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# #
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase12(self):
+ ObjectList = []
+ SupArchList = ['X64']
+ Type = 'Foo'
+ Usage = 'UNDEFINED'
+ Str = '\n\n\n\n'
+
+ Object = self.ObjectFactory(SupArchList, Type, Usage, Str)
+ ObjectList.append(Object)
+
+ Result = GenSpecialSections(ObjectList, 'Hob')
+ Expected = '''# [Hob.X64]
+# ##
+# #
+# #
+# #
+# Foo ## UNDEFINED
+#
+#
+'''
+ self.assertEqual(Result, Expected)
+
+#
+# Test GenGenericCommentF
+#
+class GenGenericCommentFTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testNormalCase1(self):
+ CommentLines = 'Comment Line 1'
+ Result = GenGenericCommentF(CommentLines)
+ Expected = '# Comment Line 1\n'
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase2(self):
+ CommentLines = '\n'
+ Result = GenGenericCommentF(CommentLines)
+ Expected = '#\n'
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase3(self):
+ CommentLines = '\n\n\n'
+ Result = GenGenericCommentF(CommentLines)
+ Expected = '#\n#\n#\n'
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase4(self):
+ CommentLines = 'coment line 1\n'
+ Result = GenGenericCommentF(CommentLines)
+ Expected = '# coment line 1\n'
+ self.assertEqual(Result, Expected)
+
+ def testNormalCase5(self):
+ CommentLines = 'coment line 1\n coment line 2\n'
+ Result = GenGenericCommentF(CommentLines)
+ Expected = '# coment line 1\n# coment line 2\n'
+ self.assertEqual(Result, Expected)
+
+if __name__ == '__main__':
+ Logger.Initialize()
+ unittest.main() \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py b/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py
new file mode 100644
index 0000000000..3ed3345c6d
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/UnitTest/CommentParsingUnitTest.py
@@ -0,0 +1,923 @@
+## @file
+# This file contain unit test for CommentParsing
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+import unittest
+
+import Logger.Log as Logger
+from Library.CommentParsing import ParseHeaderCommentSection, \
+ ParseGenericComment, \
+ ParseDecPcdGenericComment, \
+ ParseDecPcdTailComment
+from Library.CommentParsing import _IsCopyrightLine
+from Library.String import GetSplitValueList
+from Library.DataType import TAB_SPACE_SPLIT
+from Library.DataType import LANGUAGE_EN_US
+
+#
+# Test ParseHeaderCommentSection
+#
+class ParseHeaderCommentSectionTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # Normal case1: have license/copyright/license above @file
+ #
+ def testNormalCase1(self):
+ TestCommentLines1 = \
+ '''# License1
+ # License2
+ #
+ ## @file
+ # example abstract
+ #
+ # example description
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ #
+ # License3
+ #'''
+
+ CommentList = GetSplitValueList(TestCommentLines1, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = 'example abstract'
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = 'example description'
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010,'\
+ ' Intel Corporation. All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = 'License1\nLicense2\n\nLicense3'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Normal case2: have license/copyright above @file, but no copyright after
+ #
+ def testNormalCase2(self):
+ TestCommentLines2 = \
+ ''' # License1
+ # License2
+ #
+ ## @file
+ # example abstract
+ #
+ # example description
+ #
+ #Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines2, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = 'example abstract'
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = 'example description'
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = 'License1\nLicense2'
+ self.assertEqual(License, ExpectedLicense)
+
+
+ #
+ # Normal case2: have license/copyright/license above @file,
+ # but no abstract/description
+ #
+ def testNormalCase3(self):
+ TestCommentLines3 = \
+ ''' # License1
+ # License2
+ #
+ ## @file
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ #
+ # License3 Line1
+ # License3 Line2
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines3, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = ''
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = ''
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010,'\
+ ' Intel Corporation. All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = \
+ 'License1\n' \
+ 'License2\n\n' \
+ 'License3 Line1\n' \
+ 'License3 Line2'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Normal case4: format example in spec
+ #
+ def testNormalCase4(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ # Abstract
+ #
+ # Description
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ #
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = 'Abstract'
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = 'Description'
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = \
+ 'License'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Normal case5: other line between copyright
+ #
+ def testNormalCase5(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ # Abstract
+ #
+ # Description
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ # other line
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ #
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = 'Abstract'
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = 'Description'
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>\n'\
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = \
+ 'License'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Normal case6: multiple lines of copyright
+ #
+ def testNormalCase6(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ # Abstract
+ #
+ # Description
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ # Copyright (c) 2007 - 2010, FOO1 Corporation. All rights reserved.<BR>
+ # Copyright (c) 2007 - 2010, FOO2 Corporation. All rights reserved.<BR>
+ #
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = 'Abstract'
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = 'Description'
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>\n'\
+ 'Copyright (c) 2007 - 2010, FOO1 Corporation.'\
+ ' All rights reserved.<BR>\n'\
+ 'Copyright (c) 2007 - 2010, FOO2 Corporation.'\
+ ' All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = \
+ 'License'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Normal case7: Abstract not present
+ #
+ def testNormalCase7(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ #
+ # Description
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ # Copyright (c) 2007 - 2010, FOO1 Corporation. All rights reserved.<BR>
+ # Copyright (c) 2007 - 2010, FOO2 Corporation. All rights reserved.<BR>
+ #
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = ''
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = 'Description'
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>\n'\
+ 'Copyright (c) 2007 - 2010, FOO1 Corporation.'\
+ ' All rights reserved.<BR>\n'\
+ 'Copyright (c) 2007 - 2010, FOO2 Corporation.'\
+ ' All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = \
+ 'License'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Normal case8: Description not present
+ #
+ def testNormalCase8(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ # Abstact
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ #
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ Abstract, Description, Copyright, License = \
+ ParseHeaderCommentSection(TestCommentLinesList, "PhonyFile")
+
+ ExpectedAbstract = 'Abstact'
+ self.assertEqual(Abstract, ExpectedAbstract)
+
+ ExpectedDescription = ''
+ self.assertEqual(Description, ExpectedDescription)
+
+ ExpectedCopyright = \
+ 'Copyright (c) 2007 - 2010, Intel Corporation.'\
+ ' All rights reserved.<BR>'
+ self.assertEqual(Copyright, ExpectedCopyright)
+
+ ExpectedLicense = \
+ 'License'
+ self.assertEqual(License, ExpectedLicense)
+
+ #
+ # Error case1: No copyright found
+ #
+ def testErrorCase1(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ # Abstract
+ #
+ # Description
+ #
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ self.assertRaises(Logger.FatalError,
+ ParseHeaderCommentSection,
+ TestCommentLinesList,
+ "PhonyFile")
+
+ #
+ # Error case2: non-empty non-comment lines passed in
+ #
+ def testErrorCase2(self):
+ TestCommentLines = \
+ '''
+ ## @file
+ # Abstract
+ #
+ this is invalid line
+ # Description
+ #
+ # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+ # License
+ #
+ ##'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ self.assertRaises(Logger.FatalError,
+ ParseHeaderCommentSection,
+ TestCommentLinesList,
+ "PhonyFile")
+
+#
+# Test ParseGenericComment
+#
+class ParseGenericCommentTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # Normal case1: one line of comment
+ #
+ def testNormalCase1(self):
+ TestCommentLines = \
+ '''# hello world'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ HelptxtObj = ParseGenericComment(TestCommentLinesList, 'testNormalCase1')
+ self.failIf(not HelptxtObj)
+ self.assertEqual(HelptxtObj.GetString(), 'hello world')
+ self.assertEqual(HelptxtObj.GetLang(), LANGUAGE_EN_US)
+
+ #
+ # Normal case2: multiple lines of comment
+ #
+ def testNormalCase2(self):
+ TestCommentLines = \
+ '''## hello world
+ # second line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ HelptxtObj = ParseGenericComment(TestCommentLinesList, 'testNormalCase2')
+ self.failIf(not HelptxtObj)
+ self.assertEqual(HelptxtObj.GetString(),
+ 'hello world\n' + 'second line')
+ self.assertEqual(HelptxtObj.GetLang(), LANGUAGE_EN_US)
+
+ #
+ # Normal case3: multiple lines of comment, non comment lines will be skipped
+ #
+ def testNormalCase3(self):
+ TestCommentLines = \
+ '''## hello world
+ This is not comment line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ HelptxtObj = ParseGenericComment(TestCommentLinesList, 'testNormalCase3')
+ self.failIf(not HelptxtObj)
+ self.assertEqual(HelptxtObj.GetString(),
+ 'hello world\n\n')
+ self.assertEqual(HelptxtObj.GetLang(), LANGUAGE_EN_US)
+
+#
+# Test ParseDecPcdGenericComment
+#
+class ParseDecPcdGenericCommentTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # Normal case1: comments with no special comment
+ #
+ def testNormalCase1(self):
+ TestCommentLines = \
+ '''## hello world
+ # second line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (HelpTxt, PcdErr) = \
+ ParseDecPcdGenericComment(TestCommentLinesList, 'testNormalCase1')
+ self.failIf(not HelpTxt)
+ self.failIf(PcdErr)
+ self.assertEqual(HelpTxt,
+ 'hello world\n' + 'second line')
+
+
+ #
+ # Normal case2: comments with valid list
+ #
+ def testNormalCase2(self):
+ TestCommentLines = \
+ '''## hello world
+ # second line
+ # @ValidList 1, 2, 3
+ # other line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (HelpTxt, PcdErr) = \
+ ParseDecPcdGenericComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpTxt)
+ self.failIf(not PcdErr)
+ self.assertEqual(HelpTxt,
+ 'hello world\n' + 'second line\n' + 'other line')
+ ExpectedList = GetSplitValueList('1 2 3', TAB_SPACE_SPLIT)
+ ActualList = [item for item in \
+ GetSplitValueList(PcdErr.GetValidValue(), TAB_SPACE_SPLIT) if item]
+ self.assertEqual(ExpectedList, ActualList)
+ self.failIf(PcdErr.GetExpression())
+ self.failIf(PcdErr.GetValidValueRange())
+
+ #
+ # Normal case3: comments with valid range
+ #
+ def testNormalCase3(self):
+ TestCommentLines = \
+ '''## hello world
+ # second line
+ # @ValidRange LT 1 AND GT 2
+ # other line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (HelpTxt, PcdErr) = \
+ ParseDecPcdGenericComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpTxt)
+ self.failIf(not PcdErr)
+ self.assertEqual(HelpTxt,
+ 'hello world\n' + 'second line\n' + 'other line')
+ self.assertEqual(PcdErr.GetValidValueRange().strip(), 'LT 1 AND GT 2')
+ self.failIf(PcdErr.GetExpression())
+ self.failIf(PcdErr.GetValidValue())
+
+ #
+ # Normal case4: comments with valid expression
+ #
+ def testNormalCase4(self):
+ TestCommentLines = \
+ '''## hello world
+ # second line
+ # @Expression LT 1 AND GT 2
+ # other line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (HelpTxt, PcdErr) = \
+ ParseDecPcdGenericComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpTxt)
+ self.failIf(not PcdErr)
+ self.assertEqual(HelpTxt,
+ 'hello world\n' + 'second line\n' + 'other line')
+ self.assertEqual(PcdErr.GetExpression().strip(), 'LT 1 AND GT 2')
+ self.failIf(PcdErr.GetValidValueRange())
+ self.failIf(PcdErr.GetValidValue())
+
+ #
+ # Normal case5: comments with valid expression and no generic comment
+ #
+ def testNormalCase5(self):
+ TestCommentLines = \
+ '''# @Expression LT 1 AND GT 2'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (HelpTxt, PcdErr) = \
+ ParseDecPcdGenericComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(HelpTxt)
+ self.failIf(not PcdErr)
+ self.assertEqual(PcdErr.GetExpression().strip(), 'LT 1 AND GT 2')
+ self.failIf(PcdErr.GetValidValueRange())
+ self.failIf(PcdErr.GetValidValue())
+
+ #
+ # Normal case6: comments with only generic help text
+ #
+ def testNormalCase6(self):
+ TestCommentLines = \
+ '''#'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (HelpTxt, PcdErr) = \
+ ParseDecPcdGenericComment(TestCommentLinesList, 'UnitTest')
+ self.assertEqual(HelpTxt, '\n')
+ self.failIf(PcdErr)
+
+
+
+ #
+ # Error case1: comments with both expression and valid list, use later
+ # ignore the former and with a warning message
+ #
+ def testErrorCase1(self):
+ TestCommentLines = \
+ '''## hello world
+ # second line
+ # @ValidList 1, 2, 3
+ # @Expression LT 1 AND GT 2
+ # other line'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ try:
+ ParseDecPcdGenericComment(TestCommentLinesList, 'UnitTest')
+ except Logger.FatalError:
+ pass
+
+#
+# Test ParseDecPcdTailComment
+#
+class ParseDecPcdTailCommentTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # Normal case1: comments with no SupModeList
+ #
+ def testNormalCase1(self):
+ TestCommentLines = \
+ '''## #hello world'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (SupModeList, HelpStr) = \
+ ParseDecPcdTailComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpStr)
+ self.failIf(SupModeList)
+ self.assertEqual(HelpStr,
+ 'hello world')
+
+ #
+ # Normal case2: comments with one SupMode
+ #
+ def testNormalCase2(self):
+ TestCommentLines = \
+ '''## BASE #hello world'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (SupModeList, HelpStr) = \
+ ParseDecPcdTailComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpStr)
+ self.failIf(not SupModeList)
+ self.assertEqual(HelpStr,
+ 'hello world')
+ self.assertEqual(SupModeList,
+ ['BASE'])
+
+ #
+ # Normal case3: comments with more than one SupMode
+ #
+ def testNormalCase3(self):
+ TestCommentLines = \
+ '''## BASE UEFI_APPLICATION #hello world'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (SupModeList, HelpStr) = \
+ ParseDecPcdTailComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpStr)
+ self.failIf(not SupModeList)
+ self.assertEqual(HelpStr,
+ 'hello world')
+ self.assertEqual(SupModeList,
+ ['BASE', 'UEFI_APPLICATION'])
+
+ #
+ # Normal case4: comments with more than one SupMode, no help text
+ #
+ def testNormalCase4(self):
+ TestCommentLines = \
+ '''## BASE UEFI_APPLICATION'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (SupModeList, HelpStr) = \
+ ParseDecPcdTailComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(HelpStr)
+ self.failIf(not SupModeList)
+ self.assertEqual(SupModeList,
+ ['BASE', 'UEFI_APPLICATION'])
+
+ #
+ # Normal case5: general comments with no supModList, extract from real case
+ #
+ def testNormalCase5(self):
+ TestCommentLines = \
+ ''' # 1 = 128MB, 2 = 256MB, 3 = MAX'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ (SupModeList, HelpStr) = \
+ ParseDecPcdTailComment(TestCommentLinesList, 'UnitTest')
+ self.failIf(not HelpStr)
+ self.assertEqual(HelpStr,
+ '1 = 128MB, 2 = 256MB, 3 = MAX')
+ self.failIf(SupModeList)
+
+
+ #
+ # Error case2: comments with supModList contains valid and invalid
+ # module type
+ #
+ def testErrorCase2(self):
+ TestCommentLines = \
+ '''## BASE INVALID_MODULE_TYPE #hello world'''
+
+ CommentList = GetSplitValueList(TestCommentLines, "\n")
+ LineNum = 0
+ TestCommentLinesList = []
+ for Comment in CommentList:
+ LineNum += 1
+ TestCommentLinesList.append((Comment, LineNum))
+
+ try:
+ ParseDecPcdTailComment(TestCommentLinesList, 'UnitTest')
+ except Logger.FatalError:
+ pass
+
+
+#
+# Test _IsCopyrightLine
+#
+class _IsCopyrightLineTest(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ #
+ # Normal case
+ #
+ def testCase1(self):
+ Line = 'this is a copyright ( line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(not Result)
+
+ #
+ # Normal case
+ #
+ def testCase2(self):
+ Line = 'this is a Copyright ( line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(not Result)
+
+ #
+ # Normal case
+ #
+ def testCase3(self):
+ Line = 'this is not aCopyright ( line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(Result)
+
+ #
+ # Normal case
+ #
+ def testCase4(self):
+ Line = 'this is Copyright( line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(not Result)
+
+ #
+ # Normal case
+ #
+ def testCase5(self):
+ Line = 'this is Copyright (line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(not Result)
+
+ #
+ # Normal case
+ #
+ def testCase6(self):
+ Line = 'this is not Copyright line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(Result)
+
+ #
+ # Normal case
+ #
+ def testCase7(self):
+ Line = 'Copyright (c) line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(not Result)
+
+ #
+ # Normal case
+ #
+ def testCase8(self):
+ Line = ' Copyright (c) line'
+ Result = _IsCopyrightLine(Line)
+ self.failIf(not Result)
+
+ #
+ # Normal case
+ #
+ def testCase9(self):
+ Line = 'not a Copyright '
+ Result = _IsCopyrightLine(Line)
+ self.failIf(Result)
+
+if __name__ == '__main__':
+ Logger.Initialize()
+ unittest.main() \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py b/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py
new file mode 100644
index 0000000000..8b4ece2617
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/UnitTest/DecParserTest.py
@@ -0,0 +1,284 @@
+## @file
+# This file contain unit test for DecParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+import os
+import unittest
+
+from Parser.DecParserMisc import \
+ IsValidCArray, \
+ IsValidPcdDatum
+
+from Parser.DecParser import Dec
+
+from Library.ParserValidate import IsValidCFormatGuid
+
+#
+# Test tool function
+#
+def TestToolFuncs():
+ assert IsValidCArray('{0x1, 0x23}')
+
+ # Empty after comma
+ assert not IsValidCArray('{0x1, 0x23, }')
+
+ # 0x2345 too long
+ assert not IsValidCArray('{0x1, 0x2345}')
+
+ # Must end with '}'
+ assert not IsValidCArray('{0x1, 0x23, ')
+
+ # Whitespace between numbers
+ assert not IsValidCArray('{0x1, 0x2 3, }')
+
+ assert IsValidPcdDatum('VOID*', '"test"')[0]
+ assert IsValidPcdDatum('VOID*', 'L"test"')[0]
+ assert IsValidPcdDatum('BOOLEAN', 'TRUE')[0]
+ assert IsValidPcdDatum('BOOLEAN', 'FALSE')[0]
+ assert IsValidPcdDatum('BOOLEAN', '0')[0]
+ assert IsValidPcdDatum('BOOLEAN', '1')[0]
+ assert IsValidPcdDatum('UINT8', '0xab')[0]
+
+ assert not IsValidPcdDatum('UNKNOWNTYPE', '0xabc')[0]
+ assert not IsValidPcdDatum('UINT8', 'not number')[0]
+
+ assert( IsValidCFormatGuid('{ 0xfa0b1735 , 0x87a0, 0x4193, {0xb2, 0x66 , 0x53, 0x8c , 0x38, 0xaf, 0x48, 0xce }}'))
+ assert( not IsValidCFormatGuid('{ 0xfa0b1735 , 0x87a0, 0x4193, {0xb2, 0x66 , 0x53, 0x8c , 0x38, 0xaf, 0x48, 0xce }} 0xaa'))
+
+def TestTemplate(TestString, TestFunc):
+ Path = os.path.join(os.getcwd(), 'test.dec')
+ Path = os.path.normpath(Path)
+ try:
+ f = open(Path, 'w')
+
+ # Write test string to file
+ f.write(TestString)
+
+ # Close file
+ f.close()
+ except:
+ print 'Can not create temporary file [%s]!' % Path
+ exit(-1)
+
+ # Call test function to test
+ Ret = TestFunc(Path, TestString)
+
+ # Test done, remove temporary file
+ os.remove(Path)
+ return Ret
+
+# To make test unit works OK, must set IsRaiseError to True
+# This function test right syntax DEC file
+# @retval: parser object
+#
+def TestOK(Path, TestString):
+ try:
+ Parser = Dec(Path)
+ except:
+ raise 'Bug!!! Correct syntax in DEC file, but exception raised!\n' + TestString
+ return Parser
+
+# This function test wrong syntax DEC file
+# if parser checked wrong syntax, exception thrown and it's expected result
+def TestError(Path, TestString):
+ try:
+ Dec(Path)
+ except:
+ # Raise error, get expected result
+ return True
+ raise 'Bug!!! Wrong syntax in DEC file, but passed by DEC parser!!\n' + TestString
+
+def TestDecDefine():
+ TestString = '''
+ [Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = MdePkg
+ PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6766
+ PACKAGE_VERSION = 1.02
+ '''
+ Parser = TestTemplate(TestString, TestOK)
+ DefObj = Parser.GetDefineSectionObject()
+ assert DefObj.GetPackageSpecification() == '0x00010005'
+ assert DefObj.GetPackageName() == 'MdePkg'
+ assert DefObj.GetPackageGuid() == '1E73767F-8F52-4603-AEB4-F29B510B6766'
+ assert DefObj.GetPackageVersion() == '1.02'
+
+ TestString = '''
+ [Defines]
+ UNKNOW_KEY = 0x00010005 # A unknown key
+ '''
+ assert TestTemplate(TestString, TestError)
+
+ TestString = '''
+ [Defines]
+ PACKAGE_GUID = F-8F52-4603-AEB4-F29B510B6766 # Error GUID
+ '''
+ assert TestTemplate(TestString, TestError)
+
+def TestDecInclude():
+ TestString = '''
+ [Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = MdePkg
+ PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6766
+ PACKAGE_VERSION = 1.02
+ [ \\
+ Includes]
+ Include
+ [Includes.IA32]
+ Include/Ia32
+ '''
+
+ # Create directory in current directory
+ try:
+ os.makedirs('Include/Ia32')
+ except:
+ pass
+ Parser = TestTemplate(TestString, TestOK)
+
+ IncObj = Parser.GetIncludeSectionObject()
+ Items = IncObj.GetIncludes()
+ assert len(Items) == 1
+ assert Items[0].File == 'Include'
+
+ Items = IncObj.GetIncludes('IA32')
+ assert len(Items) == 1
+ # normpath is called in DEC parser so '/' is converted to '\'
+ assert Items[0].File == 'Include\\Ia32'
+
+ TestString = '''
+ [Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = MdePkg
+ PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6766
+ PACKAGE_VERSION = 1.02
+ [Includes]
+ Include_not_exist # directory does not exist
+ '''
+ assert TestTemplate(TestString, TestError)
+
+ os.removedirs('Include/Ia32')
+
+def TestDecGuidPpiProtocol():
+ TestString = '''
+ [Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = MdePkg
+ PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6766
+ PACKAGE_VERSION = 1.02
+ [Guids]
+ #
+ # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
+ #
+ ## Include/Guid/GlobalVariable.h
+ gEfiGlobalVariableGuid = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }}
+ [Protocols]
+ ## Include/Protocol/Bds.h
+ gEfiBdsArchProtocolGuid = { 0x665E3FF6, 0x46CC, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
+ [Ppis]
+ ## Include/Ppi/MasterBootMode.h
+ gEfiPeiMasterBootModePpiGuid = { 0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10 } }
+ '''
+ Parser = TestTemplate(TestString, TestOK)
+ Obj = Parser.GetGuidSectionObject()
+ Items = Obj.GetGuids()
+ assert Obj.GetSectionName() == 'Guids'.upper()
+ assert len(Items) == 1
+ assert Items[0].GuidCName == 'gEfiGlobalVariableGuid'
+ assert Items[0].GuidCValue == '{ 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }}'
+
+ Obj = Parser.GetProtocolSectionObject()
+ Items = Obj.GetProtocols()
+ assert Obj.GetSectionName() == 'Protocols'.upper()
+ assert len(Items) == 1
+ assert Items[0].GuidCName == 'gEfiBdsArchProtocolGuid'
+ assert Items[0].GuidCValue == '{ 0x665E3FF6, 0x46CC, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}'
+
+ Obj = Parser.GetPpiSectionObject()
+ Items = Obj.GetPpis()
+ assert Obj.GetSectionName() == 'Ppis'.upper()
+ assert len(Items) == 1
+ assert Items[0].GuidCName == 'gEfiPeiMasterBootModePpiGuid'
+ assert Items[0].GuidCValue == '{ 0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10 } }'
+
+def TestDecPcd():
+ TestString = '''
+ [Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = MdePkg
+ PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6766
+ PACKAGE_VERSION = 1.02
+ [PcdsFeatureFlag]
+ ## If TRUE, the component name protocol will not be installed.
+ gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d
+
+ [PcdsFixedAtBuild]
+ ## Indicates the maximum length of unicode string
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000|UINT32|0x00000001
+
+ [PcdsFixedAtBuild.IPF]
+ ## The base address of IO port space for IA64 arch
+ gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000|UINT64|0x0000000f
+
+ [PcdsFixedAtBuild,PcdsPatchableInModule]
+ ## This flag is used to control the printout of DebugLib
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000|UINT32|0x00000006
+
+ [PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]
+ ## This value is used to set the base address of pci express hierarchy
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000|UINT64|0x0000000a
+ '''
+ Parser = TestTemplate(TestString, TestOK)
+ Obj = Parser.GetPcdSectionObject()
+ Items = Obj.GetPcds('PcdsFeatureFlag', 'COMMON')
+ assert len(Items) == 1
+ assert Items[0].TokenSpaceGuidCName == 'gEfiMdePkgTokenSpaceGuid'
+ assert Items[0].TokenCName == 'PcdComponentNameDisable'
+ assert Items[0].DefaultValue == 'FALSE'
+ assert Items[0].DatumType == 'BOOLEAN'
+ assert Items[0].TokenValue == '0x0000000d'
+
+ Items = Obj.GetPcdsByType('PcdsFixedAtBuild')
+ assert len(Items) == 4
+ assert len(Obj.GetPcdsByType('PcdsPatchableInModule')) == 2
+
+def TestDecUserExtension():
+ TestString = '''
+ [Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = MdePkg
+ PACKAGE_GUID = 1E73767F-8F52-4603-AEB4-F29B510B6766
+ PACKAGE_VERSION = 1.02
+ [UserExtensions.MyID."TestString".IA32]
+ Some Strings...
+ '''
+ Parser = TestTemplate(TestString, TestOK)
+ Obj = Parser.GetUserExtensionSectionObject()
+ Items = Obj.GetAllUserExtensions()
+ assert len(Items) == 1
+ assert Items[0].UserString == 'Some Strings...'
+ assert len(Items[0].ArchAndModuleType) == 1
+ assert ['MyID', '"TestString"', 'IA32'] in Items[0].ArchAndModuleType
+
+if __name__ == '__main__':
+ import Logger.Logger
+ Logger.Logger.Initialize()
+ unittest.FunctionTestCase(TestToolFuncs).runTest()
+ unittest.FunctionTestCase(TestDecDefine).runTest()
+ unittest.FunctionTestCase(TestDecInclude).runTest()
+ unittest.FunctionTestCase(TestDecGuidPpiProtocol).runTest()
+ unittest.FunctionTestCase(TestDecPcd).runTest()
+ unittest.FunctionTestCase(TestDecUserExtension).runTest()
+
+ print 'All tests passed...'
+
+
diff --git a/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py b/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py
new file mode 100644
index 0000000000..2f4917525b
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py
@@ -0,0 +1,534 @@
+## @file
+# This file contain unit test for DecParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+import os
+import unittest
+from Logger.Log import FatalError
+
+from Parser.DecParser import \
+ Dec, \
+ _DecDefine, \
+ _DecLibraryclass, \
+ _DecPcd, \
+ _DecGuid, \
+ FileContent, \
+ _DecBase, \
+ CleanString
+
+from Object.Parser.DecObject import _DecComments
+
+#
+# Test CleanString
+#
+class CleanStringTestCase(unittest.TestCase):
+ def testCleanString(self):
+ Line, Comment = CleanString('')
+ self.assertEqual(Line, '')
+ self.assertEqual(Comment, '')
+
+ Line, Comment = CleanString('line without comment')
+ self.assertEqual(Line, 'line without comment')
+ self.assertEqual(Comment, '')
+
+ Line, Comment = CleanString('# pure comment')
+ self.assertEqual(Line, '')
+ self.assertEqual(Comment, '# pure comment')
+
+ Line, Comment = CleanString('line # and comment')
+ self.assertEqual(Line, 'line')
+ self.assertEqual(Comment, '# and comment')
+
+ def testCleanStringCpp(self):
+ Line, Comment = CleanString('line // and comment', AllowCppStyleComment = True)
+ self.assertEqual(Line, 'line')
+ self.assertEqual(Comment, '# and comment')
+
+#
+# Test _DecBase._MacroParser function
+#
+class MacroParserTestCase(unittest.TestCase):
+ def setUp(self):
+ self.dec = _DecBase(FileContent('dummy', []))
+
+ def testCorrectMacro(self):
+ self.dec._MacroParser('DEFINE MARCRO1 = test1')
+ self.failIf('MARCRO1' not in self.dec._LocalMacro)
+ self.assertEqual(self.dec._LocalMacro['MARCRO1'], 'test1')
+
+ def testErrorMacro1(self):
+ # Raise fatal error, macro name must be upper case letter
+ self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE not_upper_case = test2')
+
+ def testErrorMacro2(self):
+ # No macro name given
+ self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE ')
+
+#
+# Test _DecBase._TryBackSlash function
+#
+class TryBackSlashTestCase(unittest.TestCase):
+ def setUp(self):
+ Content = [
+ # Right case
+ 'test no backslash',
+
+ 'test with backslash \\',
+ 'continue second line',
+
+ # Do not precede with whitespace
+ '\\',
+
+ # Empty line after backlash is not allowed
+ 'line with backslash \\',
+ ''
+ ]
+ self.dec = _DecBase(FileContent('dummy', Content))
+
+ def testBackSlash(self):
+ #
+ # Right case, assert return values
+ #
+ ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), [])
+ self.assertEqual(ConcatLine, 'test no backslash')
+ self.assertEqual(CommentList, [])
+
+ ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), [])
+ self.assertEqual(CommentList, [])
+ self.assertEqual(ConcatLine, 'test with backslash continue second line')
+
+ #
+ # Error cases, assert raise exception
+ #
+ self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), [])
+ self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), [])
+
+#
+# Test _DecBase.Parse function
+#
+class DataItem(_DecComments):
+ def __init__(self):
+ _DecComments.__init__(self)
+ self.String = ''
+
+class Data(_DecComments):
+ def __init__(self):
+ _DecComments.__init__(self)
+ # List of DataItem
+ self.ItemList = []
+
+class TestInner(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ self.ItemObject = Data()
+
+ def _StopCurrentParsing(self, Line):
+ return Line == '[TOP]'
+
+ def _ParseItem(self):
+ Item = DataItem()
+ Item.String = self._RawData.CurrentLine
+ self.ItemObject.ItemList.append(Item)
+ return Item
+
+ def _TailCommentStrategy(self, Comment):
+ return Comment.find('@comment') != -1
+
+class TestTop(_DecBase):
+ def __init__(self, RawData):
+ _DecBase.__init__(self, RawData)
+ # List of Data
+ self.ItemObject = []
+
+ # Top parser
+ def _StopCurrentParsing(self, Line):
+ return False
+
+ def _ParseItem(self):
+ TestParser = TestInner(self._RawData)
+ TestParser.Parse()
+ self.ItemObject.append(TestParser.ItemObject)
+ return TestParser.ItemObject
+
+class ParseTestCase(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def testParse(self):
+ Content = \
+ '''# Top comment
+ [TOP]
+ # sub1 head comment
+ (test item has both head and tail comment) # sub1 tail comment
+ # sub2 head comment
+ (test item has head and special tail comment)
+ # @comment test TailCommentStrategy branch
+
+ (test item has no comment)
+
+ # test NextLine branch
+ [TOP]
+ sub-item
+ '''
+ dec = TestTop(FileContent('dummy', Content.splitlines()))
+ dec.Parse()
+
+ # Two sections
+ self.assertEqual(len(dec.ItemObject), 2)
+
+ data = dec.ItemObject[0]
+ self.assertEqual(data._HeadComment[0][0], '# Top comment')
+ self.assertEqual(data._HeadComment[0][1], 1)
+
+ # 3 subitems
+ self.assertEqual(len(data.ItemList), 3)
+
+ dataitem = data.ItemList[0]
+ self.assertEqual(dataitem.String, '(test item has both head and tail comment)')
+ # Comment content
+ self.assertEqual(dataitem._HeadComment[0][0], '# sub1 head comment')
+ self.assertEqual(dataitem._TailComment[0][0], '# sub1 tail comment')
+ # Comment line number
+ self.assertEqual(dataitem._HeadComment[0][1], 3)
+ self.assertEqual(dataitem._TailComment[0][1], 4)
+
+ dataitem = data.ItemList[1]
+ self.assertEqual(dataitem.String, '(test item has head and special tail comment)')
+ # Comment content
+ self.assertEqual(dataitem._HeadComment[0][0], '# sub2 head comment')
+ self.assertEqual(dataitem._TailComment[0][0], '# @comment test TailCommentStrategy branch')
+ # Comment line number
+ self.assertEqual(dataitem._HeadComment[0][1], 5)
+ self.assertEqual(dataitem._TailComment[0][1], 7)
+
+ dataitem = data.ItemList[2]
+ self.assertEqual(dataitem.String, '(test item has no comment)')
+ # Comment content
+ self.assertEqual(dataitem._HeadComment, [])
+ self.assertEqual(dataitem._TailComment, [])
+
+ data = dec.ItemObject[1]
+ self.assertEqual(data._HeadComment[0][0], '# test NextLine branch')
+ self.assertEqual(data._HeadComment[0][1], 11)
+
+ # 1 subitems
+ self.assertEqual(len(data.ItemList), 1)
+
+ dataitem = data.ItemList[0]
+ self.assertEqual(dataitem.String, 'sub-item')
+ self.assertEqual(dataitem._HeadComment, [])
+ self.assertEqual(dataitem._TailComment, [])
+
+#
+# Test _DecDefine._ParseItem
+#
+class DecDefineTestCase(unittest.TestCase):
+ def GetObj(self, Content):
+ Obj = _DecDefine(FileContent('dummy', Content.splitlines()))
+ Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
+ return Obj
+
+ def testDecDefine(self):
+ item = self.GetObj('PACKAGE_NAME = MdePkg')._ParseItem()
+ self.assertEqual(item.Key, 'PACKAGE_NAME')
+ self.assertEqual(item.Value, 'MdePkg')
+
+ def testDecDefine1(self):
+ obj = self.GetObj('PACKAGE_NAME')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testDecDefine2(self):
+ obj = self.GetObj('unknown_key = ')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testDecDefine3(self):
+ obj = self.GetObj('PACKAGE_NAME = ')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+#
+# Test _DecLibraryclass._ParseItem
+#
+class DecLibraryTestCase(unittest.TestCase):
+ def GetObj(self, Content):
+ Obj = _DecLibraryclass(FileContent('dummy', Content.splitlines()))
+ Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
+ return Obj
+
+ def testNoInc(self):
+ obj = self.GetObj('UefiRuntimeLib')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testEmpty(self):
+ obj = self.GetObj(' | ')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testLibclassNaming(self):
+ obj = self.GetObj('lowercase_efiRuntimeLib|Include/Library/UefiRuntimeLib.h')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testLibclassExt(self):
+ obj = self.GetObj('RuntimeLib|Include/Library/UefiRuntimeLib.no_h')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testLibclassRelative(self):
+ obj = self.GetObj('RuntimeLib|Include/../UefiRuntimeLib.h')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+#
+# Test _DecPcd._ParseItem
+#
+class DecPcdTestCase(unittest.TestCase):
+ def GetObj(self, Content):
+ Obj = _DecPcd(FileContent('dummy', Content.splitlines()))
+ Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
+ Obj._RawData.CurrentScope = [('PcdsFeatureFlag'.upper(), 'COMMON')]
+ return Obj
+
+ def testOK(self):
+ item = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d')._ParseItem()
+ self.assertEqual(item.TokenSpaceGuidCName, 'gEfiMdePkgTokenSpaceGuid')
+ self.assertEqual(item.TokenCName, 'PcdComponentNameDisable')
+ self.assertEqual(item.DefaultValue, 'FALSE')
+ self.assertEqual(item.DatumType, 'BOOLEAN')
+ self.assertEqual(item.TokenValue, '0x0000000d')
+
+ def testNoCvar(self):
+ obj = self.GetObj('123ai.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testSplit(self):
+ obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable FALSE|BOOLEAN|0x0000000d')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d | abc')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testUnknownType(self):
+ obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|unknown|0x0000000d')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testVoid(self):
+ obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|abc|VOID*|0x0000000d')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testUINT(self):
+ obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|0xabc|UINT8|0x0000000d')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+#
+# Test _DecInclude._ParseItem
+#
+class DecIncludeTestCase(unittest.TestCase):
+ #
+ # Test code to be added
+ #
+ pass
+
+#
+# Test _DecGuid._ParseItem
+#
+class DecGuidTestCase(unittest.TestCase):
+ def GetObj(self, Content):
+ Obj = _DecGuid(FileContent('dummy', Content.splitlines()))
+ Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
+ Obj._RawData.CurrentScope = [('guids'.upper(), 'COMMON')]
+ return Obj
+
+ def testCValue(self):
+ item = self.GetObj('gEfiIpSecProtocolGuid={ 0xdfb386f7, 0xe100, 0x43ad,'
+ ' {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}')._ParseItem()
+ self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid')
+ self.assertEqual(item.GuidCValue, '{ 0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}')
+
+ def testGuidString(self):
+ item = self.GetObj('gEfiIpSecProtocolGuid=1E73767F-8F52-4603-AEB4-F29B510B6766')._ParseItem()
+ self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid')
+ self.assertEqual(item.GuidCValue, '1E73767F-8F52-4603-AEB4-F29B510B6766')
+
+ def testNoValue1(self):
+ obj = self.GetObj('gEfiIpSecProtocolGuid')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testNoValue2(self):
+ obj = self.GetObj('gEfiIpSecProtocolGuid=')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+ def testNoName(self):
+ obj = self.GetObj('=')
+ self.assertRaises(FatalError, obj._ParseItem)
+
+#
+# Test Dec.__init__
+#
+class DecDecInitTestCase(unittest.TestCase):
+ def testNoDecFile(self):
+ self.assertRaises(FatalError, Dec, 'No_Such_File')
+
+class TmpFile:
+ def __init__(self, File):
+ self.File = File
+
+ def Write(self, Content):
+ try:
+ FileObj = open(self.File, 'w')
+ FileObj.write(Content)
+ FileObj.close()
+ except:
+ pass
+
+ def Remove(self):
+ try:
+ os.remove(self.File)
+ except:
+ pass
+
+#
+# Test Dec._UserExtentionSectionParser
+#
+class DecUESectionTestCase(unittest.TestCase):
+ def setUp(self):
+ self.File = TmpFile('test.dec')
+ self.File.Write(
+'''[userextensions.intel."myid"]
+[userextensions.intel."myid".IA32]
+[userextensions.intel."myid".IA32,]
+[userextensions.intel."myid]
+'''
+ )
+
+ def tearDown(self):
+ self.File.Remove()
+
+ def testUserExtentionHeader(self):
+ dec = Dec('test.dec', False)
+
+ # OK: [userextensions.intel."myid"]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ dec._UserExtentionSectionParser()
+ self.assertEqual(len(dec._RawData.CurrentScope), 1)
+ self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper())
+ self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel')
+ self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"')
+ self.assertEqual(dec._RawData.CurrentScope[0][3], 'COMMON')
+
+ # OK: [userextensions.intel."myid".IA32]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ dec._UserExtentionSectionParser()
+ self.assertEqual(len(dec._RawData.CurrentScope), 1)
+ self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper())
+ self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel')
+ self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"')
+ self.assertEqual(dec._RawData.CurrentScope[0][3], 'IA32')
+
+ # Fail: [userextensions.intel."myid".IA32,]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._UserExtentionSectionParser)
+
+ # Fail: [userextensions.intel."myid]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._UserExtentionSectionParser)
+
+#
+# Test Dec._SectionHeaderParser
+#
+class DecSectionTestCase(unittest.TestCase):
+ def setUp(self):
+ self.File = TmpFile('test.dec')
+ self.File.Write(
+'''[no section start or end
+[,] # empty sub-section
+[unknow_section_name]
+[Includes.IA32.other] # no third one
+[PcdsFeatureFlag, PcdsFixedAtBuild] # feature flag PCD must not be in the same section of other types of PCD
+[Includes.IA32, Includes.IA32]
+[Includes, Includes.IA32] # common cannot be with other arch
+[Includes.IA32, PcdsFeatureFlag] # different section name
+''' )
+
+ def tearDown(self):
+ self.File.Remove()
+
+ def testSectionHeader(self):
+ dec = Dec('test.dec', False)
+ # [no section start or end
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+ #[,] # empty sub-section
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+ # [unknow_section_name]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+ # [Includes.IA32.other] # no third one
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+ # [PcdsFeatureFlag, PcdsFixedAtBuild]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+ # [Includes.IA32, Includes.IA32]
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ dec._SectionHeaderParser()
+ self.assertEqual(len(dec._RawData.CurrentScope), 1)
+ self.assertEqual(dec._RawData.CurrentScope[0][0], 'Includes'.upper())
+ self.assertEqual(dec._RawData.CurrentScope[0][1], 'IA32')
+
+ # [Includes, Includes.IA32] # common cannot be with other arch
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+ # [Includes.IA32, PcdsFeatureFlag] # different section name not allowed
+ dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
+ self.assertRaises(FatalError, dec._SectionHeaderParser)
+
+#
+# Test Dec._ParseDecComment
+#
+class DecDecCommentTestCase(unittest.TestCase):
+ def testDecHeadComment(self):
+ File = TmpFile('test.dec')
+ File.Write(
+ '''# abc
+ ##''')
+ dec = Dec('test.dec', False)
+ dec.ParseDecComment()
+ self.assertEqual(len(dec._HeadComment), 2)
+ self.assertEqual(dec._HeadComment[0][0], '# abc')
+ self.assertEqual(dec._HeadComment[0][1], 1)
+ self.assertEqual(dec._HeadComment[1][0], '##')
+ self.assertEqual(dec._HeadComment[1][1], 2)
+ File.Remove()
+
+ def testNoDoubleComment(self):
+ File = TmpFile('test.dec')
+ File.Write(
+ '''# abc
+ #
+ [section_start]''')
+ dec = Dec('test.dec', False)
+ dec.ParseDecComment()
+ self.assertEqual(len(dec._HeadComment), 2)
+ self.assertEqual(dec._HeadComment[0][0], '# abc')
+ self.assertEqual(dec._HeadComment[0][1], 1)
+ self.assertEqual(dec._HeadComment[1][0], '#')
+ self.assertEqual(dec._HeadComment[1][1], 2)
+ File.Remove()
+
+if __name__ == '__main__':
+ import Logger.Logger
+ Logger.Logger.Initialize()
+ unittest.main()
+
diff --git a/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py b/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
new file mode 100644
index 0000000000..f3b43ee0bc
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/UnitTest/InfBinarySectionTest.py
@@ -0,0 +1,386 @@
+## @file
+# This file contain unit test for Test [Binary] section part of InfParser
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+import os
+#import Object.Parser.InfObject as InfObject
+from Object.Parser.InfCommonObject import CurrentLine
+from Object.Parser.InfCommonObject import InfLineCommentObject
+from Object.Parser.InfBinaryObject import InfBinariesObject
+import Logger.Log as Logger
+import Library.GlobalData as Global
+##
+# Test Common binary item
+#
+
+#-------------start of common binary item test input--------------------------#
+
+#
+# Only has 1 element, binary item Type
+#
+SectionStringsCommonItem1 = \
+"""
+GUID
+"""
+#
+# Have 2 elements, binary item Type and FileName
+#
+SectionStringsCommonItem2 = \
+"""
+GUID | Test/Test.guid
+"""
+
+#
+# Have 3 elements, Type | FileName | Target | Family | TagName | FeatureFlagExp
+#
+SectionStringsCommonItem3 = \
+"""
+GUID | Test/Test.guid | DEBUG
+"""
+
+#
+# Have 3 elements, Type | FileName | Target
+# Target with MACRO defined in [Define] section
+#
+SectionStringsCommonItem4 = \
+"""
+GUID | Test/Test.guid | $(TARGET)
+"""
+
+#
+# Have 3 elements, Type | FileName | Target
+# FileName with MACRO defined in [Binary] section
+#
+SectionStringsCommonItem5 = \
+"""
+DEFINE BINARY_FILE_PATH = Test
+GUID | $(BINARY_FILE_PATH)/Test.guid | $(TARGET)
+"""
+
+#
+# Have 4 elements, Type | FileName | Target | Family
+#
+SectionStringsCommonItem6 = \
+"""
+GUID | Test/Test.guid | DEBUG | *
+"""
+
+#
+# Have 4 elements, Type | FileName | Target | Family
+#
+SectionStringsCommonItem7 = \
+"""
+GUID | Test/Test.guid | DEBUG | MSFT
+"""
+
+#
+# Have 5 elements, Type | FileName | Target | Family | TagName
+#
+SectionStringsCommonItem8 = \
+"""
+GUID | Test/Test.guid | DEBUG | MSFT | TEST
+"""
+
+#
+# Have 6 elements, Type | FileName | Target | Family | TagName | FFE
+#
+SectionStringsCommonItem9 = \
+"""
+GUID | Test/Test.guid | DEBUG | MSFT | TEST | TRUE
+"""
+
+#
+# Have 7 elements, Type | FileName | Target | Family | TagName | FFE | Overflow
+# Test wrong format
+#
+SectionStringsCommonItem10 = \
+"""
+GUID | Test/Test.guid | DEBUG | MSFT | TEST | TRUE | OVERFLOW
+"""
+
+#-------------end of common binary item test input----------------------------#
+
+
+
+#-------------start of VER type binary item test input------------------------#
+
+#
+# Has 1 element, error format
+#
+SectionStringsVerItem1 = \
+"""
+VER
+"""
+#
+# Have 5 elements, error format(Maximum elements amount is 4)
+#
+SectionStringsVerItem2 = \
+"""
+VER | Test/Test.ver | * | TRUE | OverFlow
+"""
+
+#
+# Have 2 elements, Type | FileName
+#
+SectionStringsVerItem3 = \
+"""
+VER | Test/Test.ver
+"""
+
+#
+# Have 3 elements, Type | FileName | Target
+#
+SectionStringsVerItem4 = \
+"""
+VER | Test/Test.ver | DEBUG
+"""
+
+#
+# Have 4 elements, Type | FileName | Target | FeatureFlagExp
+#
+SectionStringsVerItem5 = \
+"""
+VER | Test/Test.ver | DEBUG | TRUE
+"""
+
+#
+# Exist 2 VER items, both opened.
+#
+SectionStringsVerItem6 = \
+"""
+VER | Test/Test.ver | * | TRUE
+VER | Test/Test2.ver | * | TRUE
+"""
+
+
+#
+# Exist 2 VER items, only 1 opened.
+#
+SectionStringsVerItem7 = \
+"""
+VER | Test/Test.ver | * | TRUE
+VER | Test/Test2.ver | * | FALSE
+"""
+
+#-------------end of VER type binary item test input--------------------------#
+
+
+#-------------start of UI type binary item test input-------------------------#
+
+#
+# Test only one UI section can exist
+#
+SectionStringsUiItem1 = \
+"""
+UI | Test/Test.ui | * | TRUE
+UI | Test/Test2.ui | * | TRUE
+"""
+
+SectionStringsUiItem2 = \
+"""
+UI | Test/Test.ui | * | TRUE
+SEC_UI | Test/Test2.ui | * | TRUE
+"""
+
+SectionStringsUiItem3 = \
+"""
+UI | Test/Test.ui | * | TRUE
+UI | Test/Test2.ui | * | FALSE
+"""
+
+#
+# Has 1 element, error format
+#
+SectionStringsUiItem4 = \
+"""
+UI
+"""
+#
+# Have 5 elements, error format(Maximum elements amount is 4)
+#
+SectionStringsUiItem5 = \
+"""
+UI | Test/Test.ui | * | TRUE | OverFlow
+"""
+
+#
+# Have 2 elements, Type | FileName
+#
+SectionStringsUiItem6 = \
+"""
+UI | Test/Test.ui
+"""
+
+#
+# Have 3 elements, Type | FileName | Target
+#
+SectionStringsUiItem7 = \
+"""
+UI | Test/Test.ui | DEBUG
+"""
+
+#
+# Have 4 elements, Type | FileName | Target | FeatureFlagExp
+#
+SectionStringsUiItem8 = \
+"""
+UI | Test/Test.ui | DEBUG | TRUE
+"""
+#---------------end of UI type binary item test input-------------------------#
+
+
+gFileName = "BinarySectionTest.inf"
+
+##
+# Construct SectionString for call section parser usage.
+#
+def StringToSectionString(String):
+ Lines = String.split('\n')
+ LineNo = 0
+ SectionString = []
+ for Line in Lines:
+ if Line.strip() == '':
+ continue
+ SectionString.append((Line, LineNo, ''))
+ LineNo = LineNo + 1
+
+ return SectionString
+
+def PrepareTest(String):
+ SectionString = StringToSectionString(String)
+ ItemList = []
+ for Item in SectionString:
+ ValueList = Item[0].split('|')
+ for count in range(len(ValueList)):
+ ValueList[count] = ValueList[count].strip()
+ if len(ValueList) >= 2:
+ #
+ # Create a temp file for test.
+ #
+ FileName = os.path.normpath(os.path.realpath(ValueList[1].strip()))
+ try:
+ TempFile = open (FileName, "w")
+ TempFile.close()
+ except:
+ print "File Create Error"
+ CurrentLine = CurrentLine()
+ CurrentLine.SetFileName("Test")
+ CurrentLine.SetLineString(Item[0])
+ CurrentLine.SetLineNo(Item[1])
+ InfLineCommentObject = InfLineCommentObject()
+
+ ItemList.append((ValueList, InfLineCommentObject, CurrentLine))
+
+ return ItemList
+
+if __name__ == '__main__':
+ Logger.Initialize()
+
+ InfBinariesInstance = InfBinariesObject()
+ ArchList = ['COMMON']
+ Global.gINF_MODULE_DIR = os.getcwd()
+
+ AllPassedFlag = True
+
+ #
+ # For All Ui test
+ #
+ UiStringList = [
+ SectionStringsUiItem1,
+ SectionStringsUiItem2,
+ SectionStringsUiItem3,
+ SectionStringsUiItem4,
+ SectionStringsUiItem5,
+ SectionStringsUiItem6,
+ SectionStringsUiItem7,
+ SectionStringsUiItem8
+ ]
+
+ for Item in UiStringList:
+ Ui = PrepareTest(Item)
+ if Item == SectionStringsUiItem4 or Item == SectionStringsUiItem5:
+ try:
+ InfBinariesInstance.SetBinary(Ui = Ui, ArchList = ArchList)
+ except Logger.FatalError:
+ pass
+ else:
+ try:
+ InfBinariesInstance.SetBinary(Ui = Ui, ArchList = ArchList)
+ except:
+ AllPassedFlag = False
+
+ #
+ # For All Ver Test
+ #
+ VerStringList = [
+ SectionStringsVerItem1,
+ SectionStringsVerItem2,
+ SectionStringsVerItem3,
+ SectionStringsVerItem4,
+ SectionStringsVerItem5,
+ SectionStringsVerItem6,
+ SectionStringsVerItem7
+ ]
+ for Item in VerStringList:
+ Ver = PrepareTest(Item)
+ if Item == SectionStringsVerItem1 or \
+ Item == SectionStringsVerItem2:
+
+ try:
+ InfBinariesInstance.SetBinary(Ver = Ver, ArchList = ArchList)
+ except:
+ pass
+
+ else:
+ try:
+ InfBinariesInstance.SetBinary(Ver = Ver, ArchList = ArchList)
+ except:
+ AllPassedFlag = False
+
+ #
+ # For All Common Test
+ #
+ CommonStringList = [
+ SectionStringsCommonItem1,
+ SectionStringsCommonItem2,
+ SectionStringsCommonItem3,
+ SectionStringsCommonItem4,
+ SectionStringsCommonItem5,
+ SectionStringsCommonItem6,
+ SectionStringsCommonItem7,
+ SectionStringsCommonItem8,
+ SectionStringsCommonItem9,
+ SectionStringsCommonItem10
+ ]
+
+ for Item in CommonStringList:
+ CommonBin = PrepareTest(Item)
+ if Item == SectionStringsCommonItem10 or \
+ Item == SectionStringsCommonItem1:
+
+ try:
+ InfBinariesInstance.SetBinary(CommonBinary = CommonBin, ArchList = ArchList)
+ except:
+ pass
+
+ else:
+ try:
+ InfBinariesInstance.SetBinary(Ver = Ver, ArchList = ArchList)
+ except:
+ print "Test Failed!"
+ AllPassedFlag = False
+
+ if AllPassedFlag :
+ print 'All tests passed...'
+ else:
+ print 'Some unit test failed!'
+
diff --git a/BaseTools/Source/Python/UPT/Xml/CommonXml.py b/BaseTools/Source/Python/UPT/Xml/CommonXml.py
new file mode 100644
index 0000000000..fff6e6772e
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/CommonXml.py
@@ -0,0 +1,879 @@
+## @file
+# This file is used to parse a PCD file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+CommonXml
+'''
+
+##
+# Import Modules
+#
+
+from Core.DistributionPackageClass import DistributionPackageHeaderObject
+from Library.String import ConvertNEToNOTEQ
+from Library.String import ConvertNOTEQToNE
+from Library.String import GetSplitValueList
+from Library.String import GetStringOfList
+from Library.Xml.XmlRoutines import XmlElement
+from Library.Xml.XmlRoutines import XmlElement2
+from Library.Xml.XmlRoutines import XmlAttribute
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import XmlList
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Object.POM.CommonObject import FileObject
+from Object.POM.CommonObject import MiscFileObject
+from Object.POM.CommonObject import UserExtensionObject
+from Object.POM.CommonObject import ClonedRecordObject
+from Object.POM.CommonObject import LibraryClassObject
+from Object.POM.CommonObject import FileNameObject
+from Object.POM.ModuleObject import ModuleObject
+from Xml.XmlParserMisc import IsRequiredItemListNull
+from Xml.XmlParserMisc import GetHelpTextList
+
+import Library.DataType as DataType
+
+##
+# ClonedFromXml
+#
+class ClonedFromXml(object):
+ def __init__(self):
+ self.GUID = ''
+ self.Version = ''
+
+ def FromXml(self, Item, Key):
+ self.GUID = XmlElement(Item, '%s/GUID' % Key)
+ self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version')
+
+ if self.GUID == '' and self.Version == '':
+ return None
+
+ ClonedFrom = ClonedRecordObject()
+ ClonedFrom.SetPackageGuid(self.GUID)
+ ClonedFrom.SetPackageVersion(self.Version)
+
+ return ClonedFrom
+
+ def ToXml(self, ClonedFrom, Key):
+ if self.GUID:
+ pass
+ Element1 = CreateXmlElement('GUID', ClonedFrom.GetPackageGuid(), [],
+ [['Version', ClonedFrom.GetPackageVersion()]])
+ AttributeList = []
+ NodeList = [Element1]
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ return "GUID = %s Version = %s" % (self.GUID, self.Version)
+
+
+##
+# CommonDefinesXml
+#
+class CommonDefinesXml(object):
+ def __init__(self):
+ self.Usage = ''
+ self.SupArchList = []
+ self.SupModList = []
+ self.FeatureFlag = ''
+
+ def FromXml(self, Item, Key):
+ if Key:
+ pass
+ self.Usage = XmlAttribute(Item, 'Usage')
+ self.SupArchList = \
+ [Arch for Arch in GetSplitValueList(XmlAttribute(Item, 'SupArchList'), DataType.TAB_SPACE_SPLIT) if Arch]
+ self.SupModList = \
+ [Mod for Mod in GetSplitValueList(XmlAttribute(Item, 'SupModList'), DataType.TAB_SPACE_SPLIT) if Mod]
+ self.FeatureFlag = ConvertNOTEQToNE(XmlAttribute(Item, 'FeatureFlag'))
+
+
+ def ToXml(self):
+ pass
+
+ def __str__(self):
+ return "Usage = %s SupArchList = %s SupModList = %s FeatureFlag = %s" \
+ % (self.Usage, self.SupArchList, self.SupModList, self.FeatureFlag)
+
+
+##
+# HelpTextXml
+#
+class HelpTextXml(object):
+ def __init__(self):
+ self.HelpText = ''
+ self.Lang = ''
+
+ def FromXml(self, Item, Key):
+ if Key:
+ pass
+ self.HelpText = XmlElement2(Item, 'HelpText')
+ self.Lang = XmlAttribute(Item, 'Lang')
+
+ def ToXml(self, HelpText, Key='HelpText'):
+ if self.HelpText:
+ pass
+ return CreateXmlElement('%s' % Key, HelpText.GetString(), [], [['Lang', HelpText.GetLang()]])
+ def __str__(self):
+ return "HelpText = %s Lang = %s" % (self.HelpText, self.Lang)
+
+##
+# HeaderXml
+#
+class HeaderXml(object):
+ def __init__(self):
+ self.Name = ''
+ self.BaseName = ''
+ self.GUID = ''
+ self.Version = ''
+ self.Copyright = ''
+ self.License = ''
+ self.Abstract = ''
+ self.Description = ''
+
+ def FromXml(self, Item, Key, IsRequiredCheck=False, IsStandAlongModule=False):
+ if not Item and IsRequiredCheck:
+ XmlTreeLevel = []
+ if IsStandAlongModule:
+ XmlTreeLevel = ['DistributionPackage', 'ModuleSurfaceArea']
+ else:
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ModuleSurfaceArea']
+ CheckDict = {'Header':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ self.Name = XmlElement(Item, '%s/Name' % Key)
+ self.BaseName = XmlAttribute(XmlNode(Item, '%s/Name' % Key), 'BaseName')
+ self.GUID = XmlElement(Item, '%s/GUID' % Key)
+ self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version')
+ self.Copyright = XmlElement(Item, '%s/Copyright' % Key)
+ self.License = XmlElement(Item, '%s/License' % Key)
+ self.Abstract = XmlElement(Item, '%s/Abstract' % Key)
+ self.Description = XmlElement(Item, '%s/Description' % Key)
+
+ ModuleHeader = ModuleObject()
+ ModuleHeader.SetName(self.Name)
+ ModuleHeader.SetBaseName(self.BaseName)
+ ModuleHeader.SetGuid(self.GUID)
+ ModuleHeader.SetVersion(self.Version)
+ ModuleHeader.SetCopyright(self.Copyright)
+ ModuleHeader.SetLicense(self.License)
+ ModuleHeader.SetAbstract(self.Abstract)
+ ModuleHeader.SetDescription(self.Description)
+
+ return ModuleHeader
+
+ def ToXml(self, Header, Key):
+ if self.GUID:
+ pass
+ Element1 = CreateXmlElement('Name', Header.GetName(), [], [['BaseName', Header.GetBaseName()]])
+ Element2 = CreateXmlElement('GUID', Header.GetGuid(), [], [['Version', Header.GetVersion()]])
+ AttributeList = []
+ NodeList = [Element1,
+ Element2,
+ ['Copyright', Header.GetCopyright()],
+ ['License', Header.GetLicense()],
+ ['Abstract', Header.GetAbstract()],
+ ['Description', Header.GetDescription()],
+ ]
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ return "Name = %s BaseName = %s GUID = %s Version = %s Copyright = %s \
+ License = %s Abstract = %s Description = %s" % \
+ (self.Name, self.BaseName, self.GUID, self.Version, self.Copyright, \
+ self.License, self.Abstract, self.Description)
+##
+# DistributionPackageHeaderXml
+#
+class DistributionPackageHeaderXml(object):
+ def __init__(self):
+ self.Header = HeaderXml()
+ self.ReadOnly = ''
+ self.RePackage = ''
+ self.Vendor = ''
+ self.Date = ''
+ self.Signature = ''
+ self.XmlSpecification = ''
+
+ def FromXml(self, Item, Key):
+ if not Item:
+ return None
+ self.ReadOnly = XmlAttribute(XmlNode(Item, '%s' % Key), 'ReadOnly')
+ self.RePackage = XmlAttribute(XmlNode(Item, '%s' % Key), 'RePackage')
+ self.Vendor = XmlElement(Item, '%s/Vendor' % Key)
+ self.Date = XmlElement(Item, '%s/Date' % Key)
+ self.Signature = XmlElement(Item, '%s/Signature' % Key)
+ self.XmlSpecification = XmlElement(Item, '%s/XmlSpecification' % Key)
+ self.Header.FromXml(Item, Key)
+
+ DistributionPackageHeader = DistributionPackageHeaderObject()
+ if self.ReadOnly.upper() == 'TRUE':
+ DistributionPackageHeader.ReadOnly = True
+ elif self.ReadOnly.upper() == 'FALSE':
+ DistributionPackageHeader.ReadOnly = False
+
+ if self.RePackage.upper() == 'TRUE':
+ DistributionPackageHeader.RePackage = True
+ elif self.RePackage.upper() == 'FALSE':
+ DistributionPackageHeader.RePackage = False
+ DistributionPackageHeader.Vendor = self.Vendor
+ DistributionPackageHeader.Date = self.Date
+ DistributionPackageHeader.Signature = self.Signature
+ DistributionPackageHeader.XmlSpecification = self.XmlSpecification
+
+ DistributionPackageHeader.SetName(self.Header.Name)
+ DistributionPackageHeader.SetBaseName(self.Header.BaseName)
+ DistributionPackageHeader.SetGuid(self.Header.GUID)
+ DistributionPackageHeader.SetVersion(self.Header.Version)
+ DistributionPackageHeader.SetCopyright(self.Header.Copyright)
+ DistributionPackageHeader.SetLicense(self.Header.License)
+ DistributionPackageHeader.SetAbstract(self.Header.Abstract)
+ DistributionPackageHeader.SetDescription(self.Header.Description)
+
+ return DistributionPackageHeader
+
+ def ToXml(self, DistributionPackageHeader, Key):
+ if self.Header:
+ pass
+ Element1 = CreateXmlElement('Name', \
+ DistributionPackageHeader.GetName(), [], \
+ [['BaseName', \
+ DistributionPackageHeader.GetBaseName()]])
+ Element2 = CreateXmlElement('GUID', \
+ DistributionPackageHeader.GetGuid(), [], \
+ [['Version', \
+ DistributionPackageHeader.GetVersion()]])
+ AttributeList = []
+ if DistributionPackageHeader.ReadOnly != '':
+ AttributeList.append(['ReadOnly', str(DistributionPackageHeader.ReadOnly).lower()])
+ if DistributionPackageHeader.RePackage != '':
+ AttributeList.append(['RePackage', str(DistributionPackageHeader.RePackage).lower()])
+
+ NodeList = [Element1,
+ Element2,
+ ['Vendor', DistributionPackageHeader.Vendor],
+ ['Date', DistributionPackageHeader.Date],
+ ['Copyright', DistributionPackageHeader.GetCopyright()],
+ ['License', DistributionPackageHeader.GetLicense()],
+ ['Abstract', DistributionPackageHeader.GetAbstract()],
+ ['Description', \
+ DistributionPackageHeader.GetDescription()],
+ ['Signature', DistributionPackageHeader.Signature],
+ ['XmlSpecification', \
+ DistributionPackageHeader.XmlSpecification],
+ ]
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ return "ReadOnly = %s RePackage = %s Vendor = %s Date = %s \
+ Signature = %s XmlSpecification = %s %s" % \
+ (self.ReadOnly, self.RePackage, self.Vendor, self.Date, \
+ self.Signature, self.XmlSpecification, self.Header)
+##
+# PackageHeaderXml
+#
+class PackageHeaderXml(object):
+ def __init__(self):
+ self.Header = HeaderXml()
+ self.PackagePath = ''
+
+ def FromXml(self, Item, Key, PackageObject2):
+ if not Item:
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea']
+ CheckDict = {'PackageHeader':None, }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ self.PackagePath = XmlElement(Item, '%s/PackagePath' % Key)
+ self.Header.FromXml(Item, Key)
+
+ PackageObject2.SetName(self.Header.Name)
+ PackageObject2.SetBaseName(self.Header.BaseName)
+ PackageObject2.SetGuid(self.Header.GUID)
+ PackageObject2.SetVersion(self.Header.Version)
+ PackageObject2.SetCopyright(self.Header.Copyright)
+ PackageObject2.SetLicense(self.Header.License)
+ PackageObject2.SetAbstract(self.Header.Abstract)
+ PackageObject2.SetDescription(self.Header.Description)
+ PackageObject2.SetPackagePath(self.PackagePath)
+
+ def ToXml(self, PackageObject2, Key):
+ if self.PackagePath:
+ pass
+ Element1 = \
+ CreateXmlElement('Name', PackageObject2.GetName(), [], \
+ [['BaseName', PackageObject2.GetBaseName()]])
+ Element2 = CreateXmlElement('GUID', PackageObject2.GetGuid(), [], \
+ [['Version', PackageObject2.GetVersion()]])
+ AttributeList = []
+ NodeList = [Element1,
+ Element2,
+ ['Copyright', PackageObject2.GetCopyright()],
+ ['License', PackageObject2.GetLicense()],
+ ['Abstract', PackageObject2.GetAbstract()],
+ ['Description', PackageObject2.GetDescription()],
+ ['PackagePath', PackageObject2.GetPackagePath()],
+ ]
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ return "PackagePath = %s %s" \
+ % (self.PackagePath, self.Header)
+
+##
+# MiscellaneousFileXml
+#
+class MiscellaneousFileXml(object):
+ def __init__(self):
+ self.Header = HeaderXml()
+ self.Files = []
+ ##
+ # This API is used for Package or Module's MiscellaneousFile section
+ #
+ def FromXml(self, Item, Key):
+ if not Item:
+ return None
+ self.Header.FromXml(Item, Key)
+ NewItem = XmlNode(Item, '%s/Header' % Key)
+ self.Header.FromXml(NewItem, 'Header')
+
+ for SubItem in XmlList(Item, '%s/Filename' % Key):
+ Filename = XmlElement(SubItem, '%s/Filename' % Key)
+ Executable = XmlAttribute(XmlNode(SubItem, '%s/Filename' % Key), 'Executable')
+ if Executable.upper() == "TRUE":
+ Executable = True
+ else:
+ Executable = False
+ self.Files.append([Filename, Executable])
+
+ MiscFile = MiscFileObject()
+ MiscFile.SetCopyright(self.Header.Copyright)
+ MiscFile.SetLicense(self.Header.License)
+ MiscFile.SetAbstract(self.Header.Abstract)
+ MiscFile.SetDescription(self.Header.Description)
+ MiscFileList = []
+ for File in self.Files:
+ FileObj = FileObject()
+ FileObj.SetURI(File[0])
+ FileObj.SetExecutable(File[1])
+ MiscFileList.append(FileObj)
+ MiscFile.SetFileList(MiscFileList)
+
+ return MiscFile
+ ##
+ # This API is used for DistP's tool section
+ #
+ def FromXml2(self, Item, Key):
+ if Item is None:
+ return None
+
+ NewItem = XmlNode(Item, '%s/Header' % Key)
+ self.Header.FromXml(NewItem, 'Header')
+
+ for SubItem in XmlList(Item, '%s/Filename' % Key):
+ Filename = XmlElement(SubItem, '%s/Filename' % Key)
+ Executable = \
+ XmlAttribute(XmlNode(SubItem, '%s/Filename' % Key), 'Executable')
+ OsType = XmlAttribute(XmlNode(SubItem, '%s/Filename' % Key), 'OS')
+ if Executable.upper() == "TRUE":
+ Executable = True
+ else:
+ Executable = False
+ self.Files.append([Filename, Executable, OsType])
+
+ MiscFile = MiscFileObject()
+ MiscFile.SetName(self.Header.Name)
+ MiscFile.SetCopyright(self.Header.Copyright)
+ MiscFile.SetLicense(self.Header.License)
+ MiscFile.SetAbstract(self.Header.Abstract)
+ MiscFile.SetDescription(self.Header.Description)
+ MiscFileList = []
+ for File in self.Files:
+ FileObj = FileObject()
+ FileObj.SetURI(File[0])
+ FileObj.SetExecutable(File[1])
+ FileObj.SetOS(File[2])
+ MiscFileList.append(FileObj)
+ MiscFile.SetFileList(MiscFileList)
+
+ return MiscFile
+
+ ##
+ # This API is used for Package or Module's MiscellaneousFile section
+ #
+ def ToXml(self, MiscFile, Key):
+ if self.Header:
+ pass
+ if MiscFile:
+ NodeList = [['Copyright', MiscFile.GetCopyright()],
+ ['License', MiscFile.GetLicense()],
+ ['Abstract', MiscFile.GetAbstract()],
+ ['Description', MiscFile.GetDescription()],
+ ]
+
+ for File in MiscFile.GetFileList():
+ NodeList.append\
+ (CreateXmlElement\
+ ('Filename', File.GetURI(), [], \
+ [['Executable', str(File.GetExecutable()).lower()]]))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, [])
+
+ return Root
+ ##
+ # This API is used for DistP's tool section
+ #
+ def ToXml2(self, MiscFile, Key):
+ if self.Header:
+ pass
+ if MiscFile:
+ NodeList = [['Name', MiscFile.GetName()],
+ ['Copyright', MiscFile.GetCopyright()],
+ ['License', MiscFile.GetLicense()],
+ ['Abstract', MiscFile.GetAbstract()],
+ ['Description', MiscFile.GetDescription()],
+ ]
+ HeaderNode = CreateXmlElement('Header', '', NodeList, [])
+ NodeList = [HeaderNode]
+
+ for File in MiscFile.GetFileList():
+ NodeList.append\
+ (CreateXmlElement\
+ ('Filename', File.GetURI(), [], \
+ [['Executable', str(File.GetExecutable()).lower()], \
+ ['OS', File.GetOS()]]))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, [])
+
+ return Root
+
+ def __str__(self):
+ Str = str(self.Header)
+ for Item in self.Files:
+ Str = Str + '\n\tFilename:' + str(Item)
+ return Str
+##
+# UserExtensionsXml
+#
+class UserExtensionsXml(object):
+ def __init__(self):
+ self.UserId = ''
+ self.Identifier = ''
+ self.DefineDict = {}
+ self.BuildOptionDict = {}
+ self.IncludesDict = {}
+ self.SourcesDict = {}
+ self.BinariesDict = {}
+ self.SupArchList = []
+ self.Statement = ''
+ self.Defines = ''
+ self.BuildOptions = ''
+
+ def FromXml2(self, Item, Key):
+ self.UserId = XmlAttribute(XmlNode(Item, '%s' % Key), 'UserId')
+ self.Identifier = XmlAttribute(XmlNode(Item, '%s' % Key), 'Identifier')
+
+ UserExtension = UserExtensionObject()
+ UserExtension.SetUserID(self.UserId)
+ UserExtension.SetIdentifier(self.Identifier)
+
+ return UserExtension
+
+ def FromXml(self, Item, Key):
+ self.UserId = XmlAttribute(XmlNode(Item, '%s' % Key), 'UserId')
+ self.Identifier = XmlAttribute(XmlNode(Item, '%s' % Key), 'Identifier')
+
+ DefineItem = XmlNode(Item, '%s/Define' % Key)
+ for SubItem in XmlList(DefineItem, 'Define/Statement'):
+ Statement = XmlElement(SubItem, '%s/Statement' % Key)
+ self.DefineDict[Statement] = ""
+
+ BuildOptionItem = XmlNode(Item, '%s/BuildOption' % Key)
+ for SubItem in XmlList(BuildOptionItem, 'BuildOption/Statement'):
+ Statement = XmlElement(SubItem, '%s/Statement' % Key)
+ Arch = XmlAttribute(XmlNode(SubItem, '%s/Statement' % Key), 'SupArchList')
+ self.BuildOptionDict[Arch] = Statement
+
+ IncludesItem = XmlNode(Item, '%s/Includes' % Key)
+ for SubItem in XmlList(IncludesItem, 'Includes/Statement'):
+ Statement = XmlElement(SubItem, '%s/Statement' % Key)
+ Arch = XmlAttribute(XmlNode(SubItem, '%s/Statement' % Key), 'SupArchList')
+ self.IncludesDict[Statement] = Arch
+
+ SourcesItem = XmlNode(Item, '%s/Sources' % Key)
+ Tmp = UserExtensionSourceXml()
+ SourceDict = Tmp.FromXml(SourcesItem, 'Sources')
+ self.SourcesDict = SourceDict
+
+ BinariesItem = XmlNode(Item, '%s/Binaries' % Key)
+ Tmp = UserExtensionBinaryXml()
+ BinariesDict = Tmp.FromXml(BinariesItem, 'Binaries')
+ self.BinariesDict = BinariesDict
+
+ self.Statement = XmlElement(Item, 'UserExtensions')
+ SupArch = XmlAttribute(XmlNode(Item, '%s' % Key), 'SupArchList')
+ self.SupArchList = [Arch for Arch in GetSplitValueList(SupArch, DataType.TAB_SPACE_SPLIT) if Arch]
+
+ UserExtension = UserExtensionObject()
+ UserExtension.SetUserID(self.UserId)
+ UserExtension.SetIdentifier(self.Identifier)
+ UserExtension.SetStatement(self.Statement)
+ UserExtension.SetSupArchList(self.SupArchList)
+ UserExtension.SetDefinesDict(self.DefineDict)
+ UserExtension.SetBuildOptionDict(self.BuildOptionDict)
+ UserExtension.SetIncludesDict(self.IncludesDict)
+ UserExtension.SetSourcesDict(self.SourcesDict)
+ UserExtension.SetBinariesDict(self.BinariesDict)
+
+ return UserExtension
+
+ def ToXml(self, UserExtension, Key):
+ if self.UserId:
+ pass
+
+ AttributeList = [['UserId', str(UserExtension.GetUserID())],
+ ['Identifier', str(UserExtension.GetIdentifier())],
+ ['SupArchList', \
+ GetStringOfList(UserExtension.GetSupArchList())],
+ ]
+
+ Root = CreateXmlElement('%s' % Key, UserExtension.GetStatement(), [], \
+ AttributeList)
+
+ NodeList = []
+ DefineDict = UserExtension.GetDefinesDict()
+ if DefineDict:
+ for Item in DefineDict.keys():
+ NodeList.append(CreateXmlElement\
+ ('Statement', Item, [], []))
+ DefineElement = CreateXmlElement('Define', '', NodeList, [])
+ Root.appendChild(DefineElement)
+
+ NodeList = []
+ BuildOptionDict = UserExtension.GetBuildOptionDict()
+ if BuildOptionDict:
+ for Item in BuildOptionDict.keys():
+ NodeList.append(CreateXmlElement\
+ ('Statement', BuildOptionDict[Item], [], \
+ [['SupArchList', Item]]))
+ BuildOptionElement = \
+ CreateXmlElement('BuildOption', '', NodeList, [])
+ Root.appendChild(BuildOptionElement)
+
+ NodeList = []
+ IncludesDict = UserExtension.GetIncludesDict()
+ if IncludesDict:
+ for Item in IncludesDict.keys():
+ NodeList.append(CreateXmlElement\
+ ('Statement', Item, [], \
+ [['SupArchList', IncludesDict[Item]]]))
+ IncludesElement = CreateXmlElement('Includes', '', NodeList, [])
+ Root.appendChild(IncludesElement)
+
+ NodeList = []
+ SourcesDict = UserExtension.GetSourcesDict()
+ if SourcesDict:
+ Tmp = UserExtensionSourceXml()
+ Root.appendChild(Tmp.ToXml(SourcesDict, 'Sources'))
+
+ NodeList = []
+ BinariesDict = UserExtension.GetBinariesDict()
+ if BinariesDict:
+ Tmp = UserExtensionBinaryXml()
+ Root.appendChild(Tmp.ToXml(BinariesDict, 'Binaries'))
+
+ return Root
+
+ def __str__(self):
+ Str = "UserId = %s Identifier = %s" % (self.UserId, self.Identifier)
+ Str = Str + '\n\tDefines:' + str(self.Defines)
+ Str = Str + '\n\tBuildOptions:' + str(self.BuildOptions)
+ return Str
+
+##
+# UserExtensionSourceXml
+#
+class UserExtensionSourceXml(object):
+ def __init__(self):
+ self.UserExtensionSource = ''
+
+ def FromXml(self, Item, Key):
+ if Key:
+ pass
+ if self.UserExtensionSource:
+ pass
+ Dict = {}
+
+ #SourcesItem = XmlNode(Item, '%s/Sources' % Key)
+ for SubItem in XmlList(Item, 'Sources/SourceFile'):
+ FileName = XmlElement(SubItem, 'SourceFile/FileName')
+ Family = XmlElement(SubItem, 'SourceFile/Family')
+ FeatureFlag = XmlElement(SubItem, 'SourceFile/FeatureFlag')
+ SupArchStr = XmlElement(SubItem, 'SourceFile/SupArchList')
+ DictKey = (FileName, Family, FeatureFlag, SupArchStr)
+
+ ValueList = []
+ for ValueNodeItem in XmlList(SubItem, \
+ 'SourceFile/SourceFileOtherAttr'):
+ TagName = XmlElement(ValueNodeItem, \
+ 'SourceFileOtherAttr/TagName')
+ ToolCode = XmlElement(ValueNodeItem, \
+ 'SourceFileOtherAttr/ToolCode')
+ Comment = XmlElement(ValueNodeItem, \
+ 'SourceFileOtherAttr/Comment')
+ if (TagName == ' ') and (ToolCode == ' ') and (Comment == ' '):
+ TagName = ''
+ ToolCode = ''
+ Comment = ''
+ ValueList.append((TagName, ToolCode, Comment))
+
+ Dict[DictKey] = ValueList
+
+ return Dict
+
+ def ToXml(self, Dict, Key):
+ if self.UserExtensionSource:
+ pass
+ SourcesNodeList = []
+ for Item in Dict:
+ ValueList = Dict[Item]
+ (FileName, Family, FeatureFlag, SupArchStr) = Item
+ SourceFileNodeList = []
+ SourceFileNodeList.append(["FileName", FileName])
+ SourceFileNodeList.append(["Family", Family])
+ SourceFileNodeList.append(["FeatureFlag", FeatureFlag])
+ SourceFileNodeList.append(["SupArchList", SupArchStr])
+ for (TagName, ToolCode, Comment) in ValueList:
+ ValueNodeList = []
+ if not (TagName or ToolCode or Comment):
+ TagName = ' '
+ ToolCode = ' '
+ Comment = ' '
+ ValueNodeList.append(["TagName", TagName])
+ ValueNodeList.append(["ToolCode", ToolCode])
+ ValueNodeList.append(["Comment", Comment])
+ ValueNodeXml = CreateXmlElement('SourceFileOtherAttr', '', \
+ ValueNodeList, [])
+ SourceFileNodeList.append(ValueNodeXml)
+ SourceFileNodeXml = CreateXmlElement('SourceFile', '', \
+ SourceFileNodeList, [])
+ SourcesNodeList.append(SourceFileNodeXml)
+ Root = CreateXmlElement('%s' % Key, '', SourcesNodeList, [])
+ return Root
+
+##
+# UserExtensionBinaryXml
+#
+class UserExtensionBinaryXml(object):
+ def __init__(self):
+ self.UserExtensionBinary = ''
+
+ def FromXml(self, Item, Key):
+ if Key:
+ pass
+ if self.UserExtensionBinary:
+ pass
+
+ Dict = {}
+
+ for SubItem in XmlList(Item, 'Binaries/Binary'):
+ FileName = XmlElement(SubItem, 'Binary/FileName')
+ FileType = XmlElement(SubItem, 'Binary/FileType')
+ FFE = XmlElement(SubItem, 'Binary/FeatureFlag')
+ SupArch = XmlElement(SubItem, 'Binary/SupArchList')
+ DictKey = (FileName, FileType, ConvertNOTEQToNE(FFE), SupArch)
+
+ ValueList = []
+ for ValueNodeItem in XmlList(SubItem, \
+ 'Binary/BinaryFileOtherAttr'):
+ Target = XmlElement(ValueNodeItem, \
+ 'BinaryFileOtherAttr/Target')
+ Family = XmlElement(ValueNodeItem, \
+ 'BinaryFileOtherAttr/Family')
+ TagName = XmlElement(ValueNodeItem, \
+ 'BinaryFileOtherAttr/TagName')
+ Comment = XmlElement(ValueNodeItem, \
+ 'BinaryFileOtherAttr/Comment')
+ if (Target == ' ') and (Family == ' ') and \
+ (TagName == ' ') and (Comment == ' '):
+ Target = ''
+ Family = ''
+ TagName = ''
+ Comment = ''
+
+ ValueList.append((Target, Family, TagName, Comment))
+
+ Dict[DictKey] = ValueList
+
+ return Dict
+
+ def ToXml(self, Dict, Key):
+ if self.UserExtensionBinary:
+ pass
+ BinariesNodeList = []
+ for Item in Dict:
+ ValueList = Dict[Item]
+ (FileName, FileType, FeatureFlag, SupArch) = Item
+ FileNodeList = []
+ FileNodeList.append(["FileName", FileName])
+ FileNodeList.append(["FileType", FileType])
+ FileNodeList.append(["FeatureFlag", ConvertNEToNOTEQ(FeatureFlag)])
+ FileNodeList.append(["SupArchList", SupArch])
+ for (Target, Family, TagName, Comment) in ValueList:
+ ValueNodeList = []
+ if not (Target or Family or TagName or Comment):
+ Target = ' '
+ Family = ' '
+ TagName = ' '
+ Comment = ' '
+ ValueNodeList.append(["Target", Target])
+ ValueNodeList.append(["Family", Family])
+ ValueNodeList.append(["TagName", TagName])
+ ValueNodeList.append(["Comment", Comment])
+ ValueNodeXml = CreateXmlElement('BinaryFileOtherAttr', '', \
+ ValueNodeList, [])
+ FileNodeList.append(ValueNodeXml)
+ FileNodeXml = CreateXmlElement('Binary', '', FileNodeList, [])
+ BinariesNodeList.append(FileNodeXml)
+ Root = CreateXmlElement('%s' % Key, '', BinariesNodeList, [])
+ return Root
+
+##
+# LibraryClassXml
+#
+class LibraryClassXml(object):
+ def __init__(self):
+ self.Keyword = ''
+ self.HeaderFile = ''
+ self.RecommendedInstanceGuid = ''
+ self.RecommendedInstanceVersion = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.Keyword = XmlAttribute(XmlNode(Item, '%s' % Key), 'Keyword')
+ if self.Keyword == '':
+ self.Keyword = XmlElement(Item, '%s/Keyword' % Key)
+ self.HeaderFile = XmlElement(Item, '%s/HeaderFile' % Key)
+ self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ LibraryClass = LibraryClassObject()
+ LibraryClass.SetLibraryClass(self.Keyword)
+ LibraryClass.SetIncludeHeader(self.HeaderFile)
+ if self.CommonDefines.Usage:
+ LibraryClass.SetUsage(self.CommonDefines.Usage)
+ LibraryClass.SetSupArchList(self.CommonDefines.SupArchList)
+ LibraryClass.SetSupModuleList(self.CommonDefines.SupModList)
+ LibraryClass.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ LibraryClass.SetHelpTextList(GetHelpTextList(self.HelpText))
+
+ return LibraryClass
+
+ def ToXml(self, LibraryClass, Key):
+ if self.HeaderFile:
+ pass
+ AttributeList = \
+ [['Keyword', LibraryClass.GetLibraryClass()],
+ ['SupArchList', GetStringOfList(LibraryClass.GetSupArchList())],
+ ['SupModList', GetStringOfList(LibraryClass.GetSupModuleList())]
+ ]
+ NodeList = [['HeaderFile', LibraryClass.GetIncludeHeader()]]
+ for Item in LibraryClass.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def ToXml2(self, LibraryClass, Key):
+ if self.HeaderFile:
+ pass
+
+ FeatureFlag = ConvertNEToNOTEQ(LibraryClass.GetFeatureFlag())
+
+ AttributeList = \
+ [['Usage', LibraryClass.GetUsage()], \
+ ['SupArchList', GetStringOfList(LibraryClass.GetSupArchList())], \
+ ['SupModList', GetStringOfList(LibraryClass.GetSupModuleList())], \
+ ['FeatureFlag', FeatureFlag]
+ ]
+ NodeList = [['Keyword', LibraryClass.GetLibraryClass()], ]
+ for Item in LibraryClass.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "Keyword = %s HeaderFile = %s RecommendedInstanceGuid = %s RecommendedInstanceVersion = %s %s" % \
+ (self.Keyword, self.HeaderFile, self.RecommendedInstanceGuid, self.RecommendedInstanceVersion, \
+ self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + "\n\t" + str(Item)
+ return Str
+
+##
+# FilenameXml
+#
+class FilenameXml(object):
+ def __init__(self):
+ self.FileType = ''
+ self.Filename = ''
+ self.CommonDefines = CommonDefinesXml()
+
+ def FromXml(self, Item, Key):
+ self.FileType = XmlAttribute(Item, 'FileType')
+ self.Filename = XmlElement(Item, 'Filename')
+ self.CommonDefines.FromXml(Item, Key)
+
+ FeatureFlag = ConvertNOTEQToNE(self.CommonDefines.FeatureFlag)
+
+ Filename = FileNameObject()
+ #
+ # Convert File Type
+ #
+ if self.FileType == 'UEFI_IMAGE':
+ self.FileType = 'PE32'
+
+ Filename.SetFileType(self.FileType)
+ Filename.SetFilename(self.Filename)
+ Filename.SetSupArchList(self.CommonDefines.SupArchList)
+ Filename.SetFeatureFlag(FeatureFlag)
+
+ return Filename
+
+ def ToXml(self, Filename, Key):
+ if self.Filename:
+ pass
+ AttributeList = [['SupArchList', \
+ GetStringOfList(Filename.GetSupArchList())],
+ ['FileType', Filename.GetFileType()],
+ ['FeatureFlag', ConvertNEToNOTEQ(Filename.GetFeatureFlag())],
+ ]
+ Root = CreateXmlElement('%s' % Key, Filename.GetFilename(), [], AttributeList)
+
+ return Root
+
+ def __str__(self):
+ return "FileType = %s Filename = %s %s" \
+ % (self.FileType, self.Filename, self.CommonDefines)
diff --git a/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py b/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py
new file mode 100644
index 0000000000..bfd8d4f7bb
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/GuidProtocolPpiXml.py
@@ -0,0 +1,284 @@
+## @file
+# This file is used to parse a xml file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+GuidProtocolPpiXml
+'''
+from Library.String import ConvertNEToNOTEQ
+from Library.String import ConvertNOTEQToNE
+from Library.String import GetStringOfList
+from Library.Xml.XmlRoutines import XmlElement
+from Library.Xml.XmlRoutines import XmlAttribute
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import XmlList
+from Library.Xml.XmlRoutines import CreateXmlElement
+
+from Object.POM.CommonObject import GuidObject
+from Object.POM.CommonObject import ProtocolObject
+from Object.POM.CommonObject import PpiObject
+
+from Xml.CommonXml import CommonDefinesXml
+from Xml.CommonXml import HelpTextXml
+
+from Xml.XmlParserMisc import GetHelpTextList
+
+##
+#GUID/Protocol/Ppi Common
+#
+class GuidProtocolPpiXml(object):
+ def __init__(self, Mode):
+ self.UiName = ''
+ self.GuidTypes = ''
+ self.Notify = ''
+ self.CName = ''
+ self.GuidValue = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+ #
+ # Guid/Ppi/Library, internal used for indicate return object for
+ # FromXml
+ #
+ self.Type = ''
+ #
+ # there are slightly different field between package and module
+ #
+ self.Mode = Mode
+ self.GuidType = ''
+ self.VariableName = ''
+
+ def FromXml(self, Item, Key):
+ self.UiName = XmlAttribute(XmlNode(Item, '%s' % Key), 'UiName')
+ self.GuidType = XmlAttribute(XmlNode(Item, '%s' % Key), 'GuidType')
+ self.Notify = XmlAttribute(XmlNode(Item, '%s' % Key), 'Notify')
+ self.CName = XmlElement(Item, '%s/CName' % Key)
+ self.GuidValue = XmlElement(Item, '%s/GuidValue' % Key)
+ self.VariableName = XmlElement(Item, '%s/VariableName' % Key)
+ self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ if self.Type == 'Guid':
+ GuidProtocolPpi = GuidObject()
+ elif self.Type == 'Protocol':
+ GuidProtocolPpi = ProtocolObject()
+ else:
+ GuidProtocolPpi = PpiObject()
+ GuidProtocolPpi.SetHelpTextList(GetHelpTextList(self.HelpText))
+
+ return GuidProtocolPpi
+
+ def ToXml(self, GuidProtocolPpi, Key):
+ if self.GuidValue:
+ pass
+ AttributeList = \
+ [['Usage', GetStringOfList(GuidProtocolPpi.GetUsage())], \
+ ['UiName', GuidProtocolPpi.GetName()], \
+ ['GuidType', GetStringOfList(GuidProtocolPpi.GetGuidTypeList())], \
+ ['Notify', str(GuidProtocolPpi.GetNotify()).lower()], \
+ ['SupArchList', GetStringOfList(GuidProtocolPpi.GetSupArchList())], \
+ ['SupModList', GetStringOfList(GuidProtocolPpi.GetSupModuleList())], \
+ ['FeatureFlag', ConvertNEToNOTEQ(GuidProtocolPpi.GetFeatureFlag())]
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ['GuidValue', GuidProtocolPpi.GetGuid()],
+ ['VariableName', GuidProtocolPpi.VariableName]
+ ]
+ for Item in GuidProtocolPpi.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = \
+ "UiName = %s Notify = %s GuidTypes = %s CName = %s GuidValue = %s %s" \
+ % (self.UiName, self.Notify, self.GuidTypes, self.CName, \
+ self.GuidValue, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + "\n\t" + str(Item)
+ return Str
+##
+#GUID Xml
+#
+class GuidXml(GuidProtocolPpiXml):
+ def __init__(self, Mode):
+ GuidProtocolPpiXml.__init__(self, Mode)
+ self.Type = 'Guid'
+
+ def FromXml(self, Item, Key):
+ GuidProtocolPpi = GuidProtocolPpiXml.FromXml(self, Item, Key)
+
+ if self.Mode == 'Package':
+
+ GuidProtocolPpi.SetSupArchList(self.CommonDefines.SupArchList)
+ GuidProtocolPpi.SetSupModuleList(self.CommonDefines.SupModList)
+ GuidProtocolPpi.SetCName(self.CName)
+ GuidProtocolPpi.SetGuid(self.GuidValue)
+ else:
+ GuidProtocolPpi.SetUsage(self.CommonDefines.Usage)
+ if self.GuidType:
+ GuidProtocolPpi.SetGuidTypeList([self.GuidType])
+ GuidProtocolPpi.SetSupArchList(self.CommonDefines.SupArchList)
+ GuidProtocolPpi.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ GuidProtocolPpi.SetCName(self.CName)
+ GuidProtocolPpi.SetVariableName(self.VariableName)
+ return GuidProtocolPpi
+
+ def ToXml(self, GuidProtocolPpi, Key):
+ if self.Mode == 'Package':
+ AttributeList = \
+ [['GuidType', \
+ GetStringOfList(GuidProtocolPpi.GetGuidTypeList())], \
+ ['SupArchList', \
+ GetStringOfList(GuidProtocolPpi.GetSupArchList())], \
+ ['SupModList', \
+ GetStringOfList(GuidProtocolPpi.GetSupModuleList())],
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ['GuidValue', GuidProtocolPpi.GetGuid()],
+ ]
+ else:
+ AttributeList = \
+ [['Usage', GetStringOfList(GuidProtocolPpi.GetUsage())], \
+ ['GuidType', GetStringOfList(GuidProtocolPpi.GetGuidTypeList())],\
+ ['SupArchList', \
+ GetStringOfList(GuidProtocolPpi.GetSupArchList())], \
+ ['FeatureFlag', ConvertNEToNOTEQ(GuidProtocolPpi.GetFeatureFlag())]
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ['VariableName', GuidProtocolPpi.GetVariableName()]
+ ]
+
+ for Item in GuidProtocolPpi.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+##
+#Protocol Xml
+#
+class ProtocolXml(GuidProtocolPpiXml):
+ def __init__(self, Mode):
+ GuidProtocolPpiXml.__init__(self, Mode)
+ self.Type = 'Protocol'
+
+ def FromXml(self, Item, Key):
+ GuidProtocolPpi = GuidProtocolPpiXml.FromXml(self, Item, Key)
+ if self.Mode == 'Package':
+ GuidProtocolPpi.SetFeatureFlag(self.CommonDefines.FeatureFlag)
+ GuidProtocolPpi.SetSupArchList(self.CommonDefines.SupArchList)
+ GuidProtocolPpi.SetSupModuleList(self.CommonDefines.SupModList)
+ GuidProtocolPpi.SetCName(self.CName)
+ GuidProtocolPpi.SetGuid(self.GuidValue)
+ else:
+ GuidProtocolPpi.SetUsage(self.CommonDefines.Usage)
+ if self.Notify.upper() == "TRUE":
+ GuidProtocolPpi.SetNotify(True)
+ elif self.Notify.upper() == "FALSE":
+ GuidProtocolPpi.SetNotify(False)
+ else:
+ GuidProtocolPpi.SetNotify('')
+ GuidProtocolPpi.SetSupArchList(self.CommonDefines.SupArchList)
+ GuidProtocolPpi.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ GuidProtocolPpi.SetCName(self.CName)
+
+ return GuidProtocolPpi
+
+ def ToXml(self, GuidProtocolPpi, Key):
+ if self.Mode == 'Package':
+ AttributeList = \
+ [['SupArchList', \
+ GetStringOfList(GuidProtocolPpi.GetSupArchList())], \
+ ['SupModList', \
+ GetStringOfList(GuidProtocolPpi.GetSupModuleList())], \
+ ['FeatureFlag', GuidProtocolPpi.GetFeatureFlag()]
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ['GuidValue', GuidProtocolPpi.GetGuid()],
+ ]
+ else:
+ AttributeList = \
+ [['Usage', GetStringOfList(GuidProtocolPpi.GetUsage())], \
+ ['Notify', str(GuidProtocolPpi.GetNotify()).lower()], \
+ ['SupArchList', \
+ GetStringOfList(GuidProtocolPpi.GetSupArchList())], \
+ ['FeatureFlag', ConvertNEToNOTEQ(GuidProtocolPpi.GetFeatureFlag())]
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ]
+
+ for Item in GuidProtocolPpi.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+##
+#Ppi Xml
+#
+class PpiXml(GuidProtocolPpiXml):
+ def __init__(self, Mode):
+ GuidProtocolPpiXml.__init__(self, Mode)
+ self.Type = 'Ppi'
+
+ def FromXml(self, Item, Key):
+ GuidProtocolPpi = GuidProtocolPpiXml.FromXml(self, Item, Key)
+ if self.Mode == 'Package':
+ GuidProtocolPpi.SetSupArchList(self.CommonDefines.SupArchList)
+ GuidProtocolPpi.SetSupModuleList(self.CommonDefines.SupModList)
+ GuidProtocolPpi.SetCName(self.CName)
+ GuidProtocolPpi.SetGuid(self.GuidValue)
+ else:
+ GuidProtocolPpi.SetUsage(self.CommonDefines.Usage)
+ if self.Notify.upper() == "TRUE":
+ GuidProtocolPpi.SetNotify(True)
+ elif self.Notify.upper() == "FALSE":
+ GuidProtocolPpi.SetNotify(False)
+ else:
+ GuidProtocolPpi.SetNotify('')
+ GuidProtocolPpi.SetSupArchList(self.CommonDefines.SupArchList)
+ GuidProtocolPpi.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ GuidProtocolPpi.SetCName(self.CName)
+
+ return GuidProtocolPpi
+
+ def ToXml(self, GuidProtocolPpi, Key):
+ if self.Mode == 'Package':
+ AttributeList = \
+ [['SupArchList', \
+ GetStringOfList(GuidProtocolPpi.GetSupArchList())],
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ['GuidValue', GuidProtocolPpi.GetGuid()],
+ ]
+ else:
+ AttributeList = \
+ [['Usage', GetStringOfList(GuidProtocolPpi.GetUsage())], \
+ ['Notify', str(GuidProtocolPpi.GetNotify()).lower()], \
+ ['SupArchList', \
+ GetStringOfList(GuidProtocolPpi.GetSupArchList())], \
+ ['FeatureFlag', ConvertNEToNOTEQ(GuidProtocolPpi.GetFeatureFlag())]
+ ]
+ NodeList = [['CName', GuidProtocolPpi.GetCName()],
+ ]
+
+ for Item in GuidProtocolPpi.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+ return Root
diff --git a/BaseTools/Source/Python/UPT/Xml/IniToXml.py b/BaseTools/Source/Python/UPT/Xml/IniToXml.py
new file mode 100644
index 0000000000..4be20d00ca
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/IniToXml.py
@@ -0,0 +1,503 @@
+## @file
+# This file is for converting package information data file to xml file.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+IniToXml
+'''
+
+import os.path
+import re
+from time import strftime
+from time import localtime
+
+import Logger.Log as Logger
+from Logger.ToolError import UPT_INI_PARSE_ERROR
+from Logger.ToolError import FILE_NOT_FOUND
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Library.DataType import TAB_VALUE_SPLIT
+from Library.DataType import TAB_EQUAL_SPLIT
+from Library.DataType import TAB_SECTION_START
+from Library.DataType import TAB_SECTION_END
+from Logger import StringTable as ST
+from Library.String import ConvertSpecialChar
+from Library.ParserValidate import IsValidPath
+
+## log error:
+#
+# @param error: error
+# @param File: File
+# @param Line: Line
+#
+def IniParseError(Error, File, Line):
+ Logger.Error("UPT", UPT_INI_PARSE_ERROR, File=File,
+ Line=Line, ExtraData=Error)
+
+## __ValidatePath
+#
+# @param Path: Path to be checked
+#
+def __ValidatePath(Path, Root):
+ Path = Path.strip()
+ if os.path.isabs(Path) or not IsValidPath(Path, Root):
+ return False, ST.ERR_FILELIST_LOCATION % (Root, Path)
+ return True, ''
+
+## ValidateMiscFile
+#
+# @param Filename: File to be checked
+#
+def ValidateMiscFile(Filename):
+ Root = ''
+ if 'WORKSPACE' in os.environ:
+ Root = os.environ['WORKSPACE']
+ return __ValidatePath(Filename, Root)
+
+## ValidateToolsFile
+#
+# @param Filename: File to be checked
+#
+def ValidateToolsFile(Filename):
+ Valid, Cause = False, ''
+ if not Valid and 'EDK_TOOLS_PATH' in os.environ:
+ Valid, Cause = __ValidatePath(Filename, os.environ['EDK_TOOLS_PATH'])
+ if not Valid and 'WORKSPACE' in os.environ:
+ Valid, Cause = __ValidatePath(Filename, os.environ['WORKSPACE'])
+ return Valid, Cause
+
+## ParseFileList
+#
+# @param Line: Line
+# @param Map: Map
+# @param CurrentKey: CurrentKey
+# @param PathFunc: Path validate function
+#
+def ParseFileList(Line, Map, CurrentKey, PathFunc):
+ FileList = ["", {}]
+ TokenList = Line.split(TAB_VALUE_SPLIT)
+ if len(TokenList) > 0:
+ Path = TokenList[0].strip().replace('\\', '/')
+ if not Path:
+ return False, ST.ERR_WRONG_FILELIST_FORMAT
+ Valid, Cause = PathFunc(Path)
+ if not Valid:
+ return Valid, Cause
+ FileList[0] = TokenList[0].strip()
+ for Token in TokenList[1:]:
+ Attr = Token.split(TAB_EQUAL_SPLIT)
+ if len(Attr) != 2 or not Attr[0].strip() or not Attr[1].strip():
+ return False, ST.ERR_WRONG_FILELIST_FORMAT
+
+ Key = Attr[0].strip()
+ Val = Attr[1].strip()
+ if Key not in ['OS', 'Executable']:
+ return False, ST.ERR_UNKNOWN_FILELIST_ATTR % Key
+
+ if Key == 'OS' and Val not in ["Win32", "Win64", "Linux32",
+ "Linux64", "OS/X32", "OS/X64",
+ "GenericWin", "GenericNix"]:
+ return False, ST.ERR_FILELIST_ATTR % 'OS'
+ elif Key == 'Executable' and Val not in ['true', 'false']:
+ return False, ST.ERR_FILELIST_ATTR % 'Executable'
+ FileList[1][Key] = Val
+
+ Map[CurrentKey].append(FileList)
+ return True, ''
+
+## Create header XML file
+#
+# @param DistMap: DistMap
+# @param Root: Root
+#
+def CreateHeaderXml(DistMap, Root):
+ Element1 = CreateXmlElement('Name', DistMap['Name'],
+ [], [['BaseName', DistMap['BaseName']]])
+ Element2 = CreateXmlElement('GUID', DistMap['GUID'],
+ [], [['Version', DistMap['Version']]])
+ AttributeList = [['ReadOnly', DistMap['ReadOnly']],
+ ['RePackage', DistMap['RePackage']]]
+ NodeList = [Element1,
+ Element2,
+ ['Vendor', DistMap['Vendor']],
+ ['Date', DistMap['Date']],
+ ['Copyright', DistMap['Copyright']],
+ ['License', DistMap['License']],
+ ['Abstract', DistMap['Abstract']],
+ ['Description', DistMap['Description']],
+ ['Signature', DistMap['Signature']],
+ ['XmlSpecification', DistMap['XmlSpecification']],
+ ]
+ Root.appendChild(CreateXmlElement('DistributionHeader', '',
+ NodeList, AttributeList))
+
+## Create tools XML file
+#
+# @param Map: Map
+# @param Root: Root
+# @param Tag: Tag
+#
+def CreateToolsXml(Map, Root, Tag):
+ #
+ # Check if all elements in this section are empty
+ #
+ for Key in Map:
+ if len(Map[Key]) > 0:
+ break
+ else:
+ return
+
+ NodeList = [['Name', Map['Name']],
+ ['Copyright', Map['Copyright']],
+ ['License', Map['License']],
+ ['Abstract', Map['Abstract']],
+ ['Description', Map['Description']],
+ ]
+ HeaderNode = CreateXmlElement('Header', '', NodeList, [])
+ NodeList = [HeaderNode]
+
+ for File in Map['FileList']:
+ AttrList = []
+ for Key in File[1]:
+ AttrList.append([Key, File[1][Key]])
+ NodeList.append(CreateXmlElement('Filename', File[0], [], AttrList))
+ Root.appendChild(CreateXmlElement(Tag, '', NodeList, []))
+
+## ValidateValues
+#
+# @param Key: Key
+# @param Value: Value
+# @param SectionName: SectionName
+#
+def ValidateValues(Key, Value, SectionName):
+ if SectionName == 'DistributionHeader':
+ Valid, Cause = ValidateRegValues(Key, Value)
+ if not Valid:
+ return Valid, Cause
+ Valid = __ValidateDistHeader(Key, Value)
+ if not Valid:
+ return Valid, ST.ERR_VALUE_INVALID % (Key, SectionName)
+ else:
+ Valid = __ValidateOtherHeader(Key, Value)
+ if not Valid:
+ return Valid, ST.ERR_VALUE_INVALID % (Key, SectionName)
+ return True, ''
+
+## ValidateRegValues
+#
+# @param Key: Key
+# @param Value: Value
+#
+def ValidateRegValues(Key, Value):
+ ValidateMap = {
+ 'ReadOnly' :
+ ('true|false', ST.ERR_BOOLEAN_VALUE % (Key, Value)),
+ 'RePackage' :
+ ('true|false', ST.ERR_BOOLEAN_VALUE % (Key, Value)),
+ 'GUID' :
+ ('[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}',
+ ST.ERR_GUID_VALUE % Value),
+ 'Version' : ('[0-9]+(\.[0-9]+)?', ST.ERR_VERSION_VALUE % \
+ (Key, Value)),
+ 'XmlSpecification' : ('1\.1', ST.ERR_VERSION_XMLSPEC % Value)
+ }
+ if Key not in ValidateMap:
+ return True, ''
+ Elem = ValidateMap[Key]
+ Match = re.compile(Elem[0]).match(Value)
+ if Match and Match.start() == 0 and Match.end() == len(Value):
+ return True, ''
+ return False, Elem[1]
+
+## __ValidateDistHeaderName
+#
+# @param Name: Name
+#
+def __ValidateDistHeaderName(Name):
+ if len(Name) < 1:
+ return False
+
+ for Char in Name:
+ if ord(Char) < 0x20 or ord(Char) >= 0x7f:
+ return False
+ return True
+
+## __ValidateDistHeaderBaseName
+#
+# @param BaseName: BaseName
+#
+def __ValidateDistHeaderBaseName(BaseName):
+ if not BaseName:
+ return False
+# if CheckLen and len(BaseName) < 2:
+# return False
+ if not BaseName[0].isalnum() and BaseName[0] != '_':
+ return False
+ for Char in BaseName[1:]:
+ if not Char.isalnum() and Char not in '-_':
+ return False
+ return True
+
+## __ValidateDistHeaderAbstract
+#
+# @param Abstract: Abstract
+#
+def __ValidateDistHeaderAbstract(Abstract):
+ return '\t' not in Abstract and len(Abstract.splitlines()) == 1
+
+## __ValidateOtherHeaderAbstract
+#
+# @param Abstract: Abstract
+#
+def __ValidateOtherHeaderAbstract(Abstract):
+ return __ValidateDistHeaderAbstract(Abstract)
+
+## __ValidateDistHeader
+#
+# @param Key: Key
+# @param Value: Value
+#
+def __ValidateDistHeader(Key, Value):
+ ValidateMap = {
+ 'Name' : __ValidateDistHeaderName,
+ 'BaseName' : __ValidateDistHeaderBaseName,
+ 'Abstract' : __ValidateDistHeaderAbstract,
+ 'Vendor' : __ValidateDistHeaderAbstract
+ }
+ return not (Value and Key in ValidateMap and not ValidateMap[Key](Value))
+
+## __ValidateOtherHeader
+#
+# @param Key: Key
+# @param Value: Value
+#
+def __ValidateOtherHeader(Key, Value):
+ ValidateMap = {
+ 'Name' : __ValidateDistHeaderName,
+ 'Abstract' : __ValidateOtherHeaderAbstract
+ }
+ return not (Value and Key in ValidateMap and not ValidateMap[Key](Value))
+
+## Convert ini file to xml file
+#
+# @param IniFile
+#
+def IniToXml(IniFile):
+ if not os.path.exists(IniFile):
+ Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_TEMPLATE_NOTFOUND % IniFile)
+
+ DistMap = {'ReadOnly' : '', 'RePackage' : '', 'Name' : '',
+ 'BaseName' : '', 'GUID' : '', 'Version' : '', 'Vendor' : '',
+ 'Date' : '', 'Copyright' : '', 'License' : '', 'Abstract' : '',
+ 'Description' : '', 'Signature' : '', 'XmlSpecification' : ''
+ }
+
+ ToolsMap = {'Name' : '', 'Copyright' : '', 'License' : '',
+ 'Abstract' : '', 'Description' : '', 'FileList' : []}
+ #
+ # Only FileList is a list: [['file1', {}], ['file2', {}], ...]
+ #
+ MiscMap = {'Name' : '', 'Copyright' : '', 'License' : '',
+ 'Abstract' : '', 'Description' : '', 'FileList' : []}
+
+ SectionMap = {
+ 'DistributionHeader' : DistMap,
+ 'ToolsHeader' : ToolsMap,
+ 'MiscellaneousFilesHeader' : MiscMap
+ }
+
+ PathValidator = {
+ 'ToolsHeader' : ValidateToolsFile,
+ 'MiscellaneousFilesHeader' : ValidateMiscFile
+ }
+
+ ParsedSection = []
+
+ SectionName = ''
+ CurrentKey = ''
+ PreMap = None
+ Map = None
+ FileContent = ConvertSpecialChar(open(IniFile, 'rb').readlines())
+ LastIndex = 0
+ for Index in range(0, len(FileContent)):
+ LastIndex = Index
+ Line = FileContent[Index].strip()
+ if Line == '':
+ continue
+ if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:
+ CurrentKey = ''
+ SectionName = Line[1:-1].strip()
+ if SectionName not in SectionMap:
+ IniParseError(ST.ERR_SECTION_NAME_INVALID % SectionName,
+ IniFile, Index+1)
+
+ if SectionName in ParsedSection:
+ IniParseError(ST.ERR_SECTION_REDEFINE % SectionName,
+ IniFile, Index+1)
+ else:
+ ParsedSection.append(SectionName)
+
+ Map = SectionMap[SectionName]
+ continue
+ if not Map:
+ IniParseError(ST.ERR_SECTION_NAME_NONE, IniFile, Index+1)
+ TokenList = Line.split(TAB_EQUAL_SPLIT, 1)
+ TempKey = TokenList[0].strip()
+ #
+ # Value spanned multiple or same keyword appears more than one time
+ #
+ if len(TokenList) < 2 or TempKey not in Map:
+ if CurrentKey == '':
+ IniParseError(ST.ERR_KEYWORD_INVALID % TempKey,
+ IniFile, Index+1)
+ elif CurrentKey == 'FileList':
+ #
+ # Special for FileList
+ #
+ Valid, Cause = ParseFileList(Line, Map, CurrentKey,
+ PathValidator[SectionName])
+ if not Valid:
+ IniParseError(Cause, IniFile, Index+1)
+
+ else:
+ #
+ # Multiple lines for one key such as license
+ # Or if string on the left side of '=' is not a keyword
+ #
+ Map[CurrentKey] = ''.join([Map[CurrentKey], '\n', Line])
+ Valid, Cause = ValidateValues(CurrentKey,
+ Map[CurrentKey], SectionName)
+ if not Valid:
+ IniParseError(Cause, IniFile, Index+1)
+ continue
+
+ if (TokenList[1].strip() == ''):
+ IniParseError(ST.ERR_EMPTY_VALUE, IniFile, Index+1)
+
+ #
+ # A keyword found
+ #
+ CurrentKey = TempKey
+ if Map[CurrentKey]:
+ IniParseError(ST.ERR_KEYWORD_REDEFINE % CurrentKey,
+ IniFile, Index+1)
+
+ if id(Map) != id(PreMap) and Map['Copyright']:
+ PreMap = Map
+ Copyright = Map['Copyright'].lower()
+ Pos = Copyright.find('copyright')
+ if Pos == -1:
+ IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, Index)
+ if not Copyright[Pos + len('copyright'):].lstrip(' ').startswith('('):
+ IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, Index)
+
+ if CurrentKey == 'FileList':
+ Valid, Cause = ParseFileList(TokenList[1], Map, CurrentKey,
+ PathValidator[SectionName])
+ if not Valid:
+ IniParseError(Cause, IniFile, Index+1)
+ else:
+ Map[CurrentKey] = TokenList[1].strip()
+ Valid, Cause = ValidateValues(CurrentKey,
+ Map[CurrentKey], SectionName)
+ if not Valid:
+ IniParseError(Cause, IniFile, Index+1)
+
+ if id(Map) != id(PreMap) and Map['Copyright'] and 'copyright' not in Map['Copyright'].lower():
+ IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, LastIndex)
+
+ #
+ # Check mandatory keys
+ #
+ CheckMdtKeys(DistMap, IniFile, LastIndex,
+ (('ToolsHeader', ToolsMap), ('MiscellaneousFilesHeader', MiscMap))
+ )
+
+ return CreateXml(DistMap, ToolsMap, MiscMap, IniFile)
+
+
+## CheckMdtKeys
+#
+# @param MdtDistKeys: All mandatory keys
+# @param DistMap: Dist content
+# @param IniFile: Ini file
+# @param LastIndex: Last index of Ini file
+# @param Maps: Tools and Misc section name and map. (('section_name', map),*)
+#
+def CheckMdtKeys(DistMap, IniFile, LastIndex, Maps):
+ MdtDistKeys = ['Name', 'GUID', 'Version', 'Vendor', 'Copyright', 'License', 'Abstract', 'XmlSpecification']
+ for Key in MdtDistKeys:
+ if Key not in DistMap or DistMap[Key] == '':
+ IniParseError(ST.ERR_KEYWORD_MANDATORY % Key, IniFile, LastIndex+1)
+
+ if '.' not in DistMap['Version']:
+ DistMap['Version'] = DistMap['Version'] + '.0'
+
+ DistMap['Date'] = str(strftime("%Y-%m-%dT%H:%M:%S", localtime()))
+
+ #
+ # Check Tools Surface Area according to UPT Spec
+ # <Tools> {0,}
+ # <Header> ... </Header> {0,1}
+ # <Filename> ... </Filename> {1,}
+ # </Tools>
+ # <Header>
+ # <Name> xs:normalizedString </Name> {1}
+ # <Copyright> xs:string </Copyright> {0,1}
+ # <License> xs:string </License> {0,1}
+ # <Abstract> xs:normalizedString </Abstract> {0,1}
+ # <Description> xs:string </Description> {0,1}
+ # </Header>
+ #
+ for Item in Maps:
+ Map = Item[1]
+ NonEmptyKey = 0
+ for Key in Map:
+ if Map[Key]:
+ NonEmptyKey += 1
+
+ if NonEmptyKey > 0 and not Map['FileList']:
+ IniParseError(ST.ERR_KEYWORD_MANDATORY % (Item[0] + '.FileList'), IniFile, LastIndex+1)
+
+ if NonEmptyKey > 0 and not Map['Name']:
+ IniParseError(ST.ERR_KEYWORD_MANDATORY % (Item[0] + '.Name'), IniFile, LastIndex+1)
+
+## CreateXml
+#
+# @param DistMap: Dist Content
+# @param ToolsMap: Tools Content
+# @param MiscMap: Misc Content
+# @param IniFile: Ini File
+#
+def CreateXml(DistMap, ToolsMap, MiscMap, IniFile):
+ Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],
+ ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],
+ ]
+ Root = CreateXmlElement('DistributionPackage', '', [], Attrs)
+ CreateHeaderXml(DistMap, Root)
+ CreateToolsXml(ToolsMap, Root, 'Tools')
+ CreateToolsXml(MiscMap, Root, 'MiscellaneousFiles')
+
+ FileAndExt = IniFile.rsplit('.', 1)
+ if len(FileAndExt) > 1:
+ FileName = FileAndExt[0] + '.xml'
+ else:
+ FileName = IniFile + '.xml'
+ File = open(FileName, 'w')
+
+ try:
+ File.write(Root.toprettyxml(indent = ' '))
+ finally:
+ File.close()
+ return FileName
+
diff --git a/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py b/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py
new file mode 100644
index 0000000000..a913a859f6
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/ModuleSurfaceAreaXml.py
@@ -0,0 +1,997 @@
+## @file
+# This file is used to parse a Module file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+ModuleSurfaceAreaXml
+'''
+from xml.dom import minidom
+
+from Library.String import ConvertNEToNOTEQ
+from Library.String import ConvertNOTEQToNE
+from Library.String import GetStringOfList
+from Library.Xml.XmlRoutines import XmlElement
+from Library.Xml.XmlRoutines import XmlAttribute
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import XmlList
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Object.POM.CommonObject import GuidVersionObject
+from Object.POM.ModuleObject import BootModeObject
+from Object.POM.ModuleObject import DepexObject
+from Object.POM.ModuleObject import ModuleObject
+from Object.POM.ModuleObject import EventObject
+from Object.POM.ModuleObject import HobObject
+from Object.POM.ModuleObject import SourceFileObject
+from Object.POM.ModuleObject import PackageDependencyObject
+from Object.POM.ModuleObject import ExternObject
+from Object.POM.ModuleObject import BinaryFileObject
+from Object.POM.ModuleObject import AsBuiltObject
+from Object.POM.ModuleObject import BinaryBuildFlagObject
+from Xml.CommonXml import ClonedFromXml
+from Xml.CommonXml import HeaderXml
+from Xml.CommonXml import HelpTextXml
+from Xml.CommonXml import CommonDefinesXml
+from Xml.CommonXml import LibraryClassXml
+from Xml.CommonXml import UserExtensionsXml
+from Xml.CommonXml import MiscellaneousFileXml
+from Xml.CommonXml import FilenameXml
+from Xml.GuidProtocolPpiXml import GuidXml
+from Xml.GuidProtocolPpiXml import ProtocolXml
+from Xml.GuidProtocolPpiXml import PpiXml
+from Xml.PcdXml import PcdEntryXml
+from Xml.XmlParserMisc import GetHelpTextList
+from Library import GlobalData
+from Library.Misc import GetSplitValueList
+
+## BinaryFileXml
+#
+# represent the following XML item
+#
+# <BinaryFile>
+# <Filename
+# FileType=" FileType " {1}
+# SupArchList=" ArchListType " {0,1}
+# FeatureFlag=" FeatureFlagExpression " {0,1} >
+# xs:anyURI
+# </Filename> {1,}
+# <AsBuilt> ... </AsBuilt> {0,}
+# </BinaryFile> {1,}
+#
+class BinaryFileXml(object):
+ def __init__(self):
+ self.FileNames = []
+ self.AsBuiltList = []
+ self.PatchPcdValues = ''
+ self.PcdExValues = ''
+ self.LibraryInstances = ''
+ self.BuildFlags = ''
+
+ def FromXml(self, Item, Key):
+ if self.FileNames:
+ pass
+ BinaryFile = BinaryFileObject()
+ FilenameList = []
+ for SubItem in XmlList(Item, '%s/Filename' % Key):
+ Axml = FilenameXml()
+ Bxml = Axml.FromXml(SubItem, 'Filename')
+ FilenameList.append(Bxml)
+ BinaryFile.SetFileNameList(FilenameList)
+ if GlobalData.gIS_BINARY_INF:
+ AsBuiltList = []
+ for AsBuiltItem in XmlList(Item, '%s/AsBuilt' % Key):
+ AsBuilt = AsBuiltObject()
+
+ PatchPcdValueList = []
+ for SubItem in XmlList(AsBuiltItem, 'AsBuilt/PatchPcdValue'):
+ Axml = PcdEntryXml()
+ Bxml = Axml.FromXml(SubItem, 'PatchPcdValue')
+ PatchPcdValueList.append(Bxml)
+ AsBuilt.SetPatchPcdList(PatchPcdValueList)
+ PcdExValueList = []
+ for SubItem in XmlList(AsBuiltItem, 'AsBuilt/PcdExValue'):
+ Axml = PcdEntryXml()
+ Bxml = Axml.FromXml(SubItem, 'PcdExValue')
+ PcdExValueList.append(Bxml)
+ AsBuilt.SetPcdExList(PcdExValueList)
+ LibraryList = []
+ for SubItem in XmlList(Item, '%s/AsBuilt/LibraryInstances/GUID' % Key):
+ GuidVerObj = GuidVersionObject()
+ GUID = XmlElement(SubItem, 'GUID')
+ Version = XmlAttribute(XmlNode(SubItem, 'GUID'), 'Version')
+ GuidVerObj.SetGuid(GUID)
+ GuidVerObj.SetVersion(Version)
+ LibraryList.append(GuidVerObj)
+ if XmlList(Item, '%s/AsBuilt/LibraryInstances' % Key) and not LibraryList:
+ LibraryList = [None]
+ AsBuilt.SetLibraryInstancesList(LibraryList)
+ BuildFlagList = []
+ for SubItem in XmlList(Item, '%s/AsBuilt/BuildFlags' % Key):
+ BuildFlag = BuildFlagXml()
+ BuildFlagList.append(BuildFlag.FromXml2(SubItem, 'BuildFlags'))
+ AsBuilt.SetBuildFlagsList(BuildFlagList)
+ AsBuiltList.append(AsBuilt)
+ BinaryFile.SetAsBuiltList(AsBuiltList)
+ return BinaryFile
+
+ def ToXml(self, BinaryFile, Key):
+ if self.FileNames:
+ pass
+ NodeList = []
+ FilenameList = BinaryFile.GetFileNameList()
+ for Filename in FilenameList:
+ Tmp = FilenameXml()
+ NodeList.append(Tmp.ToXml(Filename, 'Filename'))
+
+ if GlobalData.gIS_BINARY_INF:
+ AsBuildList = BinaryFile.GetAsBuiltList()
+ PatchPcdValueList = AsBuildList.GetPatchPcdList()
+ PcdExList = AsBuildList.GetPcdExList()
+ LibGuidVerList = AsBuildList.GetLibraryInstancesList()
+ BuildFlagList = AsBuildList.GetBuildFlagsList()
+
+ AsBuiltNodeList = []
+
+ for Pcd in PatchPcdValueList:
+ Tmp = PcdEntryXml()
+ AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PatchPcdValue'))
+
+ for Pcd in PcdExList:
+ Tmp = PcdEntryXml()
+ AsBuiltNodeList.append(Tmp.ToXml4(Pcd, 'PcdExValue'))
+
+ GuiVerElemList = []
+ for LibGuidVer in LibGuidVerList:
+ GuiVerElem = \
+ CreateXmlElement('GUID', LibGuidVer.GetLibGuid(), [], [['Version', LibGuidVer.GetLibVersion()]])
+ GuiVerElemList.append(GuiVerElem)
+ if len(GuiVerElemList) > 0:
+ LibGuidVerElem = CreateXmlElement('LibraryInstances', '', GuiVerElemList, [])
+ AsBuiltNodeList.append(LibGuidVerElem)
+
+ for BuildFlag in BuildFlagList:
+ Tmp = BuildFlagXml()
+ Elem = CreateXmlElement('BuildFlags', ''.join(BuildFlag), [], [])
+ AsBuiltNodeList.append(Elem)
+
+ if len(AsBuiltNodeList) > 0:
+ Element = CreateXmlElement('AsBuilt', '', AsBuiltNodeList, [])
+ NodeList.append(Element)
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, [])
+
+ return Root
+
+ def __str__(self):
+ Str = "BinaryFiles:"
+ for Item in self.FileNames:
+ Str = Str + '\n\t' + str(Item)
+ for Item in self.PatchPcdValues:
+ Str = Str + '\n\t' + str(Item)
+ for Item in self.PcdExValues:
+ Str = Str + '\n\t' + str(Item)
+ for Item in self.LibraryInstances:
+ Str = Str + '\n\t' + str(Item)
+ for Item in self.BuildFlags:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+
+##
+# PackageXml
+#
+class PackageXml(object):
+ def __init__(self):
+ self.Description = ''
+ self.Guid = ''
+ self.Version = ''
+ self.CommonDefines = CommonDefinesXml()
+
+ def FromXml(self, Item, Key):
+ self.Description = XmlElement(Item, '%s/Description' % Key)
+ self.Guid = XmlElement(Item, '%s/GUID' % Key)
+ self.Version = XmlAttribute(XmlNode(Item, '%s/GUID' % Key), 'Version')
+ self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key)
+
+ PackageDependency = PackageDependencyObject()
+ PackageDependency.SetPackage(self.Description)
+ PackageDependency.SetGuid(self.Guid)
+ PackageDependency.SetVersion(self.Version)
+ PackageDependency.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ PackageDependency.SetSupArchList(self.CommonDefines.SupArchList)
+
+ return PackageDependency
+
+ def ToXml(self, PackageDependency, Key):
+ if self.Guid:
+ pass
+ AttributeList = [['SupArchList', GetStringOfList(PackageDependency.GetSupArchList())],
+ ['FeatureFlag', ConvertNEToNOTEQ(PackageDependency.GetFeatureFlag())], ]
+ Element1 = CreateXmlElement('GUID', PackageDependency.GetGuid(), [],
+ [['Version', PackageDependency.GetVersion()]])
+ NodeList = [['Description', PackageDependency.GetPackage()], Element1, ]
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "Description = %s Guid = %s Version = %s %s" \
+ % (self.Description, self.Guid, self.Version, self.CommonDefines)
+ return Str
+##
+# ExternXml
+#
+class ExternXml(object):
+ def __init__(self):
+ self.CommonDefines = CommonDefinesXml()
+ self.EntryPoint = ''
+ self.UnloadImage = ''
+ self.Constructor = ''
+ self.Destructor = ''
+ self.SupModList = ''
+ self.SupArchList = ''
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.CommonDefines.FromXml(Item, Key)
+ self.EntryPoint = XmlElement(Item, '%s/EntryPoint' % Key)
+ self.UnloadImage = XmlElement(Item, '%s/UnloadImage' % Key)
+ self.Constructor = XmlElement(Item, '%s/Constructor' % Key)
+ self.Destructor = XmlElement(Item, '%s/Destructor' % Key)
+
+ Extern = ExternObject()
+ Extern.SetEntryPoint(self.EntryPoint)
+ Extern.SetUnloadImage(self.UnloadImage)
+ Extern.SetConstructor(self.Constructor)
+ Extern.SetDestructor(self.Destructor)
+ if self.CommonDefines.SupModList:
+ Extern.SetSupModList(self.CommonDefines.SupModList)
+ if self.CommonDefines.SupArchList:
+ Extern.SetSupArchList(self.CommonDefines.SupArchList)
+ return Extern
+
+ def ToXml(self, Extern, Key):
+ if self.HelpText:
+ pass
+
+ NodeList = []
+ if Extern.GetEntryPoint():
+ NodeList.append(['EntryPoint', Extern.GetEntryPoint()])
+ if Extern.GetUnloadImage():
+ NodeList.append(['UnloadImage', Extern.GetUnloadImage()])
+ if Extern.GetConstructor():
+ NodeList.append(['Constructor', Extern.GetConstructor()])
+ if Extern.GetDestructor():
+ NodeList.append(['Destructor', Extern.GetDestructor()])
+ Root = CreateXmlElement('%s' % Key, '', NodeList, [])
+
+ return Root
+
+ def __str__(self):
+ Str = "EntryPoint = %s UnloadImage = %s Constructor = %s Destructor = %s %s" \
+ % (self.EntryPoint, self.UnloadImage, self.Constructor, self.Destructor, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+##
+# DepexXml
+#
+class DepexXml(object):
+ def __init__(self):
+ self.CommonDefines = CommonDefinesXml()
+ self.Expression = None
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ if not Item:
+ return None
+ self.CommonDefines.FromXml(Item, Key)
+ self.Expression = XmlElement(Item, '%s/Expression' % Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ Depex = DepexObject()
+ Depex.SetDepex(self.Expression)
+ Depex.SetModuleType(self.CommonDefines.SupModList)
+ Depex.SetSupArchList(self.CommonDefines.SupArchList)
+ Depex.SetFeatureFlag(self.CommonDefines.FeatureFlag)
+ Depex.SetHelpTextList(GetHelpTextList(self.HelpText))
+
+ return Depex
+
+ def ToXml(self, Depex, Key):
+ if self.HelpText:
+ pass
+ AttributeList = [['SupArchList', GetStringOfList(Depex.GetSupArchList())],
+ ['SupModList', Depex.GetModuleType()]]
+ NodeList = [['Expression', Depex.GetDepex()]]
+ if Depex.GetHelpText():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Depex.GetHelpText(), 'HelpText'))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+ return Root
+
+ def __str__(self):
+ Str = "Expression = %s" % (self.Expression)
+ for Item in self.HelpText:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+
+##
+# BootModeXml
+#
+class BootModeXml(object):
+ def __init__(self):
+ self.SupportedBootModes = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.SupportedBootModes = \
+ XmlElement(Item, '%s/SupportedBootModes' % Key)
+ self.CommonDefines.FromXml(Item, Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ BootMode = BootModeObject()
+ BootMode.SetSupportedBootModes(self.SupportedBootModes)
+ BootMode.SetUsage(self.CommonDefines.Usage)
+ BootMode.SetHelpTextList(GetHelpTextList(self.HelpText))
+
+ return BootMode
+
+ def ToXml(self, BootMode, Key):
+ if self.HelpText:
+ pass
+ AttributeList = [['Usage', BootMode.GetUsage()], ]
+ NodeList = [['SupportedBootModes', BootMode.GetSupportedBootModes()]]
+ for Item in BootMode.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item, 'HelpText'))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "SupportedBootModes = %s %s" % (self.SupportedBootModes, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+##
+# EventXml
+#
+class EventXml(object):
+ def __init__(self):
+ self.EventType = ''
+ self.Name = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.EventType = XmlAttribute(XmlNode(Item, '%s' % Key), 'EventType')
+ self.Name = XmlElement(Item, '%s' % Key)
+ self.CommonDefines.FromXml(Item, Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ Event = EventObject()
+ Event.SetEventType(self.EventType)
+ Event.SetUsage(self.CommonDefines.Usage)
+ Event.SetHelpTextList(GetHelpTextList(self.HelpText))
+
+ return Event
+
+ def ToXml(self, Event, Key):
+ if self.HelpText:
+ pass
+ AttributeList = [['EventType', Event.GetEventType()],
+ ['Usage', Event.GetUsage()],
+ ]
+ NodeList = []
+ for Item in Event.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item, 'HelpText'))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "EventType = %s %s" % (self.EventType, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+##
+# HobXml
+#
+class HobXml(object):
+ def __init__(self):
+ self.HobType = ''
+ self.Name = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.HobType = XmlAttribute(XmlNode(Item, '%s' % Key), 'HobType')
+ self.Name = XmlElement(Item, '%s' % Key)
+ self.CommonDefines.FromXml(Item, Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ Hob = HobObject()
+ Hob.SetHobType(self.HobType)
+ Hob.SetSupArchList(self.CommonDefines.SupArchList)
+ Hob.SetUsage(self.CommonDefines.Usage)
+ Hob.SetHelpTextList(GetHelpTextList(self.HelpText))
+
+ return Hob
+
+ def ToXml(self, Hob, Key):
+ if self.Name:
+ pass
+ AttributeList = [['HobType', Hob.GetHobType()],
+ ['Usage', Hob.GetUsage()],
+ ['SupArchList', GetStringOfList(Hob.GetSupArchList())], ]
+ NodeList = []
+ for Item in Hob.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item, 'HelpText'))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "HobType = %s %s" % (self.HobType, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+
+##
+# SourceFileXml
+#
+class SourceFileXml(object):
+ def __init__(self):
+ self.SourceFile = ''
+ self.ToolChainFamily = ''
+ self.FileType = ''
+ self.CommonDefines = CommonDefinesXml()
+
+ def FromXml(self, Item, Key):
+ self.ToolChainFamily = XmlAttribute(Item, 'Family')
+ self.SourceFile = XmlElement(Item, 'Filename')
+ self.CommonDefines.FromXml(Item, Key)
+
+ self.CommonDefines.FeatureFlag = ConvertNOTEQToNE(self.CommonDefines.FeatureFlag)
+
+ SourceFile = SourceFileObject()
+ SourceFile.SetSourceFile(self.SourceFile)
+ SourceFile.SetFamily(self.ToolChainFamily)
+ SourceFile.SetSupArchList(self.CommonDefines.SupArchList)
+ SourceFile.SetFeatureFlag(self.CommonDefines.FeatureFlag)
+
+ return SourceFile
+
+ def ToXml(self, SourceFile, Key):
+ if self.SourceFile:
+ pass
+ FeatureFlag = ConvertNEToNOTEQ(SourceFile.GetFeatureFlag())
+ AttributeList = [['SupArchList', GetStringOfList(SourceFile.GetSupArchList())],
+ ['Family', SourceFile.GetFamily()],
+ ['FeatureFlag', FeatureFlag], ]
+ Root = CreateXmlElement('%s' % Key, SourceFile.GetSourceFile(), [], AttributeList)
+ return Root
+
+##
+# ModulePropertyXml
+#
+class ModulePropertyXml(object):
+ def __init__(self):
+ self.CommonDefines = CommonDefinesXml()
+ self.ModuleType = ''
+ self.Path = ''
+ self.PcdIsDriver = ''
+ self.UefiSpecificationVersion = ''
+ self.PiSpecificationVersion = ''
+ self.SpecificationList = []
+ self.SpecificationVersion = ''
+ self.BootModes = []
+ self.Events = []
+ self.HOBs = []
+
+ def FromXml(self, Item, Key, Header=None):
+ self.CommonDefines.FromXml(Item, Key)
+ self.ModuleType = XmlElement(Item, '%s/ModuleType' % Key)
+ self.Path = XmlElement(Item, '%s/Path' % Key)
+ self.PcdIsDriver = XmlElement(Item, '%s/PcdIsDriver' % Key)
+ self.UefiSpecificationVersion = XmlElement(Item, '%s/UefiSpecificationVersion' % Key)
+ self.PiSpecificationVersion = XmlElement(Item, '%s/PiSpecificationVersion' % Key)
+ for SubItem in XmlList(Item, '%s/Specification' % Key):
+ Specification = XmlElement(SubItem, '/Specification')
+ Version = XmlAttribute(XmlNode(SubItem, '/Specification'), 'Version')
+ self.SpecificationList.append((Specification, Version))
+ for SubItem in XmlList(Item, '%s/BootMode' % Key):
+ Axml = BootModeXml()
+ BootMode = Axml.FromXml(SubItem, 'BootMode')
+ self.BootModes.append(BootMode)
+ for SubItem in XmlList(Item, '%s/Event' % Key):
+ Axml = EventXml()
+ Event = Axml.FromXml(SubItem, 'Event')
+ self.Events.append(Event)
+ for SubItem in XmlList(Item, '%s/HOB' % Key):
+ Axml = HobXml()
+ Hob = Axml.FromXml(SubItem, 'HOB')
+ self.HOBs.append(Hob)
+
+ if Header == None:
+ Header = ModuleObject()
+
+ Header.SetModuleType(self.ModuleType)
+ Header.SetSupArchList(self.CommonDefines.SupArchList)
+ Header.SetModulePath(self.Path)
+
+ Header.SetPcdIsDriver(self.PcdIsDriver)
+ Header.SetUefiSpecificationVersion(self.UefiSpecificationVersion)
+ Header.SetPiSpecificationVersion(self.PiSpecificationVersion)
+ Header.SetSpecList(self.SpecificationList)
+
+ return Header, self.BootModes, self.Events, self.HOBs
+
+
+ def ToXml(self, Header, BootModes, Events, Hobs, Key):
+ if self.ModuleType:
+ pass
+ AttributeList = [['SupArchList', GetStringOfList(Header.GetSupArchList())], ]
+
+ NodeList = [['ModuleType', Header.GetModuleType()],
+ ['Path', Header.GetModulePath()],
+ ['PcdIsDriver', Header.GetPcdIsDriver()],
+ ['UefiSpecificationVersion', Header.GetUefiSpecificationVersion()],
+ ['PiSpecificationVersion', Header.GetPiSpecificationVersion()],
+ ]
+ for Item in Header.GetSpecList():
+ Spec, Version = Item
+ SpecElem = CreateXmlElement('Specification', Spec, [], [['Version', Version]])
+ NodeList.append(SpecElem)
+
+ for Item in BootModes:
+ Tmp = BootModeXml()
+ NodeList.append(Tmp.ToXml(Item, 'BootMode'))
+ for Item in Events:
+ Tmp = EventXml()
+ NodeList.append(Tmp.ToXml(Item, 'Event'))
+ for Item in Hobs:
+ Tmp = HobXml()
+ NodeList.append(Tmp.ToXml(Item, 'HOB'))
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "ModuleType = %s Path = %s PcdIsDriver = %s UefiSpecificationVersion = %s PiSpecificationVersion = %s \
+ Specification = %s SpecificationVersion = %s %s" % \
+ (self.ModuleType, self.Path, self.PcdIsDriver, \
+ self.UefiSpecificationVersion, self.PiSpecificationVersion, \
+ self.SpecificationList, self.SpecificationVersion, self.CommonDefines)
+ for Item in self.BootModes:
+ Str = Str + '\n\t' + str(Item)
+ for Item in self.Events:
+ Str = Str + '\n\t' + str(Item)
+ for Item in self.HOBs:
+ Str = Str + '\n\t' + str(Item)
+ return Str
+
+##
+# ModuleXml
+#
+class ModuleSurfaceAreaXml(object):
+ def __init__(self, Package=''):
+ self.Module = None
+ #
+ # indicate the package that this module resides in
+ #
+ self.Package = Package
+
+ def FromXml2(self, Item, Module):
+ if self.Module:
+ pass
+ #
+ # PeiDepex
+ #
+ PeiDepexList = []
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/PeiDepex'):
+ Tmp = DepexXml()
+ Depex = Tmp.FromXml(XmlNode(SubItem, 'PeiDepex'), 'PeiDepex')
+ PeiDepexList.append(Depex)
+ Module.SetPeiDepex(PeiDepexList)
+
+ #
+ # DxeDepex
+ #
+ DxeDepexList = []
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/DxeDepex'):
+ Tmp = DepexXml()
+ Depex = Tmp.FromXml(XmlNode(SubItem, 'DxeDepex'), 'DxeDepex')
+ DxeDepexList.append(Depex)
+ Module.SetDxeDepex(DxeDepexList)
+
+ #
+ # SmmDepex
+ #
+ SmmDepexList = []
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/SmmDepex'):
+ Tmp = DepexXml()
+ Depex = Tmp.FromXml(XmlNode(SubItem, 'SmmDepex'), 'SmmDepex')
+ SmmDepexList.append(Depex)
+ Module.SetSmmDepex(SmmDepexList)
+
+ #
+ # MiscellaneousFile
+ Tmp = MiscellaneousFileXml()
+ MiscFileList = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/MiscellaneousFiles'), 'MiscellaneousFiles')
+ if MiscFileList:
+ Module.SetMiscFileList([MiscFileList])
+ else:
+ Module.SetMiscFileList([])
+
+ #
+ # UserExtensions
+ #
+ for Item in XmlList(Item, '/ModuleSurfaceArea/UserExtensions'):
+ Tmp = UserExtensionsXml()
+ UserExtension = Tmp.FromXml(Item, 'UserExtensions')
+ Module.SetUserExtensionList(Module.GetUserExtensionList() + [UserExtension])
+
+ return Module
+
+ def FromXml(self, Item, Key, IsStandAlongModule=False):
+ IsBinaryModule = XmlAttribute(Item, 'BinaryModule')
+ #
+ # Header
+ #
+ Tmp = HeaderXml()
+ Module = Tmp.FromXml(XmlNode(Item, '/%s/Header' % Key), 'Header', True, IsStandAlongModule)
+ Module.SetBinaryModule(IsBinaryModule)
+
+ if IsBinaryModule:
+ GlobalData.gIS_BINARY_INF = True
+
+ #
+ # ModuleProperties
+ #
+ Tmp = ModulePropertyXml()
+ (Module, BootModes, Events, HOBs) = \
+ Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/ModuleProperties'), 'ModuleProperties', Module)
+ Module.SetBootModeList(BootModes)
+ Module.SetEventList(Events)
+ Module.SetHobList(HOBs)
+ #
+ # ClonedFrom
+ #
+ Tmp = ClonedFromXml()
+ ClonedFrom = Tmp.FromXml(XmlNode(Item, '/ModuleSurfaceArea/ClonedFrom'), 'ClonedFrom')
+ if ClonedFrom:
+ Module.SetClonedFrom(ClonedFrom)
+
+ #
+ # LibraryClass
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass'):
+ Tmp = LibraryClassXml()
+ LibraryClass = Tmp.FromXml(SubItem, 'LibraryClass')
+ Module.SetLibraryClassList(Module.GetLibraryClassList() + [LibraryClass])
+
+ if XmlList(Item, '/ModuleSurfaceArea/LibraryClassDefinitions') and \
+ not XmlList(Item, '/ModuleSurfaceArea/LibraryClassDefinitions/LibraryClass'):
+ Module.SetLibraryClassList([None])
+
+ #
+ # SourceFiles
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/SourceFiles/Filename'):
+ Tmp = SourceFileXml()
+ SourceFile = Tmp.FromXml(SubItem, 'Filename')
+ Module.SetSourceFileList(Module.GetSourceFileList() + [SourceFile])
+
+ if XmlList(Item, '/ModuleSurfaceArea/SourceFiles') and \
+ not XmlList(Item, '/ModuleSurfaceArea/SourceFiles/Filename') :
+ Module.SetSourceFileList([None])
+
+ #
+ # BinaryFile
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/BinaryFiles/BinaryFile'):
+ Tmp = BinaryFileXml()
+ BinaryFile = Tmp.FromXml(SubItem, 'BinaryFile')
+ Module.SetBinaryFileList(Module.GetBinaryFileList() + [BinaryFile])
+
+ if XmlList(Item, '/ModuleSurfaceArea/BinaryFiles') and \
+ not XmlList(Item, '/ModuleSurfaceArea/BinaryFiles/BinaryFile') :
+ Module.SetBinaryFileList([None])
+ #
+ # PackageDependencies
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/PackageDependencies/Package'):
+ Tmp = PackageXml()
+ PackageDependency = Tmp.FromXml(SubItem, 'Package')
+ Module.SetPackageDependencyList(Module.GetPackageDependencyList() + [PackageDependency])
+
+ if XmlList(Item, '/ModuleSurfaceArea/PackageDependencies') and \
+ not XmlList(Item, '/ModuleSurfaceArea/PackageDependencies/Package'):
+ Module.SetPackageDependencyList([None])
+
+ #
+ # Guid
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/Guids/GuidCName'):
+ Tmp = GuidXml('Module')
+ GuidProtocolPpi = Tmp.FromXml(SubItem, 'GuidCName')
+ Module.SetGuidList(Module.GetGuidList() + [GuidProtocolPpi])
+
+ if XmlList(Item, '/ModuleSurfaceArea/Guids') and not XmlList(Item, '/ModuleSurfaceArea/Guids/GuidCName'):
+ Module.SetGuidList([None])
+
+ #
+ # Protocol
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/Protocols/Protocol'):
+ Tmp = ProtocolXml('Module')
+ GuidProtocolPpi = Tmp.FromXml(SubItem, 'Protocol')
+ Module.SetProtocolList(Module.GetProtocolList() + [GuidProtocolPpi])
+
+ if XmlList(Item, '/ModuleSurfaceArea/Protocols') and not XmlList(Item, '/ModuleSurfaceArea/Protocols/Protocol'):
+ Module.SetProtocolList([None])
+
+ #
+ # Ppi
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/PPIs/Ppi'):
+ Tmp = PpiXml('Module')
+ GuidProtocolPpi = Tmp.FromXml(SubItem, 'Ppi')
+ Module.SetPpiList(Module.GetPpiList() + [GuidProtocolPpi])
+
+ if XmlList(Item, '/ModuleSurfaceArea/PPIs') and not XmlList(Item, '/ModuleSurfaceArea/PPIs/Ppi'):
+ Module.SetPpiList([None])
+
+ #
+ # Extern
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/Externs/Extern'):
+ Tmp = ExternXml()
+ Extern = Tmp.FromXml(SubItem, 'Extern')
+ Module.SetExternList(Module.GetExternList() + [Extern])
+
+ if XmlList(Item, '/ModuleSurfaceArea/Externs') and not XmlList(Item, '/ModuleSurfaceArea/Externs/Extern'):
+ Module.SetExternList([None])
+
+ if not Module.GetBinaryModule():
+ #
+ # PcdCoded
+ #
+ for SubItem in XmlList(Item, '/ModuleSurfaceArea/PcdCoded/PcdEntry'):
+ Tmp = PcdEntryXml()
+ PcdEntry = Tmp.FromXml3(SubItem, 'PcdEntry')
+ Module.SetPcdList(Module.GetPcdList() + [PcdEntry])
+
+ if XmlList(Item, '/ModuleSurfaceArea/PcdCoded') and \
+ not XmlList(Item, '/ModuleSurfaceArea/PcdCoded/PcdEntry'):
+ Module.SetPcdList([None])
+
+ Module = self.FromXml2(Item, Module)
+ #
+ # return the module object
+ #
+ self.Module = Module
+ return self.Module
+
+ def ToXml(self, Module):
+ if self.Package:
+ pass
+ #
+ # Create root node of module surface area
+ #
+ DomModule = minidom.Document().createElement('ModuleSurfaceArea')
+ if Module.GetBinaryModule():
+ DomModule.setAttribute('BinaryModule', 'true')
+
+ #
+ # Header
+ #
+ Tmp = HeaderXml()
+ DomModule.appendChild(Tmp.ToXml(Module, 'Header'))
+ #
+ # ModuleProperties
+ #
+ Tmp = ModulePropertyXml()
+ DomModule.appendChild(Tmp.ToXml(Module, Module.GetBootModeList(), Module.GetEventList(), Module.GetHobList(), \
+ 'ModuleProperties'))
+ #
+ # ClonedFrom
+ #
+ Tmp = ClonedFromXml()
+ if Module.GetClonedFrom():
+ DomModule.appendChild(Tmp.ToXml(Module.GetClonedFrom(), 'ClonedFrom'))
+ #
+ # LibraryClass
+ #
+ LibraryClassNode = CreateXmlElement('LibraryClassDefinitions', '', [], [])
+ for LibraryClass in Module.GetLibraryClassList():
+ Tmp = LibraryClassXml()
+ LibraryClassNode.appendChild(Tmp.ToXml2(LibraryClass, 'LibraryClass'))
+ DomModule.appendChild(LibraryClassNode)
+ #
+ # SourceFile
+ #
+ SourceFileNode = CreateXmlElement('SourceFiles', '', [], [])
+ for SourceFile in Module.GetSourceFileList():
+ Tmp = SourceFileXml()
+ SourceFileNode.appendChild(Tmp.ToXml(SourceFile, 'Filename'))
+ DomModule.appendChild(SourceFileNode)
+ #
+ # BinaryFile
+ #
+ BinaryFileNode = CreateXmlElement('BinaryFiles', '', [], [])
+ for BinaryFile in Module.GetBinaryFileList():
+ Tmp = BinaryFileXml()
+ BinaryFileNode.appendChild(Tmp.ToXml(BinaryFile, 'BinaryFile'))
+ DomModule.appendChild(BinaryFileNode)
+ #
+ # PackageDependencies
+ #
+ PackageDependencyNode = CreateXmlElement('PackageDependencies', '', [], [])
+ for PackageDependency in Module.GetPackageDependencyList():
+ Tmp = PackageXml()
+ PackageDependencyNode.appendChild(Tmp.ToXml(PackageDependency, 'Package'))
+ DomModule.appendChild(PackageDependencyNode)
+
+ #
+ # Guid
+ #
+ GuidProtocolPpiNode = CreateXmlElement('Guids', '', [], [])
+ for GuidProtocolPpi in Module.GetGuidList():
+ Tmp = GuidXml('Module')
+ GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'GuidCName'))
+ DomModule.appendChild(GuidProtocolPpiNode)
+
+ #
+ # Protocol
+ #
+ GuidProtocolPpiNode = CreateXmlElement('Protocols', '', [], [])
+ for GuidProtocolPpi in Module.GetProtocolList():
+ Tmp = ProtocolXml('Module')
+ GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Protocol'))
+ DomModule.appendChild(GuidProtocolPpiNode)
+
+ #
+ # Ppi
+ #
+ GuidProtocolPpiNode = CreateXmlElement('PPIs', '', [], [])
+ for GuidProtocolPpi in Module.GetPpiList():
+ Tmp = PpiXml('Module')
+ GuidProtocolPpiNode.appendChild(Tmp.ToXml(GuidProtocolPpi, 'Ppi'))
+ DomModule.appendChild(GuidProtocolPpiNode)
+ #
+ # Extern
+ #
+ ExternNode = CreateXmlElement('Externs', '', [], [])
+ for Extern in Module.GetExternList():
+ Tmp = ExternXml()
+ ExternNode.appendChild(Tmp.ToXml(Extern, 'Extern'))
+ DomModule.appendChild(ExternNode)
+ #
+ # PcdCoded
+ #
+ PcdEntryNode = CreateXmlElement('PcdCoded', '', [], [])
+ for PcdEntry in Module.GetPcdList():
+ Tmp = PcdEntryXml()
+ PcdEntryNode.appendChild(Tmp.ToXml3(PcdEntry, 'PcdEntry'))
+ DomModule.appendChild(PcdEntryNode)
+
+ #
+ # PeiDepex
+ #
+ if Module.GetPeiDepex():
+ for Item in Module.GetPeiDepex():
+ Tmp = DepexXml()
+ DomModule.appendChild(Tmp.ToXml(Item, 'PeiDepex'))
+
+ #
+ # DxeDepex
+ #
+ if Module.GetDxeDepex():
+ for Item in Module.GetDxeDepex():
+ Tmp = DepexXml()
+ DomModule.appendChild(Tmp.ToXml(Item, 'DxeDepex'))
+
+ #
+ # SmmDepex
+ #
+ if Module.GetSmmDepex():
+ for Item in Module.GetSmmDepex():
+ Tmp = DepexXml()
+ DomModule.appendChild(Tmp.ToXml(Item, 'SmmDepex'))
+
+ #
+ # MiscellaneousFile
+ #
+ if Module.GetMiscFileList():
+ Tmp = MiscellaneousFileXml()
+ DomModule.appendChild(Tmp.ToXml(Module.GetMiscFileList()[0], 'MiscellaneousFiles'))
+ #
+ # UserExtensions
+ #
+ if Module.GetUserExtensionList():
+ for UserExtension in Module.GetUserExtensionList():
+ Tmp = UserExtensionsXml()
+ DomModule.appendChild(Tmp.ToXml(UserExtension, 'UserExtensions'))
+
+ return DomModule
+
+##
+# BuildFlagXml used to generate BuildFlag for <AsBuilt>
+#
+class BuildFlagXml(object):
+ def __init__(self):
+ self.Target = ''
+ self.TagName = ''
+ self.Family = ''
+ self.AsBuiltFlags = ''
+
+ def FromXml(self, Item, Key):
+ self.Target = XmlElement(Item, '%s/Target' % Key)
+ self.TagName = XmlElement(Item, '%s/TagName' % Key)
+ self.Family = XmlElement(Item, '%s/Family' % Key)
+
+ BuildFlag = BinaryBuildFlagObject()
+
+ BuildFlag.SetTarget(self.Target)
+ BuildFlag.SetTagName(self.TagName)
+ BuildFlag.SetFamily(self.Family)
+
+ return BuildFlag
+
+ #
+ # For AsBuild INF usage
+ #
+ def FromXml2(self, Item, Key):
+ self.AsBuiltFlags = XmlElement(Item, '%s' % Key)
+
+ LineList = GetSplitValueList(self.AsBuiltFlags, '\n')
+ ReturnLine = ''
+ Count = 0
+ for Line in LineList:
+ if Count == 0:
+ ReturnLine = "# " + Line
+ else:
+ ReturnLine = ReturnLine + '\n' + '# ' + Line
+ Count += 1
+
+ BuildFlag = BinaryBuildFlagObject()
+ BuildFlag.SetAsBuiltOptionFlags(ReturnLine)
+
+ return BuildFlag
+
+ def ToXml(self, BuildFlag, Key):
+ if self.Target:
+ pass
+ AttributeList = []
+ NodeList = []
+ NodeList.append(['BuildFlags', BuildFlag])
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+ return Root
diff --git a/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py b/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py
new file mode 100644
index 0000000000..f340805f32
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/PackageSurfaceAreaXml.py
@@ -0,0 +1,397 @@
+## @file
+# This file is used to parse a Package file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+PackageSurfaceAreaXml
+'''
+from xml.dom import minidom
+
+from Library.String import GetStringOfList
+from Library.Xml.XmlRoutines import XmlElement
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import XmlList
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Object.POM.CommonObject import IncludeObject
+from Object.POM.CommonObject import TextObject
+from Object.POM.PackageObject import PackageObject
+from Xml.CommonXml import ClonedFromXml
+from Xml.CommonXml import PackageHeaderXml
+from Xml.CommonXml import HelpTextXml
+from Xml.CommonXml import CommonDefinesXml
+from Xml.CommonXml import LibraryClassXml
+from Xml.CommonXml import UserExtensionsXml
+from Xml.CommonXml import MiscellaneousFileXml
+from Xml.GuidProtocolPpiXml import GuidXml
+from Xml.GuidProtocolPpiXml import ProtocolXml
+from Xml.GuidProtocolPpiXml import PpiXml
+from Xml.ModuleSurfaceAreaXml import ModuleSurfaceAreaXml
+from Xml.PcdXml import PcdEntryXml
+
+##
+# IndustryStandardHeaderXml
+#
+class IndustryStandardHeaderXml(object):
+ def __init__(self):
+ self.HeaderFile = ''
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.HeaderFile = XmlElement(Item, '%s/HeaderFile' % Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ Include = IncludeObject()
+ Include.SetFilePath(self.HeaderFile)
+ HelpTxt = TextObject()
+ HelpTxt.SetString(self.HelpText)
+ Include.SetHelpText(HelpTxt)
+
+ return Include
+
+ def ToXml(self, IndustryStandardHeader, Key):
+ if self.HeaderFile:
+ pass
+ AttributeList = []
+ NodeList = [['HeaderFile', IndustryStandardHeader.GetFilePath()]]
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ Str = "HeaderFile = %s" % (self.HeaderFile)
+ for Item in self.HelpText:
+ Str = Str + "\n\t" + str(Item)
+ return Str
+##
+# PackageIncludeHeaderXml
+#
+class PackageIncludeHeaderXml(object):
+ def __init__(self):
+ self.HeaderFile = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+
+ def FromXml(self, Item, Key):
+ self.HeaderFile = XmlElement(Item, '%s/HeaderFile' % Key)
+ self.CommonDefines.FromXml(XmlNode(Item, '%s/HeaderFile' % Key), 'HeaderFile')
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+
+ Include = IncludeObject()
+ Include.SetFilePath(self.HeaderFile)
+ Include.SetSupArchList(self.CommonDefines.SupArchList)
+ HelpTxt = TextObject()
+ HelpTxt.SetString(self.HelpText)
+ Include.SetHelpText(HelpTxt)
+
+ return Include
+
+ def ToXml(self, PackageIncludeHeader, Key):
+ if self.HeaderFile:
+ pass
+ AttributeList = [['SupArchList', GetStringOfList(PackageIncludeHeader.GetSupArchList())], \
+ ['SupModList', GetStringOfList(PackageIncludeHeader.GetSupModuleList())], ]
+
+ HeaderFileNode = CreateXmlElement('HeaderFile', PackageIncludeHeader.FilePath, [], AttributeList)
+
+ NodeList = [HeaderFileNode]
+ for Item in PackageIncludeHeader.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, [])
+
+ return Root
+
+ def __str__(self):
+ Str = "HeaderFile = %s\n\t%s" % (self.HeaderFile, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + "\n\t" + str(Item)
+ return Str
+
+##
+# PcdCheckXml
+#
+class PcdCheckXml(object):
+ def __init__(self):
+ self.PcdCheck = ''
+
+ def FromXml(self, Item, Key):
+ if Key:
+ pass
+ self.PcdCheck = XmlElement(Item, 'PcdCheck')
+
+ return self.PcdCheck
+
+ def ToXml(self, PcdCheck, Key):
+ if self.PcdCheck:
+ pass
+ Root = CreateXmlElement('%s' % Key, PcdCheck, [], [])
+ return Root
+
+ def __str__(self):
+ return "PcdCheck = %s" % (self.PcdCheck)
+
+##
+# PackageSurfaceAreaXml
+#
+class PackageSurfaceAreaXml(object):
+ def __init__(self):
+ self.Package = None
+
+ def FromXml(self, Item, Key):
+ if Key:
+ pass
+ #
+ # Create a package object
+ #
+ Package = PackageObject()
+ #
+ # Header
+ #
+ Tmp = PackageHeaderXml()
+ Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/Header'), 'Header', Package)
+ #
+ # ClonedFrom
+ #
+ Tmp = ClonedFromXml()
+ if XmlNode(Item, '/PackageSurfaceArea/ClonedFrom'):
+ ClonedFrom = Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/ClonedFrom'), 'ClonedFrom')
+ Package.SetClonedFromList([ClonedFrom])
+ #
+ # LibraryClass
+ #
+
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass'):
+ Tmp = LibraryClassXml()
+ LibraryClass = Tmp.FromXml(SubItem, 'LibraryClass')
+ Package.SetLibraryClassList(Package.GetLibraryClassList() + [LibraryClass])
+
+ if XmlList(Item, '/PackageSurfaceArea/LibraryClassDeclarations') and \
+ not XmlList(Item, '/PackageSurfaceArea/LibraryClassDeclarations/LibraryClass'):
+ Package.SetLibraryClassList([None])
+
+ #
+ # IndustryStandardHeader
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/IndustryStandardIncludes/IndustryStandardHeader'):
+ Tmp = IndustryStandardHeaderXml()
+ Include = Tmp.FromXml(SubItem, 'IndustryStandardHeader')
+ Package.SetStandardIncludeFileList(Package.GetStandardIncludeFileList() + [Include])
+
+ if XmlList(Item, '/PackageSurfaceArea/IndustryStandardIncludes') and \
+ not XmlList(Item, '/PackageSurfaceArea/IndustryStandardIncludes/IndustryStandardHeader'):
+ Package.SetStandardIncludeFileList([None])
+
+
+ #
+ # PackageHeader
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/PackageIncludes/PackageHeader'):
+ Tmp = PackageIncludeHeaderXml()
+ Include = Tmp.FromXml(SubItem, 'PackageHeader')
+ Package.SetPackageIncludeFileList(Package.GetPackageIncludeFileList() + [Include])
+
+ if XmlList(Item, '/PackageSurfaceArea/PackageIncludes') and not \
+ XmlList(Item, '/PackageSurfaceArea/PackageIncludes/PackageHeader'):
+ Package.SetPackageIncludeFileList([None])
+
+ #
+ # Guid
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/GuidDeclarations/Entry'):
+ Tmp = GuidXml('Package')
+ GuidProtocolPpi = Tmp.FromXml(SubItem, 'Entry')
+ Package.SetGuidList(Package.GetGuidList() + [GuidProtocolPpi])
+
+ if XmlList(Item, '/PackageSurfaceArea/GuidDeclarations') and not \
+ XmlList(Item, '/PackageSurfaceArea/GuidDeclarations/Entry'):
+ Package.SetGuidList([None])
+
+ #
+ # Protocol
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/ProtocolDeclarations/Entry'):
+ Tmp = ProtocolXml('Package')
+ GuidProtocolPpi = Tmp.FromXml(SubItem, 'Entry')
+ Package.SetProtocolList(Package.GetProtocolList() + [GuidProtocolPpi])
+
+ if XmlList(Item, '/PackageSurfaceArea/ProtocolDeclarations') and not \
+ XmlList(Item, '/PackageSurfaceArea/ProtocolDeclarations/Entry'):
+ Package.SetProtocolList([None])
+
+ #
+ # Ppi
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/PpiDeclarations/Entry'):
+ Tmp = PpiXml('Package')
+ GuidProtocolPpi = Tmp.FromXml(SubItem, 'Entry')
+ Package.SetPpiList(Package.GetPpiList() + [GuidProtocolPpi])
+
+ if XmlList(Item, '/PackageSurfaceArea/PpiDeclarations') and not \
+ XmlList(Item, '/PackageSurfaceArea/PpiDeclarations/Entry'):
+ Package.SetPpiList([None])
+
+ #
+ # PcdEntry
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/PcdDeclarations/PcdEntry'):
+ Tmp = PcdEntryXml()
+ PcdEntry = Tmp.FromXml2(SubItem, 'PcdEntry')
+ Package.SetPcdList(Package.GetPcdList() + [PcdEntry])
+
+ if XmlList(Item, '/PackageSurfaceArea/PcdDeclarations') and not \
+ XmlList(Item, '/PackageSurfaceArea/PcdDeclarations/PcdEntry'):
+ Package.SetPcdList([None])
+
+ #
+ # PcdCheck
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/PcdRelationshipChecks/PcdCheck'):
+ Tmp = PcdCheckXml()
+ PcdCheck = Tmp.FromXml(SubItem, 'PcdCheck')
+ Package.PcdChecks.append(PcdCheck)
+
+ #
+ # Modules
+ #
+ for SubItem in XmlList(Item, '/PackageSurfaceArea/Modules/ModuleSurfaceArea'):
+ Tmp = ModuleSurfaceAreaXml()
+ Module = Tmp.FromXml(SubItem, 'ModuleSurfaceArea')
+ Package.ModuleDict[(Module.GetGuid(), Module.GetVersion(), Module.GetModulePath())] = Module
+ #
+ # MiscellaneousFile
+ #
+ Tmp = MiscellaneousFileXml()
+ MiscFileList = Tmp.FromXml(XmlNode(Item, '/PackageSurfaceArea/MiscellaneousFiles'), 'MiscellaneousFiles')
+ if MiscFileList:
+ Package.SetMiscFileList([MiscFileList])
+ else:
+ Package.SetMiscFileList([])
+
+ #
+ # UserExtensions
+ #
+ for Item in XmlList(Item, '/PackageSurfaceArea/UserExtensions'):
+ Tmp = UserExtensionsXml()
+ UserExtension = Tmp.FromXml(Item, 'UserExtensions')
+ Package.UserExtensionList.append(UserExtension)
+
+ self.Package = Package
+ return self.Package
+
+ def ToXml(self, Package):
+ if self.Package:
+ pass
+ #
+ # Create PackageSurfaceArea node
+ #
+ DomPackage = minidom.Document().createElement('PackageSurfaceArea')
+ #
+ # Header
+ #
+ Tmp = PackageHeaderXml()
+ DomPackage.appendChild(Tmp.ToXml(Package, 'Header'))
+ #
+ # ClonedFrom
+ #
+ Tmp = ClonedFromXml()
+ if Package.GetClonedFromList() != []:
+ DomPackage.appendChild(Tmp.ToXml(Package.GetClonedFromList[0], 'ClonedFrom'))
+ #
+ # LibraryClass
+ #
+ LibraryClassNode = CreateXmlElement('LibraryClassDeclarations', '', [], [])
+ for LibraryClass in Package.GetLibraryClassList():
+ Tmp = LibraryClassXml()
+ LibraryClassNode.appendChild(Tmp.ToXml(LibraryClass, 'LibraryClass'))
+ DomPackage.appendChild(LibraryClassNode)
+ #
+ # IndustryStandardHeader
+ #
+ IndustryStandardHeaderNode = CreateXmlElement('IndustryStandardIncludes', '', [], [])
+ for Include in Package.GetStandardIncludeFileList():
+ Tmp = IndustryStandardHeaderXml()
+ IndustryStandardHeaderNode.appendChild(Tmp.ToXml(Include, 'IndustryStandardHeader'))
+ DomPackage.appendChild(IndustryStandardHeaderNode)
+ #
+ # PackageHeader
+ #
+ PackageIncludeHeaderNode = CreateXmlElement('PackageIncludes', '', [], [])
+ for Include in Package.GetPackageIncludeFileList():
+ Tmp = PackageIncludeHeaderXml()
+ PackageIncludeHeaderNode.appendChild(Tmp.ToXml(Include, 'PackageHeader'))
+ DomPackage.appendChild(PackageIncludeHeaderNode)
+ ModuleNode = CreateXmlElement('Modules', '', [], [])
+ for Module in Package.GetModuleDict().values():
+ Tmp = ModuleSurfaceAreaXml()
+ ModuleNode.appendChild(Tmp.ToXml(Module))
+ DomPackage.appendChild(ModuleNode)
+ #
+ # Guid
+ #
+ GuidProtocolPpiNode = CreateXmlElement('GuidDeclarations', '', [], [])
+ for GuidProtocolPpi in Package.GetGuidList():
+ Tmp = GuidXml('Package')
+ GuidProtocolPpiNode.appendChild(Tmp.ToXml\
+ (GuidProtocolPpi, 'Entry'))
+ DomPackage.appendChild(GuidProtocolPpiNode)
+ #
+ # Protocol
+ #
+ GuidProtocolPpiNode = \
+ CreateXmlElement('ProtocolDeclarations', '', [], [])
+ for GuidProtocolPpi in Package.GetProtocolList():
+ Tmp = ProtocolXml('Package')
+ GuidProtocolPpiNode.appendChild\
+ (Tmp.ToXml(GuidProtocolPpi, 'Entry'))
+ DomPackage.appendChild(GuidProtocolPpiNode)
+ #
+ # Ppi
+ #
+ GuidProtocolPpiNode = CreateXmlElement('PpiDeclarations', '', [], [])
+ for GuidProtocolPpi in Package.GetPpiList():
+ Tmp = PpiXml('Package')
+ GuidProtocolPpiNode.appendChild\
+ (Tmp.ToXml(GuidProtocolPpi, 'Entry'))
+ DomPackage.appendChild(GuidProtocolPpiNode)
+ #
+ # PcdEntry
+ #
+ PcdEntryNode = CreateXmlElement('PcdDeclarations', '', [], [])
+ for PcdEntry in Package.GetPcdList():
+ Tmp = PcdEntryXml()
+ PcdEntryNode.appendChild(Tmp.ToXml2(PcdEntry, 'PcdEntry'))
+ DomPackage.appendChild(PcdEntryNode)
+
+ #
+ # MiscellaneousFile
+ #
+ Tmp = MiscellaneousFileXml()
+ if Package.GetMiscFileList():
+ DomPackage.appendChild(Tmp.ToXml(Package.GetMiscFileList()[0], 'MiscellaneousFiles'))
+
+ #
+ # UserExtensions
+ #
+ if Package.GetUserExtensionList():
+ for UserExtension in Package.GetUserExtensionList():
+ Tmp = UserExtensionsXml()
+ DomPackage.appendChild(Tmp.ToXml(UserExtension, 'UserExtensions'))
+
+ return DomPackage
diff --git a/BaseTools/Source/Python/UPT/Xml/PcdXml.py b/BaseTools/Source/Python/UPT/Xml/PcdXml.py
new file mode 100644
index 0000000000..d1f1332726
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/PcdXml.py
@@ -0,0 +1,403 @@
+## @file
+# This file is used to parse a PCD file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+PcdXml
+'''
+
+##
+# Import Modules
+#
+
+from Library.Xml.XmlRoutines import XmlElement
+from Library.Xml.XmlRoutines import XmlAttribute
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Library.Xml.XmlRoutines import XmlList
+from Library.String import GetStringOfList
+from Library.String import ConvertNEToNOTEQ
+from Library.String import ConvertNOTEQToNE
+from Library import GlobalData
+from Object.POM.CommonObject import PcdObject
+from Object.POM.CommonObject import PcdErrorObject
+from Xml.CommonXml import HelpTextXml
+from Xml.CommonXml import CommonDefinesXml
+from Xml.XmlParserMisc import GetHelpTextList
+
+##
+# PcdErrorXml
+#
+class PcdErrorXml(object):
+ def __init__(self):
+ self.ValidValueList = ''
+ self.ValidValueListLang = ''
+ self.ValidValueRange = ''
+ self.Expression = ''
+ self.ErrorNumber = ''
+ self.ErrorMessage = []
+
+ def FromXml(self, Item, Key):
+ self.ValidValueList = XmlElement(Item, '%s/ValidValueList' % Key)
+ self.ValidValueListLang = \
+ XmlAttribute(XmlNode(Item, '%s/ValidValueList' % Key), 'Lang')
+ self.ValidValueRange = XmlElement(Item, '%s/ValidValueRange' % Key)
+ self.Expression = XmlElement(Item, '%s/Expression' % Key)
+ self.ErrorNumber = XmlElement(Item, '%s/ErrorNumber' % Key)
+ for ErrMsg in XmlList(Item, '%s/ErrorMessage' % Key):
+ ErrorMessageString = XmlElement(ErrMsg, 'ErrorMessage')
+ ErrorMessageLang = \
+ XmlAttribute(XmlNode(ErrMsg, 'ErrorMessage'), 'Lang')
+ self.ErrorMessage.append((ErrorMessageLang, ErrorMessageString))
+
+ Error = PcdErrorObject()
+ Error.SetValidValue(self.ValidValueList)
+ Error.SetValidValueLang(self.ValidValueListLang)
+ Error.SetValidValueRange(self.ValidValueRange)
+ Error.SetExpression(self.Expression)
+ Error.SetErrorNumber(self.ErrorNumber)
+ Error.SetErrorMessageList(self.ErrorMessage)
+
+ return Error
+
+ def ToXml(self, PcdError, Key):
+ if self.Expression:
+ pass
+ AttributeList = []
+ NodeList = []
+ if PcdError.GetValidValue():
+ Element1 = \
+ CreateXmlElement('ValidValueList', PcdError.GetValidValue(), [], \
+ [['Lang', PcdError.GetValidValueLang()]])
+ NodeList.append(Element1)
+ if PcdError.GetValidValueRange():
+ Element1 = \
+ CreateXmlElement('ValidValueRange', \
+ PcdError.GetValidValueRange(), [], [])
+ NodeList.append(Element1)
+ if PcdError.GetExpression():
+ NodeList.append(['Expression', PcdError.GetExpression()])
+ if PcdError.GetErrorNumber():
+ NodeList.append(['ErrorNumber', PcdError.GetErrorNumber()])
+ for Item in PcdError.GetErrorMessageList():
+ Element = \
+ CreateXmlElement('ErrorMessage', Item[1], [], [['Lang', Item[0]]])
+ NodeList.append(Element)
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ def __str__(self):
+ return "ValidValueList = %s ValidValueListLang = %s ValidValueRange \
+ = %s Expression = %s ErrorNumber = %s %s" % \
+ (self.ValidValueList, self.ValidValueListLang, self.ValidValueRange, \
+ self.Expression, self.ErrorNumber, self.ErrorMessage)
+
+##
+# PcdEntryXml
+#
+class PcdEntryXml(object):
+ def __init__(self):
+ self.PcdItemType = ''
+ self.PcdUsage = ''
+ self.TokenSpaceGuidCName = ''
+ self.TokenSpaceGuidValue = ''
+ self.Token = ''
+ self.CName = ''
+ self.PcdCName = ''
+ self.DatumType = ''
+ self.ValidUsage = ''
+ self.DefaultValue = ''
+ self.MaxDatumSize = ''
+ self.Value = ''
+ self.Offset = ''
+ self.CommonDefines = CommonDefinesXml()
+ self.HelpText = []
+ self.PcdError = []
+
+ ##
+ # AsBuilt will use FromXml
+ #
+ def FromXml(self, Item, Key):
+ self.PcdItemType = \
+ XmlAttribute(XmlNode(Item, '%s' % Key), 'PcdItemType')
+ self.PcdUsage = XmlAttribute(XmlNode(Item, '%s' % Key), 'PcdUsage')
+ self.TokenSpaceGuidCName = \
+ XmlElement(Item, '%s/TokenSpaceGuidCname' % Key)
+ self.TokenSpaceGuidValue = \
+ XmlElement(Item, '%s/TokenSpaceGuidValue' % Key)
+ self.Token = XmlElement(Item, '%s/Token' % Key)
+ self.CName = XmlElement(Item, '%s/CName' % Key)
+ self.PcdCName = XmlElement(Item, '%s/PcdCName' % Key)
+ self.DatumType = XmlElement(Item, '%s/DatumType' % Key)
+ self.ValidUsage = XmlElement(Item, '%s/ValidUsage' % Key)
+ if not GlobalData.gIS_BINARY_INF:
+ self.DefaultValue = XmlElement(Item, '%s/DefaultValue' % Key)
+ else:
+ self.DefaultValue = XmlElement(Item, '%s/Value' % Key)
+ self.MaxDatumSize = XmlElement(Item, '%s/MaxDatumSize' % Key)
+ self.Value = XmlElement(Item, '%s/Value' % Key)
+ self.Offset = XmlElement(Item, '%s/Offset' % Key)
+ self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+ for PcdErrorItem in XmlList(Item, '%s/PcdError' % Key):
+ PcdErrorObjXml = PcdErrorXml()
+ PcdErrorObj = PcdErrorObjXml.FromXml(PcdErrorItem, 'PcdError')
+ self.PcdError.append(PcdErrorObj)
+
+ self.DefaultValue = ConvertNOTEQToNE(self.DefaultValue)
+
+ PcdEntry = PcdObject()
+ PcdEntry.SetSupArchList(self.CommonDefines.SupArchList)
+ PcdEntry.SetTokenSpaceGuidCName(self.TokenSpaceGuidCName)
+ PcdEntry.SetTokenSpaceGuidValue(self.TokenSpaceGuidValue)
+ PcdEntry.SetToken(self.Token)
+ PcdEntry.SetOffset(self.Offset)
+ PcdEntry.SetCName(self.CName)
+ PcdEntry.SetPcdCName(self.PcdCName)
+ PcdEntry.SetDatumType(self.DatumType)
+ PcdEntry.SetValidUsage(self.ValidUsage)
+ PcdEntry.SetDefaultValue(self.DefaultValue)
+ PcdEntry.SetMaxDatumSize(self.MaxDatumSize)
+ PcdEntry.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ PcdEntry.SetItemType(self.PcdItemType)
+
+ PcdEntry.SetHelpTextList(GetHelpTextList(self.HelpText))
+ PcdEntry.SetPcdErrorsList(self.PcdError)
+
+ return PcdEntry
+ ##
+ # Package will use FromXml2
+ #
+ def FromXml2(self, Item, Key):
+ self.TokenSpaceGuidCName = \
+ XmlElement(Item, '%s/TokenSpaceGuidCname' % Key)
+ self.Token = XmlElement(Item, '%s/Token' % Key)
+ self.CName = XmlElement(Item, '%s/CName' % Key)
+ self.DatumType = XmlElement(Item, '%s/DatumType' % Key)
+ self.ValidUsage = XmlElement(Item, '%s/ValidUsage' % Key)
+ self.DefaultValue = XmlElement(Item, '%s/DefaultValue' % Key)
+ self.MaxDatumSize = XmlElement(Item, '%s/MaxDatumSize' % Key)
+ self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+ for PcdErrorItem in XmlList(Item, '%s/PcdError' % Key):
+ PcdErrorObjXml = PcdErrorXml()
+ PcdErrorObj = PcdErrorObjXml.FromXml(PcdErrorItem, 'PcdError')
+ self.PcdError.append(PcdErrorObj)
+
+ self.DefaultValue = ConvertNOTEQToNE(self.DefaultValue)
+
+ PcdEntry = PcdObject()
+ PcdEntry.SetSupArchList(self.CommonDefines.SupArchList)
+ PcdEntry.SetSupModuleList(self.CommonDefines.SupModList)
+ PcdEntry.SetTokenSpaceGuidCName(self.TokenSpaceGuidCName)
+ PcdEntry.SetToken(self.Token)
+ PcdEntry.SetCName(self.CName)
+ PcdEntry.SetDatumType(self.DatumType)
+ PcdEntry.SetValidUsage(self.ValidUsage)
+ PcdEntry.SetDefaultValue(self.DefaultValue)
+ PcdEntry.SetMaxDatumSize(self.MaxDatumSize)
+ PcdEntry.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+
+ PcdEntry.SetHelpTextList(GetHelpTextList(self.HelpText))
+ PcdEntry.SetPcdErrorsList(self.PcdError)
+
+ return PcdEntry
+
+ ##
+ # Module will use FromXml3
+ #
+ def FromXml3(self, Item, Key):
+ self.PcdItemType = \
+ XmlAttribute(XmlNode(Item, '%s' % Key), 'PcdItemType')
+ self.PcdUsage = XmlAttribute(XmlNode(Item, '%s' % Key), 'PcdUsage')
+ self.TokenSpaceGuidCName = \
+ XmlElement(Item, '%s/TokenSpaceGuidCName' % Key)
+ self.CName = XmlElement(Item, '%s/CName' % Key)
+ self.DefaultValue = XmlElement(Item, '%s/DefaultValue' % Key)
+ self.CommonDefines.FromXml(XmlNode(Item, '%s' % Key), Key)
+ for HelpTextItem in XmlList(Item, '%s/HelpText' % Key):
+ HelpTextObj = HelpTextXml()
+ HelpTextObj.FromXml(HelpTextItem, '%s/HelpText' % Key)
+ self.HelpText.append(HelpTextObj)
+ for PcdErrorItem in XmlList(Item, '%s/PcdError' % Key):
+ PcdErrorObj = PcdErrorXml()
+ PcdErrorObj.FromXml(PcdErrorItem, 'PcdError')
+ self.PcdError.append(PcdErrorObj)
+
+ self.DefaultValue = ConvertNOTEQToNE(self.DefaultValue)
+
+ PcdEntry = PcdObject()
+ PcdEntry.SetSupArchList(self.CommonDefines.SupArchList)
+ PcdEntry.SetTokenSpaceGuidCName(self.TokenSpaceGuidCName)
+ PcdEntry.SetCName(self.CName)
+ PcdEntry.SetValidUsage(self.PcdUsage)
+ PcdEntry.SetDefaultValue(self.DefaultValue)
+ PcdEntry.SetFeatureFlag(ConvertNOTEQToNE(self.CommonDefines.FeatureFlag))
+ PcdEntry.SetItemType(self.PcdItemType)
+
+ PcdEntry.SetHelpTextList(GetHelpTextList(self.HelpText))
+ PcdEntry.SetPcdErrorsList(self.PcdError)
+
+ return PcdEntry
+
+ def ToXml(self, PcdEntry, Key):
+ if self.PcdCName:
+ pass
+
+ DefaultValue = ConvertNEToNOTEQ(PcdEntry.GetDefaultValue())
+
+ AttributeList = \
+ [['SupArchList', GetStringOfList(PcdEntry.GetSupArchList())], \
+ ['PcdUsage', PcdEntry.GetValidUsage()], \
+ ['PcdItemType', PcdEntry.GetItemType()], \
+ ['FeatureFlag', PcdEntry.GetFeatureFlag()],
+ ]
+ NodeList = [['TokenSpaceGuidCname', PcdEntry.GetTokenSpaceGuidCName()],
+ ['TokenSpaceGuidValue', PcdEntry.GetTokenSpaceGuidValue()],
+ ['Token', PcdEntry.GetToken()],
+ ['CName', PcdEntry.GetCName()],
+ ['DatumType', PcdEntry.GetDatumType()],
+ ['ValidUsage', GetStringOfList(PcdEntry.GetValidUsage())],
+ ['DefaultValue', DefaultValue],
+ ['MaxDatumSize', PcdEntry.GetMaxDatumSize()],
+ ['Offset', PcdEntry.GetOffset()],
+ ]
+
+ for Item in PcdEntry.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ for Item in PcdEntry.GetPcdErrorsList():
+ Tmp = PcdErrorXml()
+ NodeList.append(Tmp.ToXml(Item, 'PcdError'))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+ ##
+ # Package will use ToXml2
+ #
+ def ToXml2(self, PcdEntry, Key):
+ if self.PcdCName:
+ pass
+
+ DefaultValue = ConvertNEToNOTEQ(PcdEntry.GetDefaultValue())
+
+ AttributeList = \
+ [['SupArchList', GetStringOfList(PcdEntry.GetSupArchList())], \
+ ['SupModList', GetStringOfList(PcdEntry.GetSupModuleList())]
+ ]
+ NodeList = [['TokenSpaceGuidCname', PcdEntry.GetTokenSpaceGuidCName()],
+ ['Token', PcdEntry.GetToken()],
+ ['CName', PcdEntry.GetCName()],
+ ['DatumType', PcdEntry.GetDatumType()],
+ ['ValidUsage', GetStringOfList(PcdEntry.GetValidUsage())],
+ ['DefaultValue', DefaultValue],
+ ['MaxDatumSize', PcdEntry.GetMaxDatumSize()],
+ ]
+ for Item in PcdEntry.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+
+ for Item in PcdEntry.GetPcdErrorsList():
+ Tmp = PcdErrorXml()
+ NodeList.append(Tmp.ToXml(Item, 'PcdError'))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+ ##
+ # Module will use ToXml3
+ #
+ def ToXml3(self, PcdEntry, Key):
+ if self.PcdCName:
+ pass
+
+ DefaultValue = ConvertNEToNOTEQ(PcdEntry.GetDefaultValue())
+
+ AttributeList = \
+ [['SupArchList', GetStringOfList(PcdEntry.GetSupArchList())], \
+ ['PcdUsage', PcdEntry.GetValidUsage()], \
+ ['PcdItemType', PcdEntry.GetItemType()], \
+ ['FeatureFlag', ConvertNEToNOTEQ(PcdEntry.GetFeatureFlag())],
+ ]
+ NodeList = [['CName', PcdEntry.GetCName()],
+ ['TokenSpaceGuidCName', PcdEntry.GetTokenSpaceGuidCName()],
+ ['DefaultValue', DefaultValue],
+ ]
+
+ for Item in PcdEntry.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ for Item in PcdEntry.GetPcdErrorsList():
+ Tmp = PcdErrorXml()
+ NodeList.append(Tmp.ToXml(Item, 'PcdError'))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+ ##
+ # AsBuild Module will use ToXml4
+ #
+ def ToXml4(self, PcdEntry, Key):
+ if self.PcdCName:
+ pass
+
+ DefaultValue = ConvertNEToNOTEQ(PcdEntry.GetDefaultValue())
+
+ AttributeList = []
+
+ NodeList = [
+ ['TokenSpaceGuidValue', PcdEntry.GetTokenSpaceGuidValue()],
+ ['PcdCName', PcdEntry.GetCName()],
+ ['Token', PcdEntry.GetToken()],
+ ['DatumType', PcdEntry.GetDatumType()],
+ ['MaxDatumSize', PcdEntry.GetMaxDatumSize()],
+ ['Value', DefaultValue],
+ ['Offset', PcdEntry.GetOffset()]
+ ]
+
+ for Item in PcdEntry.GetHelpTextList():
+ Tmp = HelpTextXml()
+ NodeList.append(Tmp.ToXml(Item))
+ for Item in PcdEntry.GetPcdErrorsList():
+ Tmp = PcdErrorXml()
+ NodeList.append(Tmp.ToXml(Item, 'PcdError'))
+
+ Root = CreateXmlElement('%s' % Key, '', NodeList, AttributeList)
+
+ return Root
+
+
+ def __str__(self):
+ Str = \
+ ('PcdItemType = %s PcdUsage = %s TokenSpaceGuidCName = %s \
+ TokenSpaceGuidValue = %s Token = %s CName = %s PcdCName = %s \
+ DatumType = %s ValidUsage = %s DefaultValue = %s MaxDatumSize = %s \
+ Value = %s Offset = %s %s') % \
+ (self.PcdItemType, self.PcdUsage, self.TokenSpaceGuidCName, \
+ self.TokenSpaceGuidValue, self.Token, self.CName, self.PcdCName, \
+ self.DatumType, self.ValidUsage, self.DefaultValue, \
+ self.MaxDatumSize, self.Value, self.Offset, self.CommonDefines)
+ for Item in self.HelpText:
+ Str = Str + "\n\t" + str(Item)
+ for Item in self.PcdError:
+ Str = Str + "\n\tPcdError:" + str(Item)
+ return Str \ No newline at end of file
diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParser.py b/BaseTools/Source/Python/UPT/Xml/XmlParser.py
new file mode 100644
index 0000000000..adfeca81a0
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/XmlParser.py
@@ -0,0 +1,924 @@
+## @file
+# This file is used to parse a xml file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+XmlParser
+'''
+
+##
+# Import Modules
+#
+import re
+
+from Library.Xml.XmlRoutines import XmlNode
+from Library.Xml.XmlRoutines import CreateXmlElement
+from Library.Xml.XmlRoutines import XmlList
+from Library.Xml.XmlRoutines import XmlParseFile
+from Core.DistributionPackageClass import DistributionPackageClass
+from Object.POM.ModuleObject import DepexObject
+from Library.ParserValidate import IsValidInfMoudleType
+from Library.ParserValidate import IsValidInstallPath
+from Library.Misc import IsEqualList
+from Library.Misc import Sdict
+
+from Logger.StringTable import ERR_XML_INVALID_VARIABLENAME
+from Logger.StringTable import ERR_XML_INVALID_LIB_SUPMODLIST
+from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPARCHLIST
+from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST
+from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB
+from Logger.StringTable import ERR_FILE_NAME_INVALIDE
+from Logger.StringTable import ERR_XML_INVALID_BINARY_FILE_TYPE
+from Logger.ToolError import PARSER_ERROR
+from Logger.ToolError import FORMAT_INVALID
+
+from Xml.CommonXml import DistributionPackageHeaderXml
+from Xml.CommonXml import MiscellaneousFileXml
+from Xml.CommonXml import UserExtensionsXml
+from Xml.XmlParserMisc import ConvertVariableName
+from Xml.XmlParserMisc import IsRequiredItemListNull
+from Xml.ModuleSurfaceAreaXml import ModuleSurfaceAreaXml
+from Xml.PackageSurfaceAreaXml import PackageSurfaceAreaXml
+
+import Logger.Log as Logger
+
+##
+# DistributionPackageXml
+#
+class DistributionPackageXml(object):
+ def __init__(self):
+ self.DistP = DistributionPackageClass()
+ self.Pkg = ''
+
+ ## ValidateDistributionPackage
+ #
+ # Check if any required item is missing in DistributionPackage
+ #
+ def ValidateDistributionPackage(self):
+ XmlTreeLevel = ['DistributionPackage']
+ if self.DistP:
+ #
+ # Check DistributionPackage -> DistributionHeader
+ #
+ XmlTreeLevel = ['DistributionPackage', '']
+ CheckDict = {'DistributionHeader':self.DistP.Header }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if self.DistP.Header:
+ DpHeader = self.DistP.Header
+ XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
+ CheckDict = Sdict()
+ CheckDict['Name'] = DpHeader.GetName()
+ CheckDict['GUID'] = DpHeader.GetGuid()
+ CheckDict['Version'] = DpHeader.GetVersion()
+ CheckDict['Copyright'] = DpHeader.GetCopyright()
+ CheckDict['License'] = DpHeader.GetLicense()
+ CheckDict['Abstract'] = DpHeader.GetAbstract()
+ CheckDict['Vendor'] = DpHeader.GetVendor()
+ CheckDict['Date'] = DpHeader.GetDate()
+ CheckDict['XmlSpecification'] = DpHeader.GetXmlSpecification()
+
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ else:
+ XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
+ CheckDict = CheckDict = {'DistributionHeader':'', }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Each Package
+ #
+ for Key in self.DistP.PackageSurfaceArea:
+ ValidatePackageSurfaceArea(self.DistP.PackageSurfaceArea[Key])
+
+ #
+ # Check Each Module
+ #
+ for Key in self.DistP.ModuleSurfaceArea:
+ ValidateMS(self.DistP.ModuleSurfaceArea[Key], ['DistributionPackage', 'ModuleSurfaceArea'])
+
+ #
+ # Check Each Tool
+ #
+ if self.DistP.Tools:
+ XmlTreeLevel = ['DistributionPackage', 'Tools', 'Header']
+ CheckDict = {'Name':self.DistP.Tools.GetName(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if not self.DistP.Tools.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'Tools']
+ CheckDict = {'FileName':None, }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for Item in self.DistP.Tools.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'Tools']
+ CheckDict = {'FileName':Item.GetURI(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Each Misc File
+ #
+ if self.DistP.MiscellaneousFiles:
+ XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles', 'Header']
+ CheckDict = {'Name':self.DistP.MiscellaneousFiles.GetName(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if not self.DistP.MiscellaneousFiles.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
+ CheckDict = {'FileName':None, }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for Item in self.DistP.MiscellaneousFiles.GetFileList():
+ XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
+ CheckDict = {'FileName':Item.GetURI(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Each Distribution Level User Extension
+ #
+ for Item in self.DistP.UserExtensions:
+ XmlTreeLevel = ['DistributionPackage', 'UserExtensions']
+ CheckDict = {'UserId':Item.GetUserID(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+
+ def FromXml(self, Filename=None):
+ if Filename != None:
+ self.DistP = DistributionPackageClass()
+ #
+ # Load to XML
+ #
+ self.Pkg = XmlParseFile(Filename)
+
+ #
+ # Parse Header information
+ #
+ Tmp = DistributionPackageHeaderXml()
+ DistributionPackageHeader = \
+ Tmp.FromXml(XmlNode(self.Pkg, '/DistributionPackage/DistributionHeader'), 'DistributionHeader')
+ self.DistP.Header = DistributionPackageHeader
+ #
+ # Parse each PackageSurfaceArea
+ #
+ for Item in XmlList(self.Pkg, '/DistributionPackage/PackageSurfaceArea'):
+ Psa = PackageSurfaceAreaXml()
+ Package = Psa.FromXml(Item, 'PackageSurfaceArea')
+ self.DistP.PackageSurfaceArea[(Package.GetGuid(), \
+ Package.GetVersion(), \
+ Package.GetPackagePath())] = \
+ Package
+ #
+ # Parse each ModuleSurfaceArea
+ #
+ for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'):
+ Msa = ModuleSurfaceAreaXml()
+ Module = Msa.FromXml(Item, 'ModuleSurfaceArea', True)
+ self.DistP.ModuleSurfaceArea[(Module.GetGuid(), Module.GetVersion(), Module.GetModulePath())] = Module
+ #
+ # Parse Tools
+ #
+ Tmp = MiscellaneousFileXml()
+ self.DistP.Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools')
+
+ #
+ # Parse MiscFiles
+ #
+ Tmp = MiscellaneousFileXml()
+ self.DistP.MiscellaneousFiles = \
+ Tmp.FromXml2(XmlNode(self.Pkg, \
+ '/DistributionPackage/MiscellaneousFiles'), \
+ 'MiscellaneousFiles')
+
+ #
+ # Parse UserExtensions
+ #
+ for Item in XmlList(self.Pkg, '/DistributionPackage/UserExtensions'):
+ Tmp = UserExtensionsXml()
+ self.DistP.UserExtensions.append(Tmp.FromXml2(Item, 'UserExtensions'))
+
+ #
+ # Check Required Items for XML
+ #
+ self.ValidateDistributionPackage()
+
+ return self.DistP
+
+ def ToXml(self, DistP):
+ if self.DistP:
+ pass
+ if DistP != None:
+ #
+ # Parse DistributionPackageHeader
+ #
+ Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],
+ ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],
+ ]
+ Root = CreateXmlElement('DistributionPackage', '', [], Attrs)
+
+ Tmp = DistributionPackageHeaderXml()
+ Root.appendChild(Tmp.ToXml(DistP.Header, 'DistributionHeader'))
+ #
+ # Parse each PackageSurfaceArea
+ #
+ for Package in DistP.PackageSurfaceArea.values():
+ Psa = PackageSurfaceAreaXml()
+ DomPackage = Psa.ToXml(Package)
+ Root.appendChild(DomPackage)
+ #
+ # Parse each ModuleSurfaceArea
+ #
+ for Module in DistP.ModuleSurfaceArea.values():
+ Msa = ModuleSurfaceAreaXml()
+ DomModule = Msa.ToXml(Module)
+ Root.appendChild(DomModule)
+ #
+ # Parse Tools
+ #
+ Tmp = MiscellaneousFileXml()
+ ToolNode = Tmp.ToXml2(DistP.Tools, 'Tools')
+ if ToolNode is not None:
+ Root.appendChild(ToolNode)
+ #
+ # Parse MiscFiles
+ #
+ Tmp = MiscellaneousFileXml()
+ MiscFileNode = Tmp.ToXml2(DistP.MiscellaneousFiles,
+ 'MiscellaneousFiles')
+ if MiscFileNode is not None:
+ Root.appendChild(MiscFileNode)
+
+ XmlContent = Root.toprettyxml(indent=' ')
+
+
+ #
+ # Remove empty element
+ #
+ XmlContent = re.sub(r'[\s\r\n]*<[^<>=]*/>', '', XmlContent)
+
+ #
+ # Remove empty help text element
+ #
+ XmlContent = re.sub(r'[\s\r\n]*<HelpText Lang="en-US"/>', '',
+ XmlContent)
+
+ #
+ # Remove SupArchList="COMMON" or "common"
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
+ '[\s\r\n]*"', '', XmlContent)
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
+ '[\s\r\n]*"', '', XmlContent)
+ #
+ # Remove <SupArchList> COMMON </SupArchList>
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*COMMON[\s\r\n]*'
+ '</SupArchList>[\s\r\n]*', '', XmlContent)
+
+ #
+ # Remove <SupArchList> common </SupArchList>
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*'
+ 'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)
+
+ #
+ # Remove SupModList="COMMON" or "common"
+ #
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
+ '[\s\r\n]*"', '', XmlContent)
+ XmlContent = \
+ re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
+ '[\s\r\n]*"', '', XmlContent)
+
+ return XmlContent
+
+ return ''
+
+## ValidateMS
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS(Module, TopXmlTreeLevel):
+ ValidateMS1(Module, TopXmlTreeLevel)
+ ValidateMS2(Module, TopXmlTreeLevel)
+ ValidateMS3(Module, TopXmlTreeLevel)
+
+## ValidateMS1
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS1(Module, TopXmlTreeLevel):
+ #
+ # Check Guids -> GuidCName
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Guids']
+ for Item in Module.GetGuidList():
+ if Item == None:
+ CheckDict = {'GuidCName':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['Guids', 'GuidCName']
+ for Item in Module.GetGuidList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidType':Item.GetGuidTypeList(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if Item.GetVariableName():
+ Result = ConvertVariableName(Item.GetVariableName())
+ if Result is None:
+ Msg = "->".join(Node for Node in XmlTreeLevel)
+ ErrorMsg = ERR_XML_INVALID_VARIABLENAME % (Item.GetVariableName(), Item.GetCName(), Msg)
+ Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True)
+ else:
+ Item.SetVariableName(Result)
+
+ #
+ # Check Protocols -> Protocol
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Protocols']
+ for Item in Module.GetProtocolList():
+ if Item == None:
+ CheckDict = {'Protocol':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['Protocols', 'Protocol']
+ for Item in Module.GetProtocolList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PPIs -> Ppi
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PPIs']
+ for Item in Module.GetPpiList():
+ if Item == None:
+ CheckDict = {'Ppi':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['PPIs', 'Ppi']
+ for Item in Module.GetPpiList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PcdCoded -> Entry
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded']
+ for Item in Module.GetPcdList():
+ if Item == None:
+ CheckDict = {'PcdEntry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded', 'PcdEntry']
+ for Item in Module.GetPcdList():
+ CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
+ 'CName':Item.GetCName(),
+ 'PcdUsage':Item.GetValidUsage(),
+ 'PcdItemType':Item.GetItemType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check Externs -> Extern
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Externs']
+ for Item in Module.GetExternList():
+ if Item == None:
+ CheckDict = {'Extern':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # If SupArchList is used to identify different EntryPoint, UnloadImage, Constructor/Destructor elements and
+ # that SupArchList does not match ModuleSurfaceArea.ModuleProperties:SupArchList, the tool must exit gracefully,
+ # informing the user that the EDK II Build system does not support different EntryPoint, UnloadImage,
+ # Constructor or Destructor elements based on Architecture type. Two SupArchList attributes are considered
+ # identical if it lists the same CPU architectures in any order.
+ #
+ for Item in Module.GetExternList():
+ if len(Item.SupArchList) > 0:
+ if not IsEqualList(Item.SupArchList, Module.SupArchList):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_EXTERN_SUPARCHLIST % (str(Item.SupArchList), str(Module.SupArchList)),
+ RaiseError=True)
+
+ #
+ # Check DistributionPackage -> ModuleSurfaceArea -> UserExtensions
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
+ for Item in Module.GetUserExtensionList():
+ CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['MiscellaneousFiles']
+ for Item in Module.GetMiscFileList():
+ if not Item.GetFileList():
+ CheckDict = {'Filename':'', }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for File in Item.GetFileList():
+ CheckDict = {'Filename':File.GetURI(), }
+
+## ValidateMS2
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS2(Module, TopXmlTreeLevel):
+ #
+ # Check Header
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['Header']
+ CheckDict = Sdict()
+ CheckDict['Name'] = Module.GetName()
+ CheckDict['BaseName'] = Module.GetBaseName()
+ CheckDict['GUID'] = Module.GetGuid()
+ CheckDict['Version'] = Module.GetVersion()
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check ModuleProperties
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties']
+ CheckDict = {'ModuleType':Module.GetModuleType(),
+ 'Path':Module.GetModulePath()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ if not IsValidInstallPath(Module.GetModulePath()):
+ Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Module.GetModulePath())
+
+ #
+ # Check ModuleProperties->BootMode
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['BootMode']
+ for Item in Module.GetBootModeList():
+ CheckDict = {'Usage':Item.GetUsage(),
+ 'SupportedBootModes':Item.GetSupportedBootModes()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check ModuleProperties->Event
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['Event']
+ for Item in Module.GetEventList():
+ CheckDict = {'Usage':Item.GetUsage(),
+ 'EventType':Item.GetEventType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check ModuleProperties->Hob
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['HOB']
+ for Item in Module.GetHobList():
+ CheckDict = {'Usage':Item.GetUsage(),
+ 'HobType':Item.GetHobType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # The UDP Specification supports the module type of UEFI_RUNTIME_DRIVER, which is not present in the EDK II INF
+ # File Specification v. 1.23, so UPT must perform the following translation that include the generation of a
+ # [Depex] section.
+ #
+ if Module.ModuleType == "UEFI_RUNTIME_DRIVER":
+ Module.ModuleType = "DXE_RUNTIME_DRIVER"
+ DxeObj = DepexObject()
+ DxeObj.SetDepex("gEfiBdsArchProtocolGuid AND \ngEfiCpuArchProtocolGuid AND\n" + \
+ "gEfiMetronomeArchProtocolGuid AND \ngEfiMonotonicCounterArchProtocolGuid AND\n" + \
+ "gEfiRealTimeClockArchProtocolGuid AND \ngEfiResetArchProtocolGuid AND\n" + \
+ "gEfiRuntimeArchProtocolGuid AND \ngEfiSecurityArchProtocolGuid AND\n" + \
+ "gEfiTimerArchProtocolGuid AND \ngEfiVariableWriteArchProtocolGuid AND\n" + \
+ "gEfiVariableArchProtocolGuid AND \ngEfiWatchdogTimerArchProtocolGuid")
+ DxeObj.SetModuleType(['DXE_RUNTIME_DRIVER'])
+ Module.PeiDepex = []
+ Module.DxeDepex = []
+ Module.SmmDepex = []
+ Module.DxeDepex.append(DxeObj)
+
+ #
+ # Check LibraryClassDefinitions -> LibraryClass
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions']
+ for Item in Module.GetLibraryClassList():
+ if Item == None:
+ CheckDict = {'LibraryClass':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions', 'LibraryClass']
+
+ IsLibraryModule = False
+ LibrarySupModList = []
+ for Item in Module.GetLibraryClassList():
+ CheckDict = {'Keyword':Item.GetLibraryClass(),
+ 'Usage':Item.GetUsage()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # If the LibraryClass:SupModList is not "UNDEFINED" the LIBRARY_CLASS entry must have the list
+ # appended using the format:
+ # LIBRARY_CLASS = <ClassName> ["|" <Edk2ModuleTypeList>]
+ #
+ # Edk2ModuleTypeList ::= <ModuleType> [" " <ModuleType>]{0,}
+ # <ModuleTypes> ::= {"BASE"} {"SEC"} {"PEI_CORE"} {"PEIM"}
+ # {"DXE_CORE"} {"DXE_DRIVER"} {"SMM_CORE"}
+ # {"DXE_SMM_DRIVER"} {"DXE_RUNTIME_DRIVER"}
+ # {"DXE_SAL_DRIVER"} {"UEFI_DRIVER"}
+ # {"UEFI_APPLICATION"} {"USER_DEFINED"}
+ #
+ if len(Item.SupModuleList) > 0:
+ for SupModule in Item.SupModuleList:
+ if not IsValidInfMoudleType(SupModule):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_LIB_SUPMODLIST % (Item.LibraryClass, str(SupModule)),
+ RaiseError=True)
+
+ if Item.Usage == 'PRODUCES' or Item.Usage == 'SOMETIMES_PRODUCES':
+ IsLibraryModule = True
+ LibrarySupModList = Item.SupModuleList
+
+
+ #
+ # For Library modules (indicated by a LIBRARY_CLASS statement in the [Defines] section)
+ # If the SupModList attribute of the CONSTRUCTOR or DESTRUCTOR element does not match the Supported Module
+ # Types listed after "LIBRARY_CLASS = <Keyword> |", the tool should gracefully exit with an error message
+ # stating that there is a conflict in the module types the CONSTRUCTOR/DESTRUCTOR is to be used with and
+ # the Module types this Library supports.
+ #
+ if IsLibraryModule:
+ for Item in Module.GetExternList():
+ if Item.Constructor or Item.Destructor:
+ if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
+ not IsEqualList(Item.SupModList, LibrarySupModList):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_EXTERN_SUPMODLIST % (str(Item.SupModList), str(LibrarySupModList)),
+ RaiseError=True)
+
+ #
+ # If the module is not a library module, the MODULE_TYPE listed in the ModuleSurfaceArea.Header must match the
+ # SupModList attribute. If these conditions cannot be met, the tool must exit gracefully, informing the user
+ # that the EDK II Build system does not currently support the features required by this Module.
+ #
+ if not IsLibraryModule:
+ for Item in Module.GetExternList():
+ if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
+ not IsEqualList(Item.SupModList, [Module.ModuleType]):
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB % (str(Module.ModuleType), str(Item.SupModList)),
+ RaiseError=True)
+ #
+ # Check SourceFiles
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
+ for Item in Module.GetSourceFileList():
+ if Item == None:
+ CheckDict = {'Filename':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
+ for Item in Module.GetSourceFileList():
+ CheckDict = {'Filename':Item.GetSourceFile()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ for ItemCount in range(len(Module.GetBinaryFileList())):
+ Item = Module.GetBinaryFileList()[ItemCount]
+ if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'FREEFORM':
+ Item.FileNamList[0].FileType = 'SUBTYPE_GUID'
+ Module.GetBinaryFileList()[ItemCount] = Item
+ if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'DISPOSABLE':
+ Logger.Error('\nUPT',
+ PARSER_ERROR,
+ ERR_XML_INVALID_BINARY_FILE_TYPE % ('DISPOSABLE'),
+ RaiseError=True)
+
+## ValidateMS3
+#
+# Check if any required item is missing in ModuleSurfaceArea
+#
+# @param Module: The ModuleSurfaceArea to be checked
+# @param XmlTreeLevel: The top level of Module
+#
+def ValidateMS3(Module, TopXmlTreeLevel):
+ #
+ # Check PackageDependencies -> Package
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies']
+ for Item in Module.GetPackageDependencyList():
+ if Item == None:
+ CheckDict = {'Package':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies', 'Package']
+ for Item in Module.GetPackageDependencyList():
+ CheckDict = {'GUID':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check BinaryFiles -> BinaryFile
+ #
+ for Item in Module.GetBinaryFileList():
+ if Item == None:
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles']
+ CheckDict = {'BinaryFile':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ if not Item.GetFileNameList():
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
+ CheckDict = {'Filename':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
+ for File in Item.GetFileNameList():
+ CheckDict = {'Filename':File.GetFilename(),
+ 'FileType':File.GetFileType()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for AsBuilt in Item.GetAsBuiltList():
+ #
+ # Check LibInstance
+ #
+ if len(AsBuilt.LibraryInstancesList) == 1 and not AsBuilt.LibraryInstancesList[0]:
+ CheckDict = {'GUID':''}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ for LibItem in AsBuilt.LibraryInstancesList:
+ CheckDict = {'Guid':LibItem.Guid,
+ 'Version':LibItem.Version}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PatchPcd
+ #
+ for PatchPcdItem in AsBuilt.PatchPcdList:
+ CheckDict = {'TokenSpaceGuidValue':PatchPcdItem.TokenSpaceGuidValue,
+ 'PcdCName':PatchPcdItem.PcdCName,
+ 'Token':PatchPcdItem.Token,
+ 'DatumType':PatchPcdItem.DatumType,
+ 'Value':PatchPcdItem.DefaultValue,
+ 'Offset':PatchPcdItem.Offset}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PatchPcdValue']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check PcdError
+ #
+ for PcdErrorItem in PatchPcdItem.PcdErrorsList:
+ CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
+ 'PatchPcdValue', 'PcdError']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check PcdEx
+ #
+ for PcdExItem in AsBuilt.PcdExValueList:
+ CheckDict = {'TokenSpaceGuidValue':PcdExItem.TokenSpaceGuidValue,
+ 'Token':PcdExItem.Token,
+ 'DatumType':PcdExItem.DatumType,
+ 'Value':PcdExItem.DefaultValue}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PcdExValue']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check PcdError
+ #
+ for PcdErrorItem in PcdExItem.PcdErrorsList:
+ CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
+ XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
+ 'PcdExValue', 'PcdError']
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ #
+ # Check SmmDepex
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['SmmDepex']
+ for Item in Module.GetSmmDepex():
+ CheckDict = {'Expression':Item.GetDepex()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check PeiDepex
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['PeiDepex']
+ for Item in Module.GetPeiDepex():
+ CheckDict = {'Expression':Item.GetDepex()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DxeDepex
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['DxeDepex']
+ for Item in Module.GetDxeDepex():
+ CheckDict = {'Expression':Item.GetDepex()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check <UserExtensions>
+ #
+ XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
+ for Item in Module.GetUserExtensionList():
+ CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+## ValidatePS1
+#
+# ValidatePS1
+#
+def ValidatePS1(Package):
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> Header
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Header']
+ CheckDict = Sdict()
+ CheckDict['Name'] = Package.GetName()
+ CheckDict['BaseName'] = Package.GetBaseName()
+ CheckDict['GUID'] = Package.GetGuid()
+ CheckDict['Version'] = Package.GetVersion()
+ CheckDict['PackagePath'] = Package.GetPackagePath()
+
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ if not IsValidInstallPath(Package.GetPackagePath()):
+ Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Package.GetPackagePath())
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> ClonedFrom
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ClonedFrom']
+ for Item in Package.GetClonedFromList():
+ if Item == None:
+ CheckDict = Sdict()
+ CheckDict['GUID'] = ''
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ CheckDict = Sdict()
+ CheckDict['GUID'] = Item.GetPackageGuid()
+ CheckDict['Version'] = Item.GetPackageVersion()
+
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> LibraryClassDeclarations -> LibraryClass
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations']
+ for Item in Package.GetLibraryClassList():
+ if Item == None:
+ CheckDict = {'LibraryClass':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations', 'LibraryClass']
+ for Item in Package.GetLibraryClassList():
+ CheckDict = {'Keyword':Item.GetLibraryClass(),
+ 'HeaderFile':Item.GetIncludeHeader()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> IndustryStandardIncludes -> IndustryStandardHeader
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes']
+ for Item in Package.GetStandardIncludeFileList():
+ if Item == None:
+ CheckDict = {'IndustryStandardHeader':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes', 'IndustryStandardHeader']
+ for Item in Package.GetStandardIncludeFileList():
+ CheckDict = {'HeaderFile':Item.GetFilePath()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> PackageIncludes -> PackageHeader
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes']
+ for Item in Package.GetPackageIncludeFileList():
+ if Item == None:
+ CheckDict = {'PackageHeader':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes', 'PackageHeader']
+ for Item in Package.GetPackageIncludeFileList():
+ CheckDict = {'HeaderFile':Item.GetFilePath()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+## ValidatePS2
+#
+# ValidatePS2
+#
+def ValidatePS2(Package):
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> Modules -> ModuleSurfaceArea
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Modules', 'ModuleSurfaceArea']
+ for Item in Package.GetModuleDict().values():
+ ValidateMS(Item, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> GuidDeclarations Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations']
+ for Item in Package.GetGuidList():
+ if Item == None:
+ CheckDict = {'Entry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations', 'Entry']
+ for Item in Package.GetGuidList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidValue':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> ProtocolDeclarations -> Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations']
+ for Item in Package.GetProtocolList():
+ if Item == None:
+ CheckDict = {'Entry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations', 'Entry']
+ for Item in Package.GetProtocolList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidValue':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> PpiDeclarations -> Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations']
+ for Item in Package.GetPpiList():
+ if Item == None:
+ CheckDict = {'Entry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations', 'Entry']
+ for Item in Package.GetPpiList():
+ CheckDict = {'CName':Item.GetCName(),
+ 'GuidValue':Item.GetGuid()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> PcdDeclarations -> Entry
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations']
+ for Item in Package.GetPcdList():
+ if Item == None:
+ CheckDict = {'PcdEntry':''}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations', 'PcdEntry']
+ for Item in Package.GetPcdList():
+ CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
+ 'Token':Item.GetToken(),
+ 'CName':Item.GetCName(),
+ 'DatumType':Item.GetDatumType(),
+ 'ValidUsage':Item.GetValidUsage(),
+ 'DefaultValue':Item.GetDefaultValue()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> UserExtensions
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'UserExtensions']
+ for Item in Package.GetUserExtensionList():
+ CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+ #
+ # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
+ #
+ XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'MiscellaneousFiles']
+ for Item in Package.GetMiscFileList():
+ if not Item.GetFileList():
+ CheckDict = {'Filename':'', }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+ for File in Item.GetFileList():
+ CheckDict = {'Filename':File.GetURI(), }
+ IsRequiredItemListNull(CheckDict, XmlTreeLevel)
+
+## ValidatePackageSurfaceArea
+#
+# Check if any required item is missing in PackageSurfaceArea
+#
+# @param Package: The PackageSurfaceArea to be checked
+#
+def ValidatePackageSurfaceArea(Package):
+ ValidatePS1(Package)
+ ValidatePS2(Package)
diff --git a/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py b/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py
new file mode 100644
index 0000000000..0ffa44d35f
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/XmlParserMisc.py
@@ -0,0 +1,89 @@
+## @file
+# This file is used to parse a xml file of .PKG file
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+XmlParserMisc
+'''
+from Object.POM.CommonObject import TextObject
+from Logger.StringTable import ERR_XML_PARSER_REQUIRED_ITEM_MISSING
+from Logger.ToolError import PARSER_ERROR
+import Logger.Log as Logger
+
+## ConvertVariableName()
+# Convert VariableName to be L"string",
+# input of UCS-2 format Hex Array or L"string" (C style.) could be converted successfully,
+# others will not.
+#
+# @param VariableName: string need to be converted
+# @retval: the L quoted string converted if success, else None will be returned
+#
+def ConvertVariableName(VariableName):
+ VariableName = VariableName.strip()
+ #
+ # check for L quoted string
+ #
+ if VariableName.startswith('L"') and VariableName.endswith('"'):
+ return VariableName
+
+ #
+ # check for Hex Array, it should be little endian even number of hex numbers
+ #
+ ValueList = VariableName.split(' ')
+ if len(ValueList)%2 == 1:
+ return None
+
+ TransferedStr = ''
+
+ Index = 0
+
+ while Index < len(ValueList):
+ FirstByte = int(ValueList[Index], 16)
+ SecondByte = int(ValueList[Index + 1], 16)
+ if SecondByte != 0:
+ return None
+
+ if FirstByte not in xrange(0x20, 0x7F):
+ return None
+ TransferedStr += ('%c')%FirstByte
+ Index = Index + 2
+
+ return 'L"' + TransferedStr + '"'
+
+## IsRequiredItemListNull
+#
+# Check if a required XML section item/attribue is NULL
+#
+# @param ItemList: The list of items to be checked
+# @param XmlTreeLevel: The error message tree level
+#
+def IsRequiredItemListNull(ItemDict, XmlTreeLevel):
+ for Key in ItemDict:
+ if not ItemDict[Key]:
+ Msg = "->".join(Node for Node in XmlTreeLevel)
+ ErrorMsg = ERR_XML_PARSER_REQUIRED_ITEM_MISSING % (Key, Msg)
+ Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True)
+
+
+## Get help text
+#
+# @param HelpText
+#
+def GetHelpTextList(HelpText):
+ HelpTextList = []
+ for HelT in HelpText:
+ HelpTextObj = TextObject()
+ HelpTextObj.SetLang(HelT.Lang)
+ HelpTextObj.SetString(HelT.HelpText)
+ HelpTextList.append(HelpTextObj)
+ return HelpTextList
diff --git a/BaseTools/Source/Python/UPT/Xml/__init__.py b/BaseTools/Source/Python/UPT/Xml/__init__.py
new file mode 100644
index 0000000000..5d268d990b
--- /dev/null
+++ b/BaseTools/Source/Python/UPT/Xml/__init__.py
@@ -0,0 +1,20 @@
+## @file
+# Python 'Library' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available
+# under the terms and conditions of the BSD License which accompanies this
+# distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+Xml
+''' \ No newline at end of file
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index 4a97b8a93b..f923129c54 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -2261,6 +2261,7 @@ class WorkspaceDatabase(object):
# @prarm RenewDb=False Create new database file if it's already there
#
def __init__(self, DbPath, GlobalMacros={}, RenewDb=False):
+ self._DbClosedFlag = False
self._GlobalMacros = GlobalMacros
if DbPath == None or DbPath == '':
@@ -2414,9 +2415,11 @@ determine whether database file is out of date!\n")
# Close the connection and cursor
#
def Close(self):
- self.Conn.commit()
- self.Cur.close()
- self.Conn.close()
+ if not self._DbClosedFlag:
+ self.Conn.commit()
+ self.Cur.close()
+ self.Conn.close()
+ self._DbClosedFlag = True
## Get unique file ID for the gvien file
def GetFileId(self, FilePath):
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index b794c0a361..b21f2204b7 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -705,7 +705,7 @@ class Build():
# @param SkuId SKU id from command line
#
def __init__(self, Target, WorkspaceDir, Platform, Module, Arch, ToolChain,
- BuildTarget, FlashDefinition, FdList=[], FvList=[],
+ BuildTarget, FlashDefinition, FdList=[], FvList=[], CapList=[],
MakefileType="nmake", SilentMode=False, ThreadNumber=2,
SkipAutoGen=False, Reparse=False, SkuId=None,
ReportFile=None, ReportType=None, UniFlag=None):
@@ -720,6 +720,7 @@ class Build():
self.Fdf = FlashDefinition
self.FdList = FdList
self.FvList = FvList
+ self.CapList = CapList
self.MakefileType = MakefileType
self.SilentMode = SilentMode
self.ThreadNumber = ThreadNumber
@@ -999,6 +1000,11 @@ class Build():
try:
#os.rmdir(AutoGenObject.BuildDir)
RemoveDirectory(AutoGenObject.BuildDir, True)
+ #
+ # First should close DB.
+ #
+ self.Db.Close()
+ RemoveDirectory(gBuildCacheDir, True)
except WindowsError, X:
EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
return True
@@ -1317,6 +1323,7 @@ class Build():
self.Fdf,
self.FdList,
self.FvList,
+ self.CapList,
self.SkuId,
self.UniFlag
)
@@ -1385,6 +1392,7 @@ class Build():
self.Fdf,
self.FdList,
self.FvList,
+ self.CapList,
self.SkuId,
self.UniFlag
)
@@ -1463,6 +1471,7 @@ class Build():
self.Fdf,
self.FdList,
self.FvList,
+ self.CapList,
self.SkuId,
self.UniFlag
)
@@ -1715,7 +1724,8 @@ def MyOptionParser():
help="The name of FD to be generated. The name must be from [FD] section in FDF file.")
Parser.add_option("-i", "--fv-image", action="append", type="string", dest="FvImage", default=[],
help="The name of FV to be generated. The name must be from [FV] section in FDF file.")
-
+ Parser.add_option("-C", "--capsule-image", action="append", type="string", dest="CapName", default=[],
+ help="The name of Capsule to be generated. The name must be from [Capsule] section in FDF file.")
Parser.add_option("-u", "--skip-autogen", action="store_true", dest="SkipAutoGen", help="Skip AutoGen step.")
Parser.add_option("-e", "--re-parse", action="store_true", dest="Reparse", help="Re-parse all meta-data files.")
@@ -1861,7 +1871,7 @@ def Main():
MyBuild = Build(Target, Workspace, Option.PlatformFile, Option.ModuleFile,
Option.TargetArch, Option.ToolChain, Option.BuildTarget,
- Option.FdfFile, Option.RomImage, Option.FvImage,
+ Option.FdfFile, Option.RomImage, Option.FvImage, Option.CapName,
None, Option.SilentMode, Option.ThreadNumber,
Option.SkipAutoGen, Option.Reparse, Option.SkuId,
Option.ReportFile, Option.ReportType, Option.Flag)
@@ -1919,14 +1929,19 @@ def Main():
else:
Conclusion = "Failed"
FinishTime = time.time()
- BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))
+ BuildDuration = time.gmtime(int(round(FinishTime - StartTime)))
+ BuildDurationStr = ""
+ if BuildDuration.tm_yday > 1:
+ BuildDurationStr = time.strftime("%H:%M:%S", BuildDuration) + ", %d day(s)"%(BuildDuration.tm_yday - 1)
+ else:
+ BuildDurationStr = time.strftime("%H:%M:%S", BuildDuration)
if MyBuild != None:
- MyBuild.BuildReport.GenerateReport(BuildDuration)
+ MyBuild.BuildReport.GenerateReport(BuildDurationStr)
MyBuild.Db.Close()
EdkLogger.SetLevel(EdkLogger.QUIET)
EdkLogger.quiet("\n- %s -" % Conclusion)
EdkLogger.quiet(time.strftime("Build end time: %H:%M:%S, %b.%d %Y", time.localtime()))
- EdkLogger.quiet("Build total time: %s\n" % BuildDuration)
+ EdkLogger.quiet("Build total time: %s\n" % BuildDurationStr)
return ReturnCode
if __name__ == '__main__':