Selaa lähdekoodia

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
lgao4 12 vuotta sitten
vanhempi
commit
4234283c3a
100 muutettua tiedostoa jossa 14768 lisäystä ja 2534 poistoa
  1. BIN
      BaseTools/Bin/Win32/BPDG.exe
  2. BIN
      BaseTools/Bin/Win32/BootSectImage.exe
  3. BIN
      BaseTools/Bin/Win32/EfiLdrImage.exe
  4. BIN
      BaseTools/Bin/Win32/EfiRom.exe
  5. BIN
      BaseTools/Bin/Win32/Fpd2Dsc.exe
  6. BIN
      BaseTools/Bin/Win32/GenBootSector.exe
  7. BIN
      BaseTools/Bin/Win32/GenCrc32.exe
  8. BIN
      BaseTools/Bin/Win32/GenDepex.exe
  9. BIN
      BaseTools/Bin/Win32/GenFds.exe
  10. BIN
      BaseTools/Bin/Win32/GenFfs.exe
  11. BIN
      BaseTools/Bin/Win32/GenFv.exe
  12. BIN
      BaseTools/Bin/Win32/GenFw.exe
  13. BIN
      BaseTools/Bin/Win32/GenPage.exe
  14. BIN
      BaseTools/Bin/Win32/GenPatchPcdTable.exe
  15. BIN
      BaseTools/Bin/Win32/GenSec.exe
  16. BIN
      BaseTools/Bin/Win32/GenVtf.exe
  17. BIN
      BaseTools/Bin/Win32/LzmaCompress.exe
  18. BIN
      BaseTools/Bin/Win32/MigrationMsa2Inf.exe
  19. BIN
      BaseTools/Bin/Win32/PatchPcdValue.exe
  20. BIN
      BaseTools/Bin/Win32/Spd2Dec.exe
  21. BIN
      BaseTools/Bin/Win32/Split.exe
  22. BIN
      BaseTools/Bin/Win32/TargetTool.exe
  23. BIN
      BaseTools/Bin/Win32/TianoCompress.exe
  24. BIN
      BaseTools/Bin/Win32/Trim.exe
  25. BIN
      BaseTools/Bin/Win32/UPT.exe
  26. BIN
      BaseTools/Bin/Win32/VfrCompile.exe
  27. BIN
      BaseTools/Bin/Win32/VolInfo.exe
  28. BIN
      BaseTools/Bin/Win32/_ctypes.pyd
  29. BIN
      BaseTools/Bin/Win32/build.exe
  30. 2 2
      BaseTools/BuildNotes.txt
  31. 9 0
      BaseTools/Conf/Empty_Package_Information_Data_File.ini
  32. 1 1
      BaseTools/Conf/XMLSchema/DistributionPackage.xsd
  33. 9 6
      BaseTools/Conf/build_rule.template
  34. 13 11
      BaseTools/Conf/target.template
  35. 20 15
      BaseTools/Conf/tools_def.template
  36. 8 1
      BaseTools/Source/C/Common/ParseInf.h
  37. 18 11
      BaseTools/Source/C/GenPage/GenPage.c
  38. 115 46
      BaseTools/Source/C/Include/Common/MdeModuleHii.h
  39. 27 0
      BaseTools/Source/C/Include/Common/UefiInternalFormRepresentation.h
  40. 0 548
      BaseTools/Source/C/Include/Protocol/DevicePath.h
  41. 2 2
      BaseTools/Source/C/VfrCompile/EfiVfr.h
  42. 37 3
      BaseTools/Source/C/VfrCompile/VfrCompiler.cpp
  43. 5 2
      BaseTools/Source/C/VfrCompile/VfrCompiler.h
  44. 3 1
      BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
  45. 89 5
      BaseTools/Source/C/VfrCompile/VfrFormPkg.h
  46. 228 47
      BaseTools/Source/C/VfrCompile/VfrSyntax.g
  47. 537 1
      BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
  48. 31 1
      BaseTools/Source/C/VfrCompile/VfrUtilityLib.h
  49. 65 3
      BaseTools/Source/Python/AutoGen/AutoGen.py
  50. 3 0
      BaseTools/Source/Python/AutoGen/GenC.py
  51. 2 1
      BaseTools/Source/Python/AutoGen/GenMake.py
  52. 2 0
      BaseTools/Source/Python/Common/BuildToolError.py
  53. 11 3
      BaseTools/Source/Python/Common/Misc.py
  54. 30 0
      BaseTools/Source/Python/GenFds/FdfParser.py
  55. 15 1
      BaseTools/Source/Python/GenFds/FfsInfStatement.py
  56. 5 1
      BaseTools/Source/Python/GenFds/Fv.py
  57. 19 3
      BaseTools/Source/Python/GenFds/GenFds.py
  58. 204 11
      BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py
  59. 1 1
      BaseTools/Source/Python/GenFds/Region.py
  60. 4 8
      BaseTools/Source/Python/GenFds/Section.py
  61. 6 4
      BaseTools/Source/Python/Makefile
  62. 0 185
      BaseTools/Source/Python/PackagingTool/DependencyRules.py
  63. 0 309
      BaseTools/Source/Python/PackagingTool/InstallPkg.py
  64. 0 629
      BaseTools/Source/Python/PackagingTool/IpiDb.py
  65. 0 294
      BaseTools/Source/Python/PackagingTool/MkPkg.py
  66. 0 160
      BaseTools/Source/Python/PackagingTool/PackageFile.py
  67. 0 218
      BaseTools/Source/Python/PackagingTool/RmPkg.py
  68. 293 0
      BaseTools/Source/Python/UPT/Core/DependencyRules.py
  69. 228 0
      BaseTools/Source/Python/UPT/Core/DistributionPackageClass.py
  70. 867 0
      BaseTools/Source/Python/UPT/Core/IpiDb.py
  71. 249 0
      BaseTools/Source/Python/UPT/Core/PackageFile.py
  72. 20 0
      BaseTools/Source/Python/UPT/Core/__init__.py
  73. BIN
      BaseTools/Source/Python/UPT/Dll/sqlite3.dll
  74. 367 0
      BaseTools/Source/Python/UPT/GenMetaFile/GenDecFile.py
  75. 988 0
      BaseTools/Source/Python/UPT/GenMetaFile/GenInfFile.py
  76. 155 0
      BaseTools/Source/Python/UPT/GenMetaFile/GenMetaFileMisc.py
  77. 18 0
      BaseTools/Source/Python/UPT/GenMetaFile/GenXmlFile.py
  78. 20 0
      BaseTools/Source/Python/UPT/GenMetaFile/__init__.py
  79. 770 0
      BaseTools/Source/Python/UPT/InstallPkg.py
  80. 217 0
      BaseTools/Source/Python/UPT/Library/CommentGenerating.py
  81. 451 0
      BaseTools/Source/Python/UPT/Library/CommentParsing.py
  82. 919 0
      BaseTools/Source/Python/UPT/Library/DataType.py
  83. 489 0
      BaseTools/Source/Python/UPT/Library/ExpressionValidate.py
  84. 94 0
      BaseTools/Source/Python/UPT/Library/GlobalData.py
  85. 921 0
      BaseTools/Source/Python/UPT/Library/Misc.py
  86. 717 0
      BaseTools/Source/Python/UPT/Library/ParserValidate.py
  87. 993 0
      BaseTools/Source/Python/UPT/Library/Parsing.py
  88. 968 0
      BaseTools/Source/Python/UPT/Library/String.py
  89. 228 0
      BaseTools/Source/Python/UPT/Library/Xml/XmlRoutines.py
  90. 20 0
      BaseTools/Source/Python/UPT/Library/Xml/__init__.py
  91. 20 0
      BaseTools/Source/Python/UPT/Library/__init__.py
  92. 325 0
      BaseTools/Source/Python/UPT/Logger/Log.py
  93. 768 0
      BaseTools/Source/Python/UPT/Logger/StringTable.py
  94. 176 0
      BaseTools/Source/Python/UPT/Logger/ToolError.py
  95. 20 0
      BaseTools/Source/Python/UPT/Logger/__init__.py
  96. 41 0
      BaseTools/Source/Python/UPT/Makefile
  97. 281 0
      BaseTools/Source/Python/UPT/MkPkg.py
  98. 789 0
      BaseTools/Source/Python/UPT/Object/POM/CommonObject.py
  99. 645 0
      BaseTools/Source/Python/UPT/Object/POM/ModuleObject.py
  100. 190 0
      BaseTools/Source/Python/UPT/Object/POM/PackageObject.py

BIN
BaseTools/Bin/Win32/BPDG.exe


BIN
BaseTools/Bin/Win32/BootSectImage.exe


BIN
BaseTools/Bin/Win32/EfiLdrImage.exe


BIN
BaseTools/Bin/Win32/EfiRom.exe


BIN
BaseTools/Bin/Win32/Fpd2Dsc.exe


BIN
BaseTools/Bin/Win32/GenBootSector.exe


BIN
BaseTools/Bin/Win32/GenCrc32.exe


BIN
BaseTools/Bin/Win32/GenDepex.exe


BIN
BaseTools/Bin/Win32/GenFds.exe


BIN
BaseTools/Bin/Win32/GenFfs.exe


BIN
BaseTools/Bin/Win32/GenFv.exe


BIN
BaseTools/Bin/Win32/GenFw.exe


BIN
BaseTools/Bin/Win32/GenPage.exe


BIN
BaseTools/Bin/Win32/GenPatchPcdTable.exe


BIN
BaseTools/Bin/Win32/GenSec.exe


BIN
BaseTools/Bin/Win32/GenVtf.exe


BIN
BaseTools/Bin/Win32/LzmaCompress.exe


BIN
BaseTools/Bin/Win32/MigrationMsa2Inf.exe


BIN
BaseTools/Bin/Win32/PatchPcdValue.exe


BIN
BaseTools/Bin/Win32/Spd2Dec.exe


BIN
BaseTools/Bin/Win32/Split.exe


BIN
BaseTools/Bin/Win32/TargetTool.exe


BIN
BaseTools/Bin/Win32/TianoCompress.exe


BIN
BaseTools/Bin/Win32/Trim.exe


BIN
BaseTools/Bin/Win32/UPT.exe


BIN
BaseTools/Bin/Win32/VfrCompile.exe


BIN
BaseTools/Bin/Win32/VolInfo.exe


BIN
BaseTools/Bin/Win32/_ctypes.pyd


BIN
BaseTools/Bin/Win32/build.exe


+ 2 - 2
BaseTools/BuildNotes.txt

@@ -74,11 +74,11 @@ please make sure the environment variable PYTHONPATH is set to
 
         <buildtools_project>/BaseTools/Source/Python
 
-  There're four tools written in Python. The entrance file of each tool is listed
+  There're five tools written in Python. The entrance file of each tool is listed
 below.
 
       build               <buildtools_project>/BaseTools/Source/Python/build/build.py
       GenFds              <buildtools_project>/BaseTools/Source/Python/GenFds/GenFds.py
       Trim                <buildtools_project>/BaseTools/Source/Python/Trim/Trim.py
       MigrationMsa2Inf    <buildtools_project>/BaseTools/Source/Python/MigrationMsa2Inf/MigrationMsa2Inf.py
-
+      UPT                 <buildtools_project>/BaseTools/Source/Python/UPT/UPT.py

+ 9 - 0
BaseTools/Conf/Empty_Package_Information_Data_File.ini

@@ -0,0 +1,9 @@
+[DistributionHeader]
+Name = 
+GUID = 
+Version = 
+Vendor = 
+Copyright = 
+License = 
+Abstract = 
+XmlSpecification = 1.1 

+ 1 - 1
BaseTools/Conf/XMLSchema/DistributionPackage.xsd

@@ -2,7 +2,7 @@
 <!--
 Filename: DistributionPackage.xsd
 
-Copyright (c) 2008, 2011 Intel Corporation. All rights reserved.
+Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
 
 This program and the accompanying materials are licensed and made available 
 under the terms and conditions of the BSD License which may be found at 

+ 9 - 6
BaseTools/Conf/build_rule.template

@@ -198,7 +198,7 @@
         -$(MD) $(OUTPUT_DIR)(+)${s_dir} > NUL 2>&1
         "$(VFRPP)" $(VFRPP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
         -$(MD) ${d_path} > NUL 2>&1
-        "$(VFR)" $(VFR_FLAGS) --output-directory ${d_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
+        "$(VFR)" $(VFR_FLAGS) --string-db $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk --output-directory ${d_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
 
 [Object-File]
     <InputFile>
@@ -242,7 +242,7 @@
         "$(OBJCOPY)" $(OBJCOPY_FLAGS) ${dst}
 
     <Command.ARMGCC>
-        "$(DLINK)" -o ${dst} $(DLINK_FLAGS) -( $(DLINK_SPATH) $(STATIC_LIBRARY_FILES) -) $(DLINK2_FLAGS)
+        "$(DLINK)" -o ${dst} $(DLINK_FLAGS) -\( $(DLINK_SPATH) $(STATIC_LIBRARY_FILES) -\) $(DLINK2_FLAGS)
 
     <Command.RVCT>
         "$(DLINK)" $(DLINK_FLAGS) -o ${dst} $(DLINK_SPATH) --via $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS)
@@ -272,7 +272,7 @@
         "$(DLINK)" $(DLINK_FLAGS) -\( $(DLINK_SPATH) @$(STATIC_LIBRARY_FILES_LIST) -\) $(DLINK2_FLAGS)
 
     <Command.ARMGCC>
-        "$(DLINK)" $(DLINK_FLAGS) -( $(DLINK_SPATH) $(STATIC_LIBRARY_FILES) -) $(DLINK2_FLAGS)
+        "$(DLINK)" $(DLINK_FLAGS) -\( $(DLINK_SPATH) $(STATIC_LIBRARY_FILES) -\) $(DLINK2_FLAGS)
 
     <Command.RVCT>
         "$(DLINK)" $(DLINK_FLAGS) -o ${dst} $(DLINK_SPATH) --via $(STATIC_LIBRARY_FILES_LIST) $(DLINK2_FLAGS)
@@ -417,15 +417,17 @@
         $(OUTPUT_DIR)(+)${s_base}.com
 
     <Command.MSFT, Command.INTEL>
+        "$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
+        Trim --source-code --convert-hex -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
         cd $(OUTPUT_DIR)(+)${s_dir}
-        "$(ASM16)" /nologo /c /omf $(INC) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj ${src}
+        "$(ASM16)" /nologo /c /omf $(INC) /Fo$(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj ${d_path}(+)${s_base}.iii
         "$(ASMLINK)" $(ASMLINK_FLAGS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj,${dst},,,,
 
     <Command.GCC>
       "$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
       Trim --source-code -o ${d_path}(+)${s_base}.iii ${d_path}(+)${s_base}.i
       "$(ASM)" -o $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj $(ASM_FLAGS) $(INC) ${d_path}(+)${s_base}.iii
-      "$(DLINK)" -o ${dst} $(DLINK_FLAGS) -( $(DLINK_SPATH) $(LIBS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj -)
+      "$(DLINK)" -o ${dst} $(DLINK_FLAGS) -\( $(DLINK_SPATH) $(LIBS) $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.obj -\)
      
     <Command.XCODE>
       "$(PP)" $(PP_FLAGS) $(INC) ${src} > ${d_path}(+)${s_base}.i
@@ -474,6 +476,7 @@
     <OutputFile>
         $(DEBUG_DIR)(+)AutoGen.c
         $(DEBUG_DIR)(+)$(MODULE_NAME)StrDefs.h
+        $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk
 
     <Command>
 
@@ -513,7 +516,7 @@
         -$(MD) $(OUTPUT_DIR)(+)${s_dir} > NUL 2>&1
         "$(VFRPP)" $(VFRPP_FLAGS) $(INC) ${src} > $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
         -$(MD) $(OUTPUT_DIR)(+)${s_dir} > NUL 2>&1
-        "$(VFR)" $(VFR_FLAGS) --create-ifr-package --output-directory $(OUTPUT_DIR)(+)${s_dir} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
+        "$(VFR)" $(VFR_FLAGS) --create-ifr-package --string-db $(OUTPUT_DIR)(+)$(MODULE_NAME)StrDefs.hpk --output-directory $(OUTPUT_DIR)(+)${s_dir} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.i
 
 [Hii-Binary-Package.UEFI_HII]
     <InputFile>

+ 13 - 11
BaseTools/Conf/target.template

@@ -1,5 +1,5 @@
 #
-#  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
@@ -29,18 +29,20 @@ ACTIVE_PLATFORM       = Nt32Pkg/Nt32Pkg.dsc
 #                                               UserDefined; separated by a space character.
 #                                               If the line is missing or no value is specified, all
 #                                               valid targets specified in the platform description file 
-#                                               will attempt to be built. The following line will build all
-#                                               platform targets.
+#                                               will attempt to be built. The following line will build 
+#                                               DEBUG platform target.
 TARGET                = DEBUG
 
 #  TARGET_ARCH           List       Optional    What kind of architecture is the binary being target for.
 #                                               One, or more, of the following, IA32, IPF, X64, EBC or ARM.
 #                                               Multiple values can be specified on a single line, using
 #                                               space charaters to separate the values.  These are used
-#                                               during the parsing of an platform description file, 
+#                                               during the parsing of a platform description file, 
 #                                               restricting the build output target(s.)
-#                                               The Build Target ARCH is determined by a logical AND of:
-#                                               platform BuildOptions: <SupportedArchitectures> tag
+#                                               The Build Target ARCH is determined by (precedence high to low):
+#                                                 Command-line: -a ARCH option
+#                                                 target.txt: TARGET_ARCH values
+#                                                 DSC file: [Defines] SUPPORTED_ARCHITECTURES tag
 #                                               If not specified, then all valid architectures specified
 #                                               in the platform file, for which tools are available, will be
 #                                               built.
@@ -48,8 +50,7 @@ TARGET_ARCH           = IA32
 
 #  TOOL_DEFINITION_FILE  Filename  Optional   Specify the name of the filename to use for specifying
 #                                             the tools to use for the build.  If not specified,
-#                                             tools_def.txt will be used for the build.  This file
-#                                             MUST be located in the WORKSPACE/Conf directory.
+#                                             WORKSPACE/Conf/tools_def.txt will be used for the build.
 TOOL_CHAIN_CONF       = Conf/tools_def.txt
 
 #  TAGNAME               List      Optional   Specify the name(s) of the tools_def.txt TagName to use.
@@ -62,8 +63,9 @@ TOOL_CHAIN_TAG        = MYTOOLS
 #                                                 cores or CPUs. Less than 2 means disable multithread build.
 MAX_CONCURRENT_THREAD_NUMBER = 1
 
-# Build rules definition
-#
-#
+
+# BUILD_RULE_CONF  Filename Optional  Specify the file name to use for the build rules that are followed
+#                                     when generating Makefiles. If not specified, the file: 
+#                                     WORKSPACE/Conf/build_rule.txt will be used
 BUILD_RULE_CONF = Conf/build_rule.txt
 

+ 20 - 15
BaseTools/Conf/tools_def.template

@@ -164,7 +164,6 @@ DEFINE IPHONE_TOOLS            = /Developer/Platforms/iPhoneOS.platform/Develope
 DEFINE RVCT31_TOOLS_PATH       = c:/Program Files/ARM/RVCT/Programs/3.1/569/win_32-pentium
 DEFINE RVCT31CYGWIN_TOOLS_PATH = /cygdrive/c/Program Files/ARM/RVCT/Programs/3.1/569/win_32-pentium
 
-DEFINE SOURCERY_TOOLS        = c:/Program Files/CodeSourcery/Sourcery G++ Lite/bin
 DEFINE SOURCERY_CYGWIN_TOOLS = /cygdrive/c/Program Files/CodeSourcery/Sourcery G++ Lite/bin
 
 #
@@ -3437,8 +3436,8 @@ RELEASE_XCLANG_IA32_DLINK_FLAGS      = -arch i386 -u _$(IMAGE_ENTRY_POINT) -e _$
 RELEASE_XCLANG_IA32_ASM_FLAGS  = -arch i386 
 
 
-  DEBUG_XCLANG_IA32_CC_FLAGS   = -arch i386 -c -g -O0  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable 
-RELEASE_XCLANG_IA32_CC_FLAGS   = -arch i386 -c    -Os  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable 
+  DEBUG_XCLANG_IA32_CC_FLAGS   = -arch i386 -c -g -O0  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable  -fasm-blocks  -mms-bitfields -msoft-float -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
+RELEASE_XCLANG_IA32_CC_FLAGS   = -arch i386 -c    -Os  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable  -fasm-blocks  -mms-bitfields -msoft-float -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
 
 
 ##################
@@ -3453,8 +3452,8 @@ RELEASE_XCLANG_X64_ASM_FLAGS  = -arch x86_64
 *_XCLANG_*_VFRPP_FLAGS      = -x c -E -P -DVFRCOMPILE -include $(DEST_DIR_DEBUG)/$(MODULE_NAME)StrDefs.h 
 
 
-  DEBUG_XCLANG_X64_CC_FLAGS   = -ccc-host-triple x86_64-pc-win32-macho -c -g -O0  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable 
-RELEASE_XCLANG_X64_CC_FLAGS   = -ccc-host-triple x86_64-pc-win32-macho -c    -Os  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -mno-sse -mno-mmx -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable 
+  DEBUG_XCLANG_X64_CC_FLAGS   = -ccc-host-triple x86_64-pc-win32-macho -c -g -O0  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
+RELEASE_XCLANG_X64_CC_FLAGS   = -ccc-host-triple x86_64-pc-win32-macho -c    -Os  -Wall -Werror -include AutoGen.h -fno-stack-protector -fno-builtin -fshort-wchar -mdynamic-no-pic -Wno-empty-body -Wno-pointer-sign -Wno-unused-function -Wno-unused-value -Wno-missing-braces -Wno-tautological-compare -Wreturn-type -Wno-unused-variable -ftrap-function=undefined_behavior_has_been_optimized_away_by_clang
 *_XCLANG_*_ASLCC_FLAGS      = -x c -save-temps -g -O0 -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-missing-braces -c -include AutoGen.h -mdynamic-no-pic
 *_XCLANG_*_ASLDLINK_FLAGS   = -e _main -preload -segalign 0x20  -pie -seg1addr 0x240 -read_only_relocs suppress -map $(DEST_DIR_DEBUG)/$(BASE_NAME).map
 *_XCLANG_*_ASLPP_FLAGS      = -x c -E 
@@ -3560,7 +3559,7 @@ RELEASE_RVCT31CYGWIN_ARM_CC_FLAGS  = "$(CCPATH_FLAG)" $(ARCHCC_FLAGS) $(PLATFORM
 *_ARMGCC_*_*_FAMILY          = GCC
 *_ARMGCC_*_*_BUILDRULEFAMILY = ARMGCC
 
-*_ARMGCC_*_MAKE_PATH         = DEF(SOURCERY_TOOLS)/cs-make
+*_ARMGCC_*_MAKE_PATH         = make
 *_ARMGCC_*_MAKE_FLAGS        = --no-print-directory
 
 ##################
@@ -3577,16 +3576,16 @@ RELEASE_RVCT31CYGWIN_ARM_CC_FLAGS  = "$(CCPATH_FLAG)" $(ARCHCC_FLAGS) $(PLATFORM
 # ARM definitions
 ##################
 
-*_ARMGCC_ARM_ASLCC_PATH      = DEF(SOURCERY_TOOLS)/arm-none-eabi-gcc
-*_ARMGCC_ARM_ASLDLINK_PATH   = DEF(SOURCERY_TOOLS)/arm-none-eabi-ld
-*_ARMGCC_ARM_ASLPP_PATH      = DEF(SOURCERY_TOOLS)/arm-none-eabi-gcc
+*_ARMGCC_ARM_ASLCC_PATH      = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-gcc
+*_ARMGCC_ARM_ASLDLINK_PATH   = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-ld
+*_ARMGCC_ARM_ASLPP_PATH      = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-gcc
 
-*_ARMGCC_ARM_CC_PATH         = DEF(SOURCERY_TOOLS)/arm-none-eabi-gcc
-*_ARMGCC_ARM_SLINK_PATH      = DEF(SOURCERY_TOOLS)/arm-none-eabi-ar
-*_ARMGCC_ARM_DLINK_PATH      = DEF(SOURCERY_TOOLS)/arm-none-eabi-ld
-*_ARMGCC_ARM_ASM_PATH        = DEF(SOURCERY_TOOLS)/arm-none-eabi-as
-*_ARMGCC_ARM_PP_PATH         = DEF(SOURCERY_TOOLS)/arm-none-eabi-gcc
-*_ARMGCC_ARM_VFRPP_PATH      = DEF(SOURCERY_TOOLS)/arm-none-eabi-gcc
+*_ARMGCC_ARM_CC_PATH         = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-gcc
+*_ARMGCC_ARM_SLINK_PATH      = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-ar
+*_ARMGCC_ARM_DLINK_PATH      = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-ld
+*_ARMGCC_ARM_ASM_PATH        = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-as
+*_ARMGCC_ARM_PP_PATH         = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-gcc
+*_ARMGCC_ARM_VFRPP_PATH      = ENV(ARMGCC_TOOLS_PATH)arm-none-eabi-gcc
 
 #
 # Use default values, or override in DSC file
@@ -3640,6 +3639,12 @@ RELEASE_ARMGCC_ARM_CC_FLAGS = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -mlittle-endian
 *_*_*_ASLPP_FLAGS                  = /nologo /EP /C
 *_*_*_ASL_FLAGS                    =
 
+##################
+# GenCrc32 tool definitions
+##################
+*_*_*_CRC32_PATH          = GenCrc32
+*_*_*_CRC32_GUID          = FC1BCDB0-7D31-49AA-936A-A4600D9DD083
+
 ##################
 # LzmaCompress tool definitions
 ##################

+ 8 - 1
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

+ 18 - 11
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");
 
 }

+ 115 - 46
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
 

+ 27 - 0
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

+ 0 - 548
BaseTools/Source/C/Include/Protocol/DevicePath.h

@@ -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

+ 2 - 2
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 {

+ 37 - 3
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;
   }
 

+ 5 - 2
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 {

+ 3 - 1
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

+ 89 - 5
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;

+ 228 - 47
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
 //

+ 537 - 1
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;

+ 31 - 1
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

+ 65 - 3
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 = {}

+ 3 - 0
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:

+ 2 - 1
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,
         }

+ 2 - 0
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

+ 11 - 3
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
 

+ 30 - 0
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
     #

+ 15 - 1
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)

+ 5 - 1
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

+ 19 - 3
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():

+ 204 - 11
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

+ 1 - 1
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

+ 4 - 8
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:

+ 6 - 4
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

+ 0 - 185
BaseTools/Source/Python/PackagingTool/DependencyRules.py

@@ -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)
-
-
-    

+ 0 - 309
BaseTools/Source/Python/PackagingTool/InstallPkg.py

@@ -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())

+ 0 - 629
BaseTools/Source/Python/PackagingTool/IpiDb.py

@@ -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()
-
-    

+ 0 - 294
BaseTools/Source/Python/PackagingTool/MkPkg.py

@@ -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())
-

+ 0 - 160
BaseTools/Source/Python/PackagingTool/PackageFile.py

@@ -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
-

+ 0 - 218
BaseTools/Source/Python/PackagingTool/RmPkg.py

@@ -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())

+ 293 - 0
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
+        
+
+

+ 228 - 0
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
+
+        
+

+ 867 - 0
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)
+
+
+
+    

+ 249 - 0
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()
+
+
+

+ 20 - 0
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
+'''

BIN
BaseTools/Source/Python/UPT/Dll/sqlite3.dll


+ 367 - 0
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
+

+ 988 - 0
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)

+ 155 - 0
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                
+                

+ 18 - 0
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
+'''

+ 20 - 0
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
+'''

+ 770 - 0
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
+

+ 217 - 0
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

+ 451 - 0
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  

+ 919 - 0
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' 

+ 489 - 0
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()

+ 94 - 0
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

+ 921 - 0
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

+ 717 - 0
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
+

+ 993 - 0
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

+ 968 - 0
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

+ 228 - 0
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)

+ 20 - 0
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
+'''

+ 20 - 0
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
+'''

+ 325 - 0
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)
+
+
+

+ 768 - 0
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")

+ 176 - 0
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
+

+ 20 - 0
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
+'''

+ 41 - 0
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
+

+ 281 - 0
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)

+ 789 - 0
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

+ 645 - 0
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

+ 190 - 0
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
+

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä